Changeset 3748411
- Timestamp:
- 10/15/2026 12:14:02 PM (9 days ago)
- Location:
- gloty
- Files:
-
- 4 added
- 56 edited
- 1 copied
-
tags/1.64.0 (copied) (copied from gloty/trunk )
-
tags/1.64.0/build/gloty-admin.asset.php (modified) (1 diff)
-
tags/1.64.0/build/gloty-admin.js (modified) (2 diffs)
-
tags/1.64.0/build/style-gloty-editor-sidebar-rtl.css (modified) (1 diff)
-
tags/1.64.0/build/style-gloty-editor-sidebar.css (modified) (1 diff)
-
tags/1.64.0/composer.lock (modified) (2 diffs)
-
tags/1.64.0/gloty.php (modified) (2 diffs)
-
tags/1.64.0/includes/API/class-admin-rest-routes.php (modified) (1 diff)
-
tags/1.64.0/includes/Admin/class-admin-boot-data.php (modified) (1 diff)
-
tags/1.64.0/includes/Admin/class-issues-service.php (modified) (1 diff)
-
tags/1.64.0/includes/Licensing/class-license-client.php (modified) (4 diffs)
-
tags/1.64.0/languages/gloty.pot (modified) (11 diffs)
-
tags/1.64.0/package.json (modified) (1 diff)
-
tags/1.64.0/readme.txt (modified) (2 diffs)
-
tags/1.64.0/shared-js/design-system/src/components.css (modified) (2 diffs)
-
tags/1.64.0/shared-js/design-system/src/interactive-table.js (modified) (2 diffs)
-
tags/1.64.0/shared-js/design-system/src/style.css (modified) (1 diff)
-
tags/1.64.0/shared-js/design-system/src/table-state.js (modified) (2 diffs)
-
tags/1.64.0/src/admin/LicensePanel.js (modified) (5 diffs)
-
tags/1.64.0/src/admin/style.css (modified) (5 diffs)
-
tags/1.64.0/vendor/composer/autoload_classmap.php (modified) (1 diff)
-
tags/1.64.0/vendor/composer/autoload_static.php (modified) (1 diff)
-
tags/1.64.0/vendor/composer/installed.json (modified) (2 diffs)
-
tags/1.64.0/vendor/composer/installed.php (modified) (4 diffs)
-
tags/1.64.0/vendor/wp-shelf/platform/assets/admin.css (modified) (13 diffs)
-
tags/1.64.0/vendor/wp-shelf/platform/assets/revision.txt (added)
-
tags/1.64.0/vendor/wp-shelf/platform/assets/screens.js (modified) (15 diffs)
-
tags/1.64.0/vendor/wp-shelf/platform/src/AdminAssets.php (modified) (7 diffs)
-
tags/1.64.0/vendor/wp-shelf/platform/src/AsyncScreens.php (modified) (1 diff)
-
tags/1.64.0/vendor/wp-shelf/platform/src/LicenseClient.php (modified) (5 diffs)
-
tags/1.64.0/vendor/wp-shelf/platform/src/LicenseRefusal.php (added)
-
trunk/build/gloty-admin.asset.php (modified) (1 diff)
-
trunk/build/gloty-admin.js (modified) (2 diffs)
-
trunk/build/style-gloty-editor-sidebar-rtl.css (modified) (1 diff)
-
trunk/build/style-gloty-editor-sidebar.css (modified) (1 diff)
-
trunk/composer.lock (modified) (2 diffs)
-
trunk/gloty.php (modified) (2 diffs)
-
trunk/includes/API/class-admin-rest-routes.php (modified) (1 diff)
-
trunk/includes/Admin/class-admin-boot-data.php (modified) (1 diff)
-
trunk/includes/Admin/class-issues-service.php (modified) (1 diff)
-
trunk/includes/Licensing/class-license-client.php (modified) (4 diffs)
-
trunk/languages/gloty.pot (modified) (11 diffs)
-
trunk/package.json (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/shared-js/design-system/src/components.css (modified) (2 diffs)
-
trunk/shared-js/design-system/src/interactive-table.js (modified) (2 diffs)
-
trunk/shared-js/design-system/src/style.css (modified) (1 diff)
-
trunk/shared-js/design-system/src/table-state.js (modified) (2 diffs)
-
trunk/src/admin/LicensePanel.js (modified) (5 diffs)
-
trunk/src/admin/style.css (modified) (5 diffs)
-
trunk/vendor/composer/autoload_classmap.php (modified) (1 diff)
-
trunk/vendor/composer/autoload_static.php (modified) (1 diff)
-
trunk/vendor/composer/installed.json (modified) (2 diffs)
-
trunk/vendor/composer/installed.php (modified) (4 diffs)
-
trunk/vendor/wp-shelf/platform/assets/admin.css (modified) (13 diffs)
-
trunk/vendor/wp-shelf/platform/assets/revision.txt (added)
-
trunk/vendor/wp-shelf/platform/assets/screens.js (modified) (15 diffs)
-
trunk/vendor/wp-shelf/platform/src/AdminAssets.php (modified) (7 diffs)
-
trunk/vendor/wp-shelf/platform/src/AsyncScreens.php (modified) (1 diff)
-
trunk/vendor/wp-shelf/platform/src/LicenseClient.php (modified) (5 diffs)
-
trunk/vendor/wp-shelf/platform/src/LicenseRefusal.php (added)
Legend:
- Unmodified
- Added
- Removed
-
gloty/tags/1.64.0/build/gloty-admin.asset.php
r3723648 r3748411 1 <?php return array('dependencies' => array('react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => ' e3d859e836b549af3807');1 <?php return array('dependencies' => array('react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '3f1856f97a09438ce020'); -
gloty/tags/1.64.0/build/gloty-admin.js
r3723648 r3748411 1 (()=>{"use strict";var e,s={843(e,s,t){var a=t(930);const l=window.wp.i18n,n=window.wp.element;function i({search:e=null,filters:s=[],count:t=null,countLabel:a=null,onClear:l=null,clearLabel:i=null,children:r=null}){const o=e&&e.value||s.some(e=>""!==e.value&&null!=e.value);return(0,n.createElement)("div",{className:"wpshelf-filters"},e?(0,n.createElement)("div",{className:"wpshelf-filters__search"},(0,n.createElement)("input",{type:"search",className:"wpshelf-filters__search-input",value:e.value,placeholder:e.placeholder,"aria-label":e.label||e.placeholder,onChange:s=>e.onChange(s.target.value)})):null,s.map(e=>(0,n.createElement)("select",{key:e.label,className:"wpshelf-filters__select",value:e.value,"aria-label":e.label,onChange:s=>e.onChange(s.target.value)},e.options.map(e=>(0,n.createElement)("option",{key:e.value,value:e.value},e.label)))),r,null!==t&&a?(0,n.createElement)("span",{className:"wpshelf-filters__count",role:"status"},a):null,l&&o&&i?(0,n.createElement)("button",{type:"button",className:"wpshelf-linkbtn",onClick:l},i):null)}function r({label:e,onPrev:s,onNext:t,prevDisabled:a=!1,nextDisabled:l=!1,prevLabel:i,nextLabel:r}){return(0,n.createElement)("div",{className:"wpshelf-pager"},(0,n.createElement)("span",{className:"wpshelf-pager__label"},e),(0,n.createElement)("span",{className:"wpshelf-pager__controls"},(0,n.createElement)("button",{type:"button",className:"button",onClick:s,disabled:a},i),(0,n.createElement)("button",{type:"button",className:"button",onClick:t,disabled:l},r)))} function o(e){return n.Children.toArray(e).map(e=>(0,n.isValidElement)(e)?e.props["data-search"]??o(e.props.children??e.props.label??e.props.value??""):String(e)).join(" ")}function c(e){return n.Children.toArray(e).some(e=>(0,n.isValidElement)(e)&&("string"!=typeof e.type||["input","button","select","a"].includes(e.type)||c(e.props.children)))}function d(e){return n.Children.toArray(e).some(e=>(0,n.isValidElement)(e)&&("checkbox"===e.props.type||void 0!==e.props.checked||d(e.props.children)))}function h(e){return n.Children.map(e,e=>{if(!(0,n.isValidElement)(e))return e;const s="checkbox"===e.props.type||void 0!==e.props.checked;return(0,n.cloneElement)(e,s?{disabled:!0}:{},void 0===e.props.children?void 0:h(e.props.children))})}function g({children:e,labels:s,pageSize:t=25,...a}){const[l,g]=(0,n.useState)(""),[u,_]=(0,n.useState)({column:-1,direction:1}),[p,m]=(0,n.useState)(1),y=n.Children.toArray(e),f=y.find(e=>"tbody"===e.type),w=y.find(e=>"thead"===e.type),x=n.Children.toArray(f?.props.children);if(!w||!f||x.some(e=>"tr"!==e.type))return(0,n.createElement)("table",a,e);d(w)&&(t=Math.max(x.length,1));const v=l.toLocaleLowerCase().trim().split(/\s+/).filter(Boolean),j=x.filter(e=>!e.props.hidden&&v.every(s=>o(e).toLocaleLowerCase().includes(s)));u.column>=0&&j.sort((e,s)=>o(n.Children.toArray(e.props.children)[u.column]).localeCompare(o(n.Children.toArray(s.props.children)[u.column]),void 0,{numeric:!0,sensitivity:"base"})*u.direction);const b=Math.max(1,Math.ceil(j.length/t)),N=Math.min(p,b),C=new Set(j.slice((N-1)*t,N*t).map(e=>e.key)),S=[...j,...x.filter(e=>!j.includes(e))],k=(0,n.cloneElement)(w,{},n.Children.map(w.props.children,e=>(0,n.cloneElement)(e,{},n.Children.map(e.props.children,(e,s)=>(0,n.isValidElement)(e)&&!c(e.props.children)&&o(e).trim()?(0,n.cloneElement)(e,{"aria-sort":u.column===s?{1:"ascending","-1":"descending"}[u.direction]:"none"},(0,n.createElement)("button",{type:"button",className:"wpshelf-table__sort",onClick:()=>{_({column:s,direction:u.column===s?-u.direction:1}),m(1)}},e.props.children,(0,n.createElement)("span",{"aria-hidden":!0}," ↕"))):l&&(0,n.isValidElement)(e)?(0,n.cloneElement)(e,{},h(e.props.children)):e))));return(0,n.createElement)(n.Fragment,null,(0,n.createElement)(i,{search:{value:l,onChange:e=>{g(e),m(1)},label:s.search,placeholder:s.search},count:j.length,countLabel:`${j.length} / ${x.length}`}),(0,n.createElement)("table",{...a,"data-shelf-table":"react"},y.map(e=>e===w?k:e===f?(0,n.cloneElement)(f,{},S.map(e=>(0,n.cloneElement)(e,{hidden:!C.has(e.key)}))):e)),b>1?(0,n.createElement)(r,{label:`${N} / ${b}`,prevLabel:s.previous,nextLabel:s.next,prevDisabled:N<=1,nextDisabled:N>=b,onPrev:()=>m(N-1),onNext:()=>m(N+1)}):null)}const u=window.ReactJSXRuntime;function _(e){return(0,u.jsx)(g,{...e,labels:{search:(0,l.__)("Filter loaded rows","gloty"),previous:(0,l.__)("Previous","gloty"),next:(0,l.__)("Next","gloty")}})}const p=window.wp.apiFetch;var m=t.n(p);const y=window.wp.components,f=window.wp.data;var w=(0,n.forwardRef)(({icon:e,size:s=24,...t},a)=>(0,n.cloneElement)(e,{width:s,height:s,...t,ref:a}));const x=window.wp.primitives;var v=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M6.5 12.4L12 8l5.5 4.4-.9 1.2L12 10l-4.5 3.6-1-1.2z"})}),j=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"})}),b=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8Zm6.5 8c0 .6 0 1.2-.2 1.8h-2.7c0-.6.2-1.1.2-1.8s0-1.2-.2-1.8h2.7c.2.6.2 1.1.2 1.8Zm-.9-3.2h-2.4c-.3-.9-.7-1.8-1.1-2.4-.1-.2-.2-.4-.3-.5 1.6.5 3 1.6 3.8 3ZM12.8 17c-.3.5-.6 1-.8 1.3-.2-.3-.5-.8-.8-1.3-.3-.5-.6-1.1-.8-1.7h3.3c-.2.6-.5 1.2-.8 1.7Zm-2.9-3.2c-.1-.6-.2-1.1-.2-1.8s0-1.2.2-1.8H14c.1.6.2 1.1.2 1.8s0 1.2-.2 1.8H9.9ZM11.2 7c.3-.5.6-1 .8-1.3.2.3.5.8.8 1.3.3.5.6 1.1.8 1.7h-3.3c.2-.6.5-1.2.8-1.7Zm-1-1.2c-.1.2-.2.3-.3.5-.4.7-.8 1.5-1.1 2.4H6.4c.8-1.4 2.2-2.5 3.8-3Zm-1.8 8H5.7c-.2-.6-.2-1.1-.2-1.8s0-1.2.2-1.8h2.7c0 .6-.2 1.1-.2 1.8s0 1.2.2 1.8Zm-2 1.4h2.4c.3.9.7 1.8 1.1 2.4.1.2.2.4.3.5-1.6-.5-3-1.6-3.8-3Zm7.4 3c.1-.2.2-.3.3-.5.4-.7.8-1.5 1.1-2.4h2.4c-.8 1.4-2.2 2.5-3.8 3Z"})}),N=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M12 4L4 7.9V20h16V7.9L12 4zm6.5 14.5H14V13h-4v5.5H5.5V8.8L12 5.7l6.5 3.1v9.7z"})}),C=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"m11.3 17.2-5-5c-.1-.1-.1-.3 0-.4l2.3-2.3-1.1-1-2.3 2.3c-.7.7-.7 1.8 0 2.5l5 5H7.5v1.5h5.3v-5.2h-1.5v2.6zm7.5-6.4-5-5h2.7V4.2h-5.2v5.2h1.5V6.8l5 5c.1.1.1.3 0 .4l-2.3 2.3 1.1 1.1 2.3-2.3c.6-.7.6-1.9-.1-2.5z"})}),S=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M11.25 5h1.5v15h-1.5V5zM6 10h1.5v10H6V10zm12 4h-1.5v6H18v-6z"})}),k=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M17.5 10h-1.7l-3.7 10.5h1.7l.9-2.6h3.9l.9 2.6h1.7L17.5 10zm-2.2 6.3 1.4-4 1.4 4h-2.8zm-4.8-3.8c1.6-1.8 2.9-3.6 3.7-5.7H16V5.2h-5.8V3H8.8v2.2H3v1.5h9.6c-.7 1.6-1.8 3.1-3.1 4.6C8.6 10.2 7.8 9 7.2 8H5.6c.6 1.4 1.7 2.9 2.9 4.4l-2.4 2.4c-.3.4-.7.8-1.1 1.2l1 1 1.2-1.2c.8-.8 1.6-1.5 2.3-2.3.8.9 1.7 1.7 2.5 2.5l.6-1.5c-.7-.6-1.4-1.3-2.1-2z"})}),T=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M4.75 4a.75.75 0 0 0-.75.75v7.826c0 .2.08.39.22.53l6.72 6.716a2.313 2.313 0 0 0 3.276-.001l5.61-5.611-.531-.53.532.528a2.315 2.315 0 0 0 0-3.264L13.104 4.22a.75.75 0 0 0-.53-.22H4.75ZM19 12.576a.815.815 0 0 1-.236.574l-5.61 5.611a.814.814 0 0 1-1.153 0L5.5 12.264V5.5h6.763l6.5 6.502a.816.816 0 0 1 .237.574ZM8.75 9.75a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"})}),B=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M13 5c-3.3 0-6 2.7-6 6 0 1.4.5 2.7 1.3 3.7l-3.8 3.8 1.1 1.1 3.8-3.8c1 .8 2.3 1.3 3.7 1.3 3.3 0 6-2.7 6-6S16.3 5 13 5zm0 10.5c-2.5 0-4.5-2-4.5-4.5s2-4.5 4.5-4.5 4.5 2 4.5 4.5-2 4.5-4.5 4.5z"})}),E=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M10.289 4.836A1 1 0 0111.275 4h1.306a1 1 0 01.987.836l.244 1.466c.787.26 1.503.679 2.108 1.218l1.393-.522a1 1 0 011.216.437l.653 1.13a1 1 0 01-.23 1.273l-1.148.944a6.025 6.025 0 010 2.435l1.149.946a1 1 0 01.23 1.272l-.653 1.13a1 1 0 01-1.216.437l-1.394-.522c-.605.54-1.32.958-2.108 1.218l-.244 1.466a1 1 0 01-.987.836h-1.306a1 1 0 01-.986-.836l-.244-1.466a5.995 5.995 0 01-2.108-1.218l-1.394.522a1 1 0 01-1.217-.436l-.653-1.131a1 1 0 01.23-1.272l1.149-.946a6.026 6.026 0 010-2.435l-1.148-.944a1 1 0 01-.23-1.272l.653-1.131a1 1 0 011.217-.437l1.393.522a5.994 5.994 0 012.108-1.218l.244-1.466zM14.929 12a3 3 0 11-6 0 3 3 0 016 0z"})}),L=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M16.83 6.342l.602.3.625-.25.443-.176v12.569l-.443-.178-.625-.25-.603.301-1.444.723-2.41-.804-.475-.158-.474.158-2.41.803-1.445-.722-.603-.3-.625.25-.443.177V6.215l.443.178.625.25.603-.301 1.444-.722 2.41.803.475.158.474-.158 2.41-.803 1.445.722zM20 4l-1.5.6-1 .4-2-1-3 1-3-1-2 1-1-.4L5 4v17l1.5-.6 1-.4 2 1 3-1 3 1 2-1 1 .4 1.5.6V4zm-3.5 6.25v-1.5h-8v1.5h8zm0 3v-1.5h-8v1.5h8zm-8 3v-1.5h8v1.5h-8z"})}),M=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M12 4a8 8 0 1 1 .001 16.001A8 8 0 0 1 12 4Zm0 1.5a6.5 6.5 0 1 0-.001 13.001A6.5 6.5 0 0 0 12 5.5Zm.75 11h-1.5V15h1.5v1.5Zm-.445-9.234a3 3 0 0 1 .445 5.89V14h-1.5v-1.25c0-.57.452-.958.917-1.01A1.5 1.5 0 0 0 12 8.75a1.5 1.5 0 0 0-1.5 1.5H9a3 3 0 0 1 3.305-2.984Z"})}),A=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M4 20h8v-1.5H4V20zM18.9 3.5c-.6-.6-1.5-.6-2.1 0l-7.2 7.2c-.4-.1-.7 0-1.1.1-.5.2-1.5.7-1.9 2.2-.4 1.7-.8 2.2-1.1 2.7-.1.1-.2.3-.3.4l-.6 1.1H6c2 0 3.4-.4 4.7-1.4.8-.6 1.2-1.4 1.3-2.3 0-.3 0-.5-.1-.7L19 5.7c.5-.6.5-1.6-.1-2.2zM9.7 14.7c-.7.5-1.5.8-2.4 1 .2-.5.5-1.2.8-2.3.2-.6.4-1 .8-1.1.5-.1 1 .1 1.3.3.2.2.3.5.2.8 0 .3-.1.9-.7 1.3z"})});const D=Object.freeze({width:720,height:180,top:16,right:14,bottom:26,left:48}),R=Object.freeze({width:96,height:24,inset:3});function O(e){return Math.round(100*e)/100}function P(e){const s=/^(\d{4})-(\d{2})-(\d{2})$/.exec(String(e||""));if(!s)return null;const t=new Date(Number(s[1]),Number(s[2])-1,Number(s[3]));return Number.isNaN(t.getTime())?null:t}function $(e){const s=P(e);return s?new Intl.DateTimeFormat(void 0,{month:"short",day:"numeric"}).format(s):String(e||"")}function I(e){return(new Intl.NumberFormat).format(Math.round(e||0))}const H=D.height-D.bottom;function G(e){return!e||e.length<2?"":e.map((e,s)=>`${0===s?"M":"L"}${e.x} ${e.y}`).join(" ")}function z(e){const s=G(e);if(""===s)return"";const t=e[0];return`${s} L${e[e.length-1].x} ${H} L${t.x} ${H} Z`}function F(e){const s=(Array.isArray(e)?e:[]).map(e=>Number(e)||0);if(s.length<2)return"single";const t=Math.floor(s.length/2),a=e=>0===e.length?0:e.reduce((e,s)=>e+s,0)/e.length,l=a(s.slice(0,t)),n=a(s.slice(t));return 0===l?n>0?"rising":"steady":n>1.1*l?"rising":n<.9*l?"falling":"steady"}function V(e){switch(e){case"rising":return(0,l.__)("Rising","gloty");case"falling":return(0,l.__)("Falling","gloty");case"single":return(0,l.__)("One day","gloty");default:return(0,l.__)("Steady","gloty")}}function U({values:e=[],label:s=""}){const{mode:t,points:a,max:n}=function(e,s={}){const t=s.width??R.width,a=s.height??R.height,l=s.inset??R.inset,n=(Array.isArray(e)?e:[]).map(e=>Number(e)||0);if(0===n.length)return{mode:"empty",points:[],max:0};if(1===n.length)return{mode:"single",points:[{x:O(t/2),y:O(a/2)}],max:n[0]};const i=Math.max(...n),r=t-2*l,o=a-2*l,c=e=>O(l+e/(n.length-1)*r);return i<=0?{mode:"flat",points:n.map((e,s)=>({x:c(s),y:O(a-l)})),max:0}:{mode:"line",points:n.map((e,s)=>({x:c(s),y:O(l+o*(1-e/i))})),max:i}}(e),i=F(e),r=n<=0&&"empty"!==t?(0,l.sprintf)(/* translators: %s: series name. */ /* translators: %s: series name. */1 (()=>{"use strict";var e,s={843(e,s,t){var a=t(930);const l=window.wp.i18n,n=window.wp.element;function i({search:e=null,filters:s=[],count:t=null,countLabel:a=null,onClear:l=null,clearLabel:i=null,children:r=null}){const o=e&&e.value||s.some(e=>""!==e.value&&null!=e.value);return(0,n.createElement)("div",{className:"wpshelf-filters"},e?(0,n.createElement)("div",{className:"wpshelf-filters__search"},(0,n.createElement)("input",{type:"search",className:"wpshelf-filters__search-input",value:e.value,placeholder:e.placeholder,"aria-label":e.label||e.placeholder,onChange:s=>e.onChange(s.target.value)})):null,s.map(e=>(0,n.createElement)("select",{key:e.label,className:"wpshelf-filters__select",value:e.value,"aria-label":e.label,onChange:s=>e.onChange(s.target.value)},e.options.map(e=>(0,n.createElement)("option",{key:e.value,value:e.value},e.label)))),r,null!==t&&a?(0,n.createElement)("span",{className:"wpshelf-filters__count",role:"status"},a):null,l&&o&&i?(0,n.createElement)("button",{type:"button",className:"wpshelf-linkbtn",onClick:l},i):null)}function r({label:e,onPrev:s,onNext:t,prevDisabled:a=!1,nextDisabled:l=!1,prevLabel:i,nextLabel:r}){return(0,n.createElement)("div",{className:"wpshelf-pager"},(0,n.createElement)("span",{className:"wpshelf-pager__label"},e),(0,n.createElement)("span",{className:"wpshelf-pager__controls"},(0,n.createElement)("button",{type:"button",className:"button",onClick:s,disabled:a},i),(0,n.createElement)("button",{type:"button",className:"button",onClick:t,disabled:l},r)))}const o=new Intl.Collator(void 0,{numeric:!0,sensitivity:"base"});function c(e){return n.Children.toArray(e).map(e=>(0,n.isValidElement)(e)?e.props["data-search"]??c(e.props.children??e.props.label??e.props.value??""):String(e)).join(" ")}function d(e){return n.Children.toArray(e).some(e=>(0,n.isValidElement)(e)&&("string"!=typeof e.type||["input","button","select","a"].includes(e.type)||d(e.props.children)))}function h(e){return n.Children.toArray(e).some(e=>(0,n.isValidElement)(e)&&("checkbox"===e.props.type||void 0!==e.props.checked||h(e.props.children)))}function g(e){return n.Children.map(e,e=>{if(!(0,n.isValidElement)(e))return e;const s="checkbox"===e.props.type||void 0!==e.props.checked;return(0,n.cloneElement)(e,s?{disabled:!0}:{},void 0===e.props.children?void 0:g(e.props.children))})}function u({children:e,labels:s,pageSize:t=25,...a}){const[l,u]=(0,n.useState)(""),[_,p]=(0,n.useState)({column:-1,direction:1}),[m,y]=(0,n.useState)(1),f=n.Children.toArray(e),w=f.find(e=>"tbody"===e.type),x=f.find(e=>"thead"===e.type),v=n.Children.toArray(w?.props.children);if(!x||!w||v.some(e=>"tr"!==e.type))return(0,n.createElement)("table",a,e);h(x)&&(t=Math.max(v.length,1));const j=l.toLocaleLowerCase().trim().split(/\s+/).filter(Boolean),b=v.filter(e=>!e.props.hidden&&j.every(s=>c(e).toLocaleLowerCase().includes(s)));_.column>=0&&b.sort((e,s)=>o.compare(c(n.Children.toArray(e.props.children)[_.column]),c(n.Children.toArray(s.props.children)[_.column]))*_.direction);const N=Math.max(1,Math.ceil(b.length/t)),C=Math.min(m,N),S=new Set(b.slice((C-1)*t,C*t).map(e=>e.key)),k=[...b,...v.filter(e=>!b.includes(e))],T=(0,n.cloneElement)(x,{},n.Children.map(x.props.children,e=>(0,n.cloneElement)(e,{},n.Children.map(e.props.children,(e,s)=>(0,n.isValidElement)(e)&&!d(e.props.children)&&c(e).trim()?(0,n.cloneElement)(e,{"aria-sort":_.column===s?{1:"ascending","-1":"descending"}[_.direction]:"none"},(0,n.createElement)("button",{type:"button",className:"wpshelf-table__sort",onClick:()=>{p({column:s,direction:_.column===s?-_.direction:1}),y(1)}},e.props.children,(0,n.createElement)("span",{"aria-hidden":!0}," ↕"))):l&&(0,n.isValidElement)(e)?(0,n.cloneElement)(e,{},g(e.props.children)):e))));return(0,n.createElement)(n.Fragment,null,(0,n.createElement)(i,{search:{value:l,onChange:e=>{u(e),y(1)},label:s.search,placeholder:s.search},count:b.length,countLabel:`${b.length} / ${v.length}`}),(0,n.createElement)("table",{...a,"data-shelf-table":"react"},f.map(e=>e===x?T:e===w?(0,n.cloneElement)(w,{},k.map(e=>(0,n.cloneElement)(e,{hidden:!S.has(e.key)}))):e)),N>1?(0,n.createElement)(r,{label:`${C} / ${N}`,prevLabel:s.previous,nextLabel:s.next,prevDisabled:C<=1,nextDisabled:C>=N,onPrev:()=>y(C-1),onNext:()=>y(C+1)}):null)}const _=window.ReactJSXRuntime;function p(e){return(0,_.jsx)(u,{...e,labels:{search:(0,l.__)("Filter loaded rows","gloty"),previous:(0,l.__)("Previous","gloty"),next:(0,l.__)("Next","gloty")}})}const m=window.wp.apiFetch;var y=t.n(m);const f=window.wp.components,w=window.wp.data;var x=(0,n.forwardRef)(({icon:e,size:s=24,...t},a)=>(0,n.cloneElement)(e,{width:s,height:s,...t,ref:a}));const v=window.wp.primitives;var j=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M6.5 12.4L12 8l5.5 4.4-.9 1.2L12 10l-4.5 3.6-1-1.2z"})}),b=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"})}),N=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8Zm6.5 8c0 .6 0 1.2-.2 1.8h-2.7c0-.6.2-1.1.2-1.8s0-1.2-.2-1.8h2.7c.2.6.2 1.1.2 1.8Zm-.9-3.2h-2.4c-.3-.9-.7-1.8-1.1-2.4-.1-.2-.2-.4-.3-.5 1.6.5 3 1.6 3.8 3ZM12.8 17c-.3.5-.6 1-.8 1.3-.2-.3-.5-.8-.8-1.3-.3-.5-.6-1.1-.8-1.7h3.3c-.2.6-.5 1.2-.8 1.7Zm-2.9-3.2c-.1-.6-.2-1.1-.2-1.8s0-1.2.2-1.8H14c.1.6.2 1.1.2 1.8s0 1.2-.2 1.8H9.9ZM11.2 7c.3-.5.6-1 .8-1.3.2.3.5.8.8 1.3.3.5.6 1.1.8 1.7h-3.3c.2-.6.5-1.2.8-1.7Zm-1-1.2c-.1.2-.2.3-.3.5-.4.7-.8 1.5-1.1 2.4H6.4c.8-1.4 2.2-2.5 3.8-3Zm-1.8 8H5.7c-.2-.6-.2-1.1-.2-1.8s0-1.2.2-1.8h2.7c0 .6-.2 1.1-.2 1.8s0 1.2.2 1.8Zm-2 1.4h2.4c.3.9.7 1.8 1.1 2.4.1.2.2.4.3.5-1.6-.5-3-1.6-3.8-3Zm7.4 3c.1-.2.2-.3.3-.5.4-.7.8-1.5 1.1-2.4h2.4c-.8 1.4-2.2 2.5-3.8 3Z"})}),C=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M12 4L4 7.9V20h16V7.9L12 4zm6.5 14.5H14V13h-4v5.5H5.5V8.8L12 5.7l6.5 3.1v9.7z"})}),S=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"m11.3 17.2-5-5c-.1-.1-.1-.3 0-.4l2.3-2.3-1.1-1-2.3 2.3c-.7.7-.7 1.8 0 2.5l5 5H7.5v1.5h5.3v-5.2h-1.5v2.6zm7.5-6.4-5-5h2.7V4.2h-5.2v5.2h1.5V6.8l5 5c.1.1.1.3 0 .4l-2.3 2.3 1.1 1.1 2.3-2.3c.6-.7.6-1.9-.1-2.5z"})}),k=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M11.25 5h1.5v15h-1.5V5zM6 10h1.5v10H6V10zm12 4h-1.5v6H18v-6z"})}),T=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M17.5 10h-1.7l-3.7 10.5h1.7l.9-2.6h3.9l.9 2.6h1.7L17.5 10zm-2.2 6.3 1.4-4 1.4 4h-2.8zm-4.8-3.8c1.6-1.8 2.9-3.6 3.7-5.7H16V5.2h-5.8V3H8.8v2.2H3v1.5h9.6c-.7 1.6-1.8 3.1-3.1 4.6C8.6 10.2 7.8 9 7.2 8H5.6c.6 1.4 1.7 2.9 2.9 4.4l-2.4 2.4c-.3.4-.7.8-1.1 1.2l1 1 1.2-1.2c.8-.8 1.6-1.5 2.3-2.3.8.9 1.7 1.7 2.5 2.5l.6-1.5c-.7-.6-1.4-1.3-2.1-2z"})}),B=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M4.75 4a.75.75 0 0 0-.75.75v7.826c0 .2.08.39.22.53l6.72 6.716a2.313 2.313 0 0 0 3.276-.001l5.61-5.611-.531-.53.532.528a2.315 2.315 0 0 0 0-3.264L13.104 4.22a.75.75 0 0 0-.53-.22H4.75ZM19 12.576a.815.815 0 0 1-.236.574l-5.61 5.611a.814.814 0 0 1-1.153 0L5.5 12.264V5.5h6.763l6.5 6.502a.816.816 0 0 1 .237.574ZM8.75 9.75a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"})}),E=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M13 5c-3.3 0-6 2.7-6 6 0 1.4.5 2.7 1.3 3.7l-3.8 3.8 1.1 1.1 3.8-3.8c1 .8 2.3 1.3 3.7 1.3 3.3 0 6-2.7 6-6S16.3 5 13 5zm0 10.5c-2.5 0-4.5-2-4.5-4.5s2-4.5 4.5-4.5 4.5 2 4.5 4.5-2 4.5-4.5 4.5z"})}),L=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M10.289 4.836A1 1 0 0111.275 4h1.306a1 1 0 01.987.836l.244 1.466c.787.26 1.503.679 2.108 1.218l1.393-.522a1 1 0 011.216.437l.653 1.13a1 1 0 01-.23 1.273l-1.148.944a6.025 6.025 0 010 2.435l1.149.946a1 1 0 01.23 1.272l-.653 1.13a1 1 0 01-1.216.437l-1.394-.522c-.605.54-1.32.958-2.108 1.218l-.244 1.466a1 1 0 01-.987.836h-1.306a1 1 0 01-.986-.836l-.244-1.466a5.995 5.995 0 01-2.108-1.218l-1.394.522a1 1 0 01-1.217-.436l-.653-1.131a1 1 0 01.23-1.272l1.149-.946a6.026 6.026 0 010-2.435l-1.148-.944a1 1 0 01-.23-1.272l.653-1.131a1 1 0 011.217-.437l1.393.522a5.994 5.994 0 012.108-1.218l.244-1.466zM14.929 12a3 3 0 11-6 0 3 3 0 016 0z"})}),M=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M16.83 6.342l.602.3.625-.25.443-.176v12.569l-.443-.178-.625-.25-.603.301-1.444.723-2.41-.804-.475-.158-.474.158-2.41.803-1.445-.722-.603-.3-.625.25-.443.177V6.215l.443.178.625.25.603-.301 1.444-.722 2.41.803.475.158.474-.158 2.41-.803 1.445.722zM20 4l-1.5.6-1 .4-2-1-3 1-3-1-2 1-1-.4L5 4v17l1.5-.6 1-.4 2 1 3-1 3 1 2-1 1 .4 1.5.6V4zm-3.5 6.25v-1.5h-8v1.5h8zm0 3v-1.5h-8v1.5h8zm-8 3v-1.5h8v1.5h-8z"})}),A=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M12 4a8 8 0 1 1 .001 16.001A8 8 0 0 1 12 4Zm0 1.5a6.5 6.5 0 1 0-.001 13.001A6.5 6.5 0 0 0 12 5.5Zm.75 11h-1.5V15h1.5v1.5Zm-.445-9.234a3 3 0 0 1 .445 5.89V14h-1.5v-1.25c0-.57.452-.958.917-1.01A1.5 1.5 0 0 0 12 8.75a1.5 1.5 0 0 0-1.5 1.5H9a3 3 0 0 1 3.305-2.984Z"})}),D=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M4 20h8v-1.5H4V20zM18.9 3.5c-.6-.6-1.5-.6-2.1 0l-7.2 7.2c-.4-.1-.7 0-1.1.1-.5.2-1.5.7-1.9 2.2-.4 1.7-.8 2.2-1.1 2.7-.1.1-.2.3-.3.4l-.6 1.1H6c2 0 3.4-.4 4.7-1.4.8-.6 1.2-1.4 1.3-2.3 0-.3 0-.5-.1-.7L19 5.7c.5-.6.5-1.6-.1-2.2zM9.7 14.7c-.7.5-1.5.8-2.4 1 .2-.5.5-1.2.8-2.3.2-.6.4-1 .8-1.1.5-.1 1 .1 1.3.3.2.2.3.5.2.8 0 .3-.1.9-.7 1.3z"})});const R=Object.freeze({width:720,height:180,top:16,right:14,bottom:26,left:48}),O=Object.freeze({width:96,height:24,inset:3});function P(e){return Math.round(100*e)/100}function $(e){const s=/^(\d{4})-(\d{2})-(\d{2})$/.exec(String(e||""));if(!s)return null;const t=new Date(Number(s[1]),Number(s[2])-1,Number(s[3]));return Number.isNaN(t.getTime())?null:t}function I(e){const s=$(e);return s?new Intl.DateTimeFormat(void 0,{month:"short",day:"numeric"}).format(s):String(e||"")}function H(e){return(new Intl.NumberFormat).format(Math.round(e||0))}const G=R.height-R.bottom;function z(e){return!e||e.length<2?"":e.map((e,s)=>`${0===s?"M":"L"}${e.x} ${e.y}`).join(" ")}function F(e){const s=z(e);if(""===s)return"";const t=e[0];return`${s} L${e[e.length-1].x} ${G} L${t.x} ${G} Z`}function V(e){const s=(Array.isArray(e)?e:[]).map(e=>Number(e)||0);if(s.length<2)return"single";const t=Math.floor(s.length/2),a=e=>0===e.length?0:e.reduce((e,s)=>e+s,0)/e.length,l=a(s.slice(0,t)),n=a(s.slice(t));return 0===l?n>0?"rising":"steady":n>1.1*l?"rising":n<.9*l?"falling":"steady"}function U(e){switch(e){case"rising":return(0,l.__)("Rising","gloty");case"falling":return(0,l.__)("Falling","gloty");case"single":return(0,l.__)("One day","gloty");default:return(0,l.__)("Steady","gloty")}}function q({values:e=[],label:s=""}){const{mode:t,points:a,max:n}=function(e,s={}){const t=s.width??O.width,a=s.height??O.height,l=s.inset??O.inset,n=(Array.isArray(e)?e:[]).map(e=>Number(e)||0);if(0===n.length)return{mode:"empty",points:[],max:0};if(1===n.length)return{mode:"single",points:[{x:P(t/2),y:P(a/2)}],max:n[0]};const i=Math.max(...n),r=t-2*l,o=a-2*l,c=e=>P(l+e/(n.length-1)*r);return i<=0?{mode:"flat",points:n.map((e,s)=>({x:c(s),y:P(a-l)})),max:0}:{mode:"line",points:n.map((e,s)=>({x:c(s),y:P(l+o*(1-e/i))})),max:i}}(e),i=V(e),r=n<=0&&"empty"!==t?(0,l.sprintf)(/* translators: %s: series name. */ /* translators: %s: series name. */ 2 2 (0,l.__)("%s — no views in this window","gloty"),s):(0,l.sprintf)(/* translators: 1: series name, 2: trend direction, 3: busiest-day views. */ /* translators: 1: series name, 2: trend direction, 3: busiest-day views. */ 3 (0,l.__)("%1$s — %2$s, busiest day %3$d views","gloty"),s, V(i).toLocaleLowerCase(),n);return"empty"===t?(0,u.jsx)("span",{className:"wpshelf-sparkline__none",role:"img","aria-label":(0,l.sprintf)(/* translators: %s: series name. */ /* translators: %s: series name. */4 (0,l.__)("%s — nothing recorded","gloty"),s),children:"—"}):(0, u.jsx)("svg",{className:"wpshelf-sparkline",viewBox:`0 0 ${R.width} ${R.height}`,width:R.width,height:R.height,role:"img","aria-label":r,children:"single"===t?(0,u.jsx)("circle",{className:"wpshelf-sparkline__dot",cx:a[0].x,cy:a[0].y,r:2.5}):(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("polyline",{className:"wpshelf-sparkline__line",points:a.map(e=>`${e.x},${e.y}`).join(" "),vectorEffect:"non-scaling-stroke"}),(0,u.jsx)("circle",{className:"wpshelf-sparkline__dot",cx:a[a.length-1].x,cy:a[a.length-1].y,r:2})]})})}function q({trend:e,windowDays:s=0,firstRecorded:t="",languageNames:a={}}){const[i,r]=(0,n.useState)(null),o=(0,n.useId)(),c=(0,n.useId)(),{days:d,mode:h,peak:g}=e,_=function(e){const s=Number(e);if(!Number.isFinite(s)||s<=0)return 2;const t=Math.floor(Math.log10(s));for(const e of[t-1,t,t+1]){const t=Math.pow(10,e);for(const e of[1,1.5,2,2.5,3,4,5,6,8,10]){const a=e*t;if(a>=s&&Number.isInteger(a)&&a%2==0)return a}}return 2*Math.ceil(s/2)}(e.max),p=(0,n.useMemo)(()=>function(e,s){const t=D.width-D.left-D.right,a=D.height-D.top-D.bottom,l=Math.max(1,Number(s)||1),n=(e||[]).length;return(e||[]).map((e,s)=>({x:O(n<2?D.left+t/2:D.left+s/(n-1)*t),y:O(D.top+a*(1-e.total/l)),date:e.date,total:e.total}))}(d,_),[d,_]);if("empty"===h)return(0,u.jsx)("p",{className:"wpshelf-chart__blank wpshelf-muted",children:"never"===e.reason?(0,l.__)("No views recorded yet, so there is no trend to draw. Counting starts from the moment this version was installed — give it a day of traffic.","gloty"):(0,l.sprintf)(/* translators: 1: number of days in the window, 2: date counting began. */ /* translators: 1: number of days in the window, 2: date counting began. */5 (0,l.__)("No views in the last %1$d days, so there is no trend to draw. Counting began on %2$s, so there is history — just none inside this window. Try a longer range.","gloty"),s,t)});if("single"===h){const e=d[0];return(0, u.jsxs)("div",{className:"wpshelf-chart__single",children:[(0,u.jsx)("p",{className:"wpshelf-chart__single-value",children:I(e.total)}),(0,u.jsx)("p",{className:"wpshelf-chart__single-label wpshelf-muted",children:(0,l.sprintf)(/* translators: %s: a date. */ /* translators: %s: a date. */6 (0,l.__)("Views on %s — the first day on record. A trend needs a second day; this chart appears tomorrow.","gloty"), $(e.date))})]})}const m=(y=d.length)<2?[0]:y<14?[0,y-1]:[0,Math.floor((y-1)/2),y-1];var y;const f=[_,_/2,0],w=null===i?null:p[i],x=(0,l.sprintf)(/* translators: 1: number of days, 2: first date, 3: last date, 4: peak views, 5: date of the peak. */ /* translators: 1: number of days, 2: first date, 3: last date, 4: peak views, 5: date of the peak. */7 (0,l.__)("Daily views across %1$d days, %2$s to %3$s. Busiest day %4$s views on %5$s. Every day is listed in the table below.","gloty"),d.length, $(e.from),$(e.to),I(g?.total||0),$(g?.date||e.to)),v=g?p[g.index]:null,j=!!v&&v.y-D.top>18,b=v?v.x<D.left+32?"start":v.x>D.width-D.right-32?"end":"middle":"middle";return(0,u.jsxs)("div",{className:"wpshelf-chart",children:[(0,u.jsxs)("svg",{className:"wpshelf-chart__svg",viewBox:`0 0 ${D.width} ${D.height}`,preserveAspectRatio:"xMidYMid meet",role:"img",tabIndex:0,"aria-labelledby":`${o} ${c}`,onPointerMove:e=>{const s=e.currentTarget.getBoundingClientRect();if(s.width<=0)return;const t=(e.clientX-s.left)/s.width*D.width,a=D.width-D.left-D.right,l=(t-D.left)/a,n=Math.round(l*(d.length-1));r(Math.min(d.length-1,Math.max(0,n)))},onPointerLeave:()=>r(null),onBlur:()=>r(null),onKeyDown:e=>{const s={ArrowLeft:-1,ArrowRight:1,Home:-d.length,End:d.length};var t;"Escape"!==e.key?void 0!==s[e.key]&&(e.preventDefault(),t=s[e.key],r(e=>{const s=(null===e?d.length-1:e)+t;return Math.min(d.length-1,Math.max(0,s))})):r(null)},children:[(0,u.jsx)("title",{id:o,children:(0,l.__)("Views per day","gloty")}),(0,u.jsx)("desc",{id:c,children:x}),f.map(e=>{const s=D.top+(D.height-D.top-D.bottom)*(1-e/_);return(0,u.jsxs)("g",{children:[(0,u.jsx)("line",{className:"wpshelf-chart__grid",x1:D.left,x2:D.width-D.right,y1:s,y2:s,vectorEffect:"non-scaling-stroke"}),(0,u.jsx)("text",{className:"wpshelf-chart__tick",x:D.left-8,y:s+4,textAnchor:"end",children:I(e)})]},e)}),(0,u.jsx)("path",{className:"wpshelf-chart__area",d:z(p)}),(0,u.jsx)("path",{className:"wpshelf-chart__line",d:G(p),vectorEffect:"non-scaling-stroke"}),v&&(0,u.jsx)("text",{className:"wpshelf-chart__peak",x:v.x,y:j?v.y-10:v.y+18,textAnchor:b,children:I(g.total)}),m.map(e=>(0,u.jsx)("text",{className:"wpshelf-chart__tick",x:p[e].x,y:D.height-8,textAnchor:0===e?"start":e===d.length-1?"end":"middle",children:$(d[e].date)},e)),w&&(0,u.jsxs)("g",{children:[(0,u.jsx)("line",{className:"wpshelf-chart__crosshair",x1:w.x,x2:w.x,y1:D.top,y2:H,vectorEffect:"non-scaling-stroke"}),(0,u.jsx)("circle",{className:"wpshelf-chart__dot",cx:w.x,cy:w.y,r:4,vectorEffect:"non-scaling-stroke"})]})]}),w&&(0,u.jsxs)("div",{className:"wpshelf-chart__tip",role:"status",style:{left:w.x/D.width*100+"%"},children:[(0,u.jsx)("span",{className:"wpshelf-chart__tip-value",children:(0,l.sprintf)(/* translators: %s: a number of views. */ /* translators: %s: a number of views. */8 (0,l._x)("%s views","tooltip readout","gloty"), I(w.total))}),(0,u.jsx)("span",{className:"wpshelf-chart__tip-date",children:$(w.date)}),Object.entries(d[i].perLanguage).length>0&&(0,u.jsx)("ul",{className:"wpshelf-chart__tip-list",children:Object.entries(d[i].perLanguage).map(([e,s])=>(0,u.jsxs)("li",{children:[a[e]||e.toUpperCase()," ",(0,u.jsx)("b",{children:I(s)})]},e))})]}),(0,u.jsx)("p",{className:"wpshelf-chart__note wpshelf-muted",children:(0,l.__)("Hover or focus the chart and use the arrow keys to read a single day. The last day is still in progress.","gloty")})]})}const W=[7,30,90];function X(){const[e,s]=(0,n.useState)(30),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)(!0),[o,c]=(0,n.useState)(null),d=(0,n.useCallback)(async e=>{r(!0),c(null);try{const s=await m()({path:`/gloty/v1/analytics/traffic?days=${e}`});a(s)}catch(e){c(e?.message||(0,l.__)("Could not load traffic data.","gloty"))}finally{r(!1)}},[]);(0,n.useEffect)(()=>{d(e)},[d,e]);const h=t?.totals||[],g=t?.total_views||0,p=(0,n.useMemo)(()=>function({series:e=[],range:s=null,firstRecorded:t=""}={}){const a=Array.isArray(e)?e:[],l=s?.from||"",n=s?.to||"";if(!l||!n||0===a.length)return{mode:"empty",reason:t?"window":"never",days:[],max:0,peak:null,from:l,to:n};const i=function(e,s){const t=P(e),a=P(s);if(!t||!a||t>a)return[];const l=[],n=new Date(t.getTime());for(;n<=a&&l.length<400;){const e=String(n.getMonth()+1).padStart(2,"0"),s=String(n.getDate()).padStart(2,"0");l.push(`${n.getFullYear()}-${e}-${s}`),n.setDate(n.getDate()+1)}return l}(t&&t>l?t:l,n),r=i.length>0?i:[n],o=new Map;for(const e of a){const s=e?.per_language;e?.date&&s&&o.set(e.date,s)}let c=0,d=null;const h=r.map((e,s)=>{const t=o.get(e)||{};let a=0;for(const e of Object.values(t))a+=Number(e)||0;return a>c&&(c=a,d={index:s,date:e,total:a}),{date:e,total:a,perLanguage:t}});return{mode:h.length<2?"single":"line",reason:null,days:h,max:c,peak:d,from:r[0],to:r[r.length-1]}}({series:t?.series||[],range:t?.range||null,firstRecorded:t?.first_recorded||""}),[t]),f=(0,n.useMemo)(()=>Object.fromEntries((t?.totals||[]).map(e=>[e.code,e.name])),[t]);return(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-analytics-screen",children:[(0,u.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("How much of your traffic reads which language. Counted on this site, in your own database — no visitor data is collected and nothing is sent anywhere.","gloty")}),o&&(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:o}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsxs)(y.CardHeader,{size:"small",children:[(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Views by language","gloty")}),(0,u.jsx)("div",{className:"wpshelf-range-picker",role:"group","aria-label":(0,l.__)("Range","gloty"),children:W.map(t=>(0,u.jsx)(y.Button,{size:"compact",variant:t===e?"primary":"secondary","aria-pressed":t===e,onClick:()=>s(t),children:(0,l.sprintf)(/* translators: %d: number of days. */ /* translators: %d: number of days. */9 (0,l.__)("%d days","gloty"),t)},t))})]}),(0, u.jsxs)(y.CardBody,{children:[i&&!t&&(0,u.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,u.jsx)(y.Spinner,{}),(0,u.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading traffic…","gloty")})]}),t&&(0,u.jsxs)("div",{className:i?"wpshelf-analytics-body wpshelf-analytics-body--stale":"wpshelf-analytics-body","aria-busy":i,children:[h.length>0&&(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.sprintf)(/* translators: 1: total views, 2: start date, 3: end date. */ /* translators: 1: total views, 2: start date, 3: end date. */10 (0,l.__)("%1$s views between %2$s and %3$s.","gloty"), I(g),t?.range?.from||"",t?.range?.to||"")}),(0,u.jsx)(q,{trend:p,windowDays:t?.range?.days||0,firstRecorded:t?.first_recorded||"",languageNames:f}),h.length>0&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsxs)(_,{className:"wp-list-table widefat striped wpshelf-table",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Language","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Views","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Share","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Trend","gloty")})]})}),(0,u.jsx)("tbody",{children:h.map(e=>{const s=function(e,s){return(e||[]).map(e=>Number(e?.perLanguage?.[s])||0)}(p.days,e.code);return(0,u.jsxs)("tr",{children:[(0,u.jsxs)("td",{children:[e.name," ",(0,u.jsx)("span",{className:"wpshelf-muted",children:e.code.toUpperCase()}),!e.is_translated&&(0,u.jsxs)("span",{className:"wpshelf-muted",children:[" — ",(0,l.__)("source","gloty")]})]}),(0,u.jsx)("td",{children:I(e.views)}),(0,u.jsxs)("td",{children:[e.share,"%"]}),(0,u.jsx)("td",{"data-search":V(F(s)),children:(0,u.jsx)(U,{values:s,label:e.name})})]},e.code)})})]}),(0,u.jsx)("p",{className:"wpshelf-chart__note wpshelf-muted",children:(0,l.__)("Each row’s trend is scaled to its own busiest day, so the shapes are comparable but their heights are not — read magnitude from the Views column.","gloty")})]})]})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("What this counts","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsxs)("ul",{className:"wpshelf-muted",style:{marginTop:0},children:[(0,u.jsx)("li",{children:(0,l.__)("Views, not visitors. Telling one person apart from another needs a cookie or a fingerprint, and this feature exists precisely so that neither is set.","gloty")}),(0,u.jsx)("li",{children:"browser"===t?.counter?(0,l.__)("Counted from the browser, so pages your cache served are included. A visitor with JavaScript disabled is not counted, and neither is most automated traffic.","gloty"):(0,l.__)("Requests that reached WordPress. A full-page cache (WP Rocket, LiteSpeed, Cloudflare) serves pages without starting PHP, so those views cannot be counted here and your real totals are higher. Settings → Analytics can move counting into the browser.","gloty")}),(0,u.jsx)("li",{children:(0,l.__)("Obvious crawlers are left out by their user agent, which is read and discarded. No IP address, page URL, user agent or account is ever stored.","gloty")}),t?.first_recorded&&(0,u.jsx)("li",{children:(0,l.sprintf)(/* translators: %s: date counting began. */ /* translators: %s: date counting began. */11 (0,l.__)("Counting began on %s.","gloty"),t.first_recorded)})]})})]})]})}const Y={not_translated:{label:(0,l.__)("Not translated","gloty"),description:(0,l.__)("No translation stored yet. Ready to queue.","gloty"),next:(0,l.__)("Queue translation","gloty"),tone:"muted"},pending:{label:(0,l.__)("Pending","gloty"),description:(0,l.__)("Captured and queued, waiting for dispatch.","gloty"),next:(0,l.__)("Wait or inspect the queue","gloty"),tone:"warn"},processing:{label:(0,l.__)("Processing","gloty"),description:(0,l.__)("In progress with the translation provider.","gloty"),next:(0,l.__)("Wait for the provider","gloty"),tone:"warn"},synced:{label:(0,l.__)("Synced","gloty"),description:(0,l.__)("Machine-translated and stored in local cache.","gloty"),next:null,tone:"success"},stale:{label:(0,l.__)("Out of date","gloty"),description:(0,l.__)("Source changed since the last translation. Needs re-sync.","gloty"),next:(0,l.__)("Re-sync","gloty"),tone:"warn"},failed:{label:(0,l.__)("Failed","gloty"),description:(0,l.__)("Could not be completed. Inspect error details.","gloty"),next:(0,l.__)("Retry or fix config","gloty"),tone:"error"},manually_edited:{label:(0,l.__)("Manually edited","gloty"),description:(0,l.__)("Human-reviewed. Machine sync will not overwrite it.","gloty"),next:(0,l.__)("Protected from overwrite","gloty"),tone:"info"},auto:{label:(0,l.__)("Synced","gloty"),description:(0,l.__)("Machine-translated and stored in local cache.","gloty"),next:null,tone:"success",alias:"synced"},manual:{label:(0,l.__)("Manually edited","gloty"),description:(0,l.__)("Human-reviewed. Machine sync will not overwrite it.","gloty"),next:(0,l.__)("Protected from overwrite","gloty"),tone:"info",alias:"manually_edited"},queued:{label:(0,l.__)("Queued","gloty"),description:(0,l.__)("Job created and waiting for execution.","gloty"),next:(0,l.__)("Wait for dispatch","gloty"),tone:"warn"},completed:{label:(0,l.__)("Completed","gloty"),description:(0,l.__)("Job finished and results persisted.","gloty"),next:null,tone:"success"},complete:{label:(0,l.__)("Completed","gloty"),description:(0,l.__)("Scan finished for all currently discovered entities.","gloty"),next:null,tone:"success",alias:"completed"},cancelled:{label:(0,l.__)("Cancelled","gloty"),description:(0,l.__)("Stopped by an operator action.","gloty"),next:null,tone:"muted"},running:{label:(0,l.__)("Running","gloty"),description:(0,l.__)("Background scan is in progress.","gloty"),next:null,tone:"info"},idle:{label:(0,l.__)("Idle","gloty"),description:(0,l.__)("No active processing right now.","gloty"),next:null,tone:"muted"},paused:{label:(0,l.__)("Paused","gloty"),description:(0,l.__)("Scan paused by an operator and ready to resume.","gloty"),next:(0,l.__)("Resume scan","gloty"),tone:"muted"}},Z={success:"wpshelf-chip wpshelf-chip--success",warn:"wpshelf-chip wpshelf-chip--warn",error:"wpshelf-chip wpshelf-chip--error",info:"wpshelf-chip wpshelf-chip--info",muted:"wpshelf-chip wpshelf-chip--muted"};function J(e){const s=Y[e]?.tone;return Z[s]||"wpshelf-chip"}function K({status:e}){const s=Y[e],t=s?.label||e,a=s?.description||"",l=s?.next?`${t}: ${s.next}`:a||t;return(0,n.createElement)("span",{className:J(e),title:a||t,"aria-label":l,"data-status":e},t)}function Q({statuses:e}){return(0,n.createElement)("div",{className:"wpshelf-status-glossary"},e.map(e=>{const s=function(e){return Y[e]||null}(e);return s?(0,n.createElement)("div",{key:e,className:"wpshelf-status-glossary__item"},(0,n.createElement)(K,{status:e}),(0,n.createElement)("p",{className:"wpshelf-status-glossary__text"},s.description||(s.next?`${(0,l.__)("Next","gloty")}: ${s.next}.`:(0,l.__)("No action needed.","gloty")))):null}))}function ee({title:e,subtitle:s,children:t,actions:a}){return(0,u.jsxs)("div",{className:"wpshelf-section-card",children:[(0,u.jsxs)("div",{className:"wpshelf-section-card__header",children:[(0,u.jsxs)("div",{children:[(0,u.jsx)("h2",{className:"wpshelf-section-card__title",children:e}),s&&(0,u.jsx)("p",{className:"wpshelf-section-card__subtitle",children:s})]}),a&&(0,u.jsx)("div",{className:"wpshelf-section-card__actions",children:a})]}),t]})}function se(e){const s=Number(e);return Number.isFinite(s)?s.toLocaleString():String(e??"")}function te(e){if(!e)return"—";let s=String(e).trim();s.includes("T")||(s=s.replace(" ","T")),/(?:[zZ]|[+-]\d\d:?\d\d)$/.test(s)||(s+="Z");const t=new Date(s).getTime();if(Number.isNaN(t))return"—";const a=(Date.now()-t)/1e3;return a<60?(0,l.__)("just now","gloty"):a<3600?Math.floor(a/60)+(0,l.__)("m ago","gloty"):a<86400?Math.floor(a/3600)+(0,l.__)("h ago","gloty"):Math.floor(a/86400)+(0,l.__)("d ago","gloty")}function ae(e){const s=String(e||"");if(""===s)return"";let t=s;try{t="undefined"!=typeof DOMParser?(new DOMParser).parseFromString(s,"text/html").body.textContent||"":s.replace(/<[^>]*>/g," ")}catch(e){t=s.replace(/<[^>]*>/g," ")}return t.replace(/\s+/g," ").trim()}function le(e){return ae(e)||String(e||"").trim()}function ne({icon:e,title:s,hint:t}){return(0,u.jsxs)("div",{className:"wpshelf-empty",children:[e&&(0,u.jsx)("div",{className:"wpshelf-empty__icon",children:e}),(0,u.jsx)("p",{className:"wpshelf-empty__title",children:s}),t&&(0,u.jsx)("p",{className:"wpshelf-empty__hint",children:t})]})}function ie({title:e,message:s,confirmLabel:t,isDestructive:a=!0,busy:n=!1,onConfirm:i,onCancel:r}){return(0,u.jsxs)(y.Modal,{title:e,onRequestClose:r,className:"wpshelf-confirm-modal",size:"small",children:[(0,u.jsx)("p",{className:"wpshelf-confirm-modal__message",children:s}),(0,u.jsxs)("div",{className:"wpshelf-confirm-modal__actions",children:[(0,u.jsx)(y.Button,{variant:"tertiary",onClick:r,disabled:n,children:(0,l.__)("Cancel","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",isDestructive:a,onClick:i,isBusy:n,disabled:n,children:t||(0,l.__)("Delete","gloty")})]})]})}function re({label:e}){return(0,u.jsxs)("span",{className:"wpshelf-inline-busy",role:"status","aria-live":"polite",children:[(0,u.jsx)(y.Spinner,{}),(0,u.jsx)("span",{className:"wpshelf-inline-busy__label",children:e})]})}function oe({text:e}){return(0,u.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,u.jsx)(y.Spinner,{}),e&&(0,u.jsx)("span",{className:"wpshelf-skeleton__text",children:e})]})}function ce({cols:e=4,rows:s=5,headers:t}){const a=t?t.length:e;return(0,u.jsxs)("table",{className:"wp-list-table widefat striped wpshelf-table-skeleton",children:[(0,u.jsx)("thead",{children:(0,u.jsx)("tr",{children:Array.from({length:a},(e,s)=>(0,u.jsx)("th",{scope:"col",children:t?.[s]?t[s]:(0,u.jsx)("span",{className:"wpshelf-shimmer wpshelf-shimmer--header"})},s))})}),(0,u.jsx)("tbody",{children:Array.from({length:s},(e,s)=>(0,u.jsx)("tr",{children:Array.from({length:a},(e,t)=>(0,u.jsx)("td",{children:(0,u.jsx)("span",{className:"wpshelf-shimmer",style:{width:55+(7*s+13*t)%35+"%"}})},t))},s))})]})}function de(e){return e>=90?"danger":e>=75?"warn":""}const he={success:"var(--wpshelf-success)",warn:"var(--wpshelf-warn)",danger:"var(--wpshelf-danger)"},ge={success:"var(--wpshelf-success-dark)",warn:"var(--wpshelf-warn-dark)",danger:"var(--wpshelf-danger)"};function ue({value:e,max:s,label:t,tone:a,scale:l="usage"}){const n=s>0?Math.min(e/s*100,100):0,i=t||`${Math.round(n)}%`,r=a||("completion"===l?function(e){return e>=67?"success":e>=34?"warn":"danger"}(n):de(n)),o=he[r]||"",c=ge[r]||"";return(0,u.jsxs)("div",{className:"wpshelf-progress",children:[(0,u.jsx)("div",{className:"wpshelf-progress__bar",role:"progressbar","aria-valuenow":Math.round(n),"aria-valuemin":0,"aria-valuemax":100,"aria-valuetext":i,children:(0,u.jsx)("div",{className:"wpshelf-progress__fill",style:{width:`${n}%`,...o?{background:o}:{}}})}),(0,u.jsx)("span",{className:"wpshelf-progress__label","aria-hidden":"true",style:c?{color:c}:void 0,children:i})]})}function _e({steps:e,current:s}){return(0,u.jsx)("ol",{className:"wpshelf-stepper","aria-label":(0,l.__)("Setup progress","gloty"),children:e.map((t,a)=>{const l=a===s;let n="wpshelf-stepper__step";return a<s&&(n+=" wpshelf-stepper__step--done"),l&&(n+=" wpshelf-stepper__step--active"),(0,u.jsxs)("li",{className:n,"aria-current":l?"step":void 0,children:[a<e.length-1&&(0,u.jsx)("span",{className:"wpshelf-stepper__connector","aria-hidden":"true"}),(0,u.jsx)("span",{className:"wpshelf-stepper__label",children:t.label})]},t.key)})})}function pe({items:e}){return(0,u.jsx)("div",{className:"wpshelf-milestones",role:"list",children:e.map(e=>{const s=e.done?(0,l.__)("Complete","gloty"):(0,l.__)("Pending","gloty");return(0,u.jsxs)("div",{className:"wpshelf-milestone "+(e.done?"wpshelf-milestone--done":"wpshelf-milestone--todo"),role:"listitem","aria-label":`${e.title}: ${s}`,children:[(0,u.jsx)("div",{className:"wpshelf-milestone__title",children:e.title}),(0,u.jsx)("div",{className:"wpshelf-milestone__state",children:s})]},e.key)})})}function me({oldText:e,newText:s}){const t=(e||"").split(/(\s+)/),a=(s||"").split(/(\s+)/),l=t.length,n=a.length,i=Array.from({length:l+1},()=>new Array(n+1).fill(0));for(let e=1;e<=l;e++)for(let s=1;s<=n;s++)i[e][s]=t[e-1]===a[s-1]?i[e-1][s-1]+1:Math.max(i[e-1][s],i[e][s-1]);const r=[];let o=l,c=n;for(;o>0||c>0;)o>0&&c>0&&t[o-1]===a[c-1]?(r.unshift({type:"same",text:t[o-1]}),o--,c--):c>0&&(0===o||i[o][c-1]>=i[o-1][c])?(r.unshift({type:"add",text:a[c-1]}),c--):(r.unshift({type:"del",text:t[o-1]}),o--);return(0,u.jsx)("div",{className:"wpshelf-diff__content",children:r.map((e,s)=>"del"===e.type?(0,u.jsx)("del",{className:"wpshelf-diff__del",children:e.text},s):"add"===e.type?(0,u.jsx)("ins",{className:"wpshelf-diff__ins",children:e.text},s):(0,u.jsx)("span",{children:e.text},s))})}async function ye(){try{const e=await m()({path:"/gloty/v1/license/plans"});return Array.isArray(e?.plans)?e.plans:[]}catch{return[]}}function fe(e,s){const t=e?.plan_slug||"",a=e?.characters_limit??0;return(s||[]).filter(e=>e.slug!==t).filter(e=>!e.renews||(e.quota?.limit??0)>a).sort((e,s)=>e.price-s.price)}function we(e){const s=`$${(e.price/100).toLocaleString(void 0,{maximumFractionDigits:2})}`;return e.renews?"year"===e.interval?(0,l.sprintf)(/* translators: %s: price, e.g. $290 */ /* translators: %s: price, e.g. $290 */3 (0,l.__)("%1$s — %2$s, busiest day %3$d views","gloty"),s,U(i).toLocaleLowerCase(),n);return"empty"===t?(0,_.jsx)("span",{className:"wpshelf-sparkline__none",role:"img","aria-label":(0,l.sprintf)(/* translators: %s: series name. */ /* translators: %s: series name. */ 4 (0,l.__)("%s — nothing recorded","gloty"),s),children:"—"}):(0,_.jsx)("svg",{className:"wpshelf-sparkline",viewBox:`0 0 ${O.width} ${O.height}`,width:O.width,height:O.height,role:"img","aria-label":r,children:"single"===t?(0,_.jsx)("circle",{className:"wpshelf-sparkline__dot",cx:a[0].x,cy:a[0].y,r:2.5}):(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("polyline",{className:"wpshelf-sparkline__line",points:a.map(e=>`${e.x},${e.y}`).join(" "),vectorEffect:"non-scaling-stroke"}),(0,_.jsx)("circle",{className:"wpshelf-sparkline__dot",cx:a[a.length-1].x,cy:a[a.length-1].y,r:2})]})})}function W({trend:e,windowDays:s=0,firstRecorded:t="",languageNames:a={}}){const[i,r]=(0,n.useState)(null),o=(0,n.useId)(),c=(0,n.useId)(),{days:d,mode:h,peak:g}=e,u=function(e){const s=Number(e);if(!Number.isFinite(s)||s<=0)return 2;const t=Math.floor(Math.log10(s));for(const e of[t-1,t,t+1]){const t=Math.pow(10,e);for(const e of[1,1.5,2,2.5,3,4,5,6,8,10]){const a=e*t;if(a>=s&&Number.isInteger(a)&&a%2==0)return a}}return 2*Math.ceil(s/2)}(e.max),p=(0,n.useMemo)(()=>function(e,s){const t=R.width-R.left-R.right,a=R.height-R.top-R.bottom,l=Math.max(1,Number(s)||1),n=(e||[]).length;return(e||[]).map((e,s)=>({x:P(n<2?R.left+t/2:R.left+s/(n-1)*t),y:P(R.top+a*(1-e.total/l)),date:e.date,total:e.total}))}(d,u),[d,u]);if("empty"===h)return(0,_.jsx)("p",{className:"wpshelf-chart__blank wpshelf-muted",children:"never"===e.reason?(0,l.__)("No views recorded yet, so there is no trend to draw. Counting starts from the moment this version was installed — give it a day of traffic.","gloty"):(0,l.sprintf)(/* translators: 1: number of days in the window, 2: date counting began. */ /* translators: 1: number of days in the window, 2: date counting began. */ 5 (0,l.__)("No views in the last %1$d days, so there is no trend to draw. Counting began on %2$s, so there is history — just none inside this window. Try a longer range.","gloty"),s,t)});if("single"===h){const e=d[0];return(0,_.jsxs)("div",{className:"wpshelf-chart__single",children:[(0,_.jsx)("p",{className:"wpshelf-chart__single-value",children:H(e.total)}),(0,_.jsx)("p",{className:"wpshelf-chart__single-label wpshelf-muted",children:(0,l.sprintf)(/* translators: %s: a date. */ /* translators: %s: a date. */ 6 (0,l.__)("Views on %s — the first day on record. A trend needs a second day; this chart appears tomorrow.","gloty"),I(e.date))})]})}const m=(y=d.length)<2?[0]:y<14?[0,y-1]:[0,Math.floor((y-1)/2),y-1];var y;const f=[u,u/2,0],w=null===i?null:p[i],x=(0,l.sprintf)(/* translators: 1: number of days, 2: first date, 3: last date, 4: peak views, 5: date of the peak. */ /* translators: 1: number of days, 2: first date, 3: last date, 4: peak views, 5: date of the peak. */ 7 (0,l.__)("Daily views across %1$d days, %2$s to %3$s. Busiest day %4$s views on %5$s. Every day is listed in the table below.","gloty"),d.length,I(e.from),I(e.to),H(g?.total||0),I(g?.date||e.to)),v=g?p[g.index]:null,j=!!v&&v.y-R.top>18,b=v?v.x<R.left+32?"start":v.x>R.width-R.right-32?"end":"middle":"middle";return(0,_.jsxs)("div",{className:"wpshelf-chart",children:[(0,_.jsxs)("svg",{className:"wpshelf-chart__svg",viewBox:`0 0 ${R.width} ${R.height}`,preserveAspectRatio:"xMidYMid meet",role:"img",tabIndex:0,"aria-labelledby":`${o} ${c}`,onPointerMove:e=>{const s=e.currentTarget.getBoundingClientRect();if(s.width<=0)return;const t=(e.clientX-s.left)/s.width*R.width,a=R.width-R.left-R.right,l=(t-R.left)/a,n=Math.round(l*(d.length-1));r(Math.min(d.length-1,Math.max(0,n)))},onPointerLeave:()=>r(null),onBlur:()=>r(null),onKeyDown:e=>{const s={ArrowLeft:-1,ArrowRight:1,Home:-d.length,End:d.length};var t;"Escape"!==e.key?void 0!==s[e.key]&&(e.preventDefault(),t=s[e.key],r(e=>{const s=(null===e?d.length-1:e)+t;return Math.min(d.length-1,Math.max(0,s))})):r(null)},children:[(0,_.jsx)("title",{id:o,children:(0,l.__)("Views per day","gloty")}),(0,_.jsx)("desc",{id:c,children:x}),f.map(e=>{const s=R.top+(R.height-R.top-R.bottom)*(1-e/u);return(0,_.jsxs)("g",{children:[(0,_.jsx)("line",{className:"wpshelf-chart__grid",x1:R.left,x2:R.width-R.right,y1:s,y2:s,vectorEffect:"non-scaling-stroke"}),(0,_.jsx)("text",{className:"wpshelf-chart__tick",x:R.left-8,y:s+4,textAnchor:"end",children:H(e)})]},e)}),(0,_.jsx)("path",{className:"wpshelf-chart__area",d:F(p)}),(0,_.jsx)("path",{className:"wpshelf-chart__line",d:z(p),vectorEffect:"non-scaling-stroke"}),v&&(0,_.jsx)("text",{className:"wpshelf-chart__peak",x:v.x,y:j?v.y-10:v.y+18,textAnchor:b,children:H(g.total)}),m.map(e=>(0,_.jsx)("text",{className:"wpshelf-chart__tick",x:p[e].x,y:R.height-8,textAnchor:0===e?"start":e===d.length-1?"end":"middle",children:I(d[e].date)},e)),w&&(0,_.jsxs)("g",{children:[(0,_.jsx)("line",{className:"wpshelf-chart__crosshair",x1:w.x,x2:w.x,y1:R.top,y2:G,vectorEffect:"non-scaling-stroke"}),(0,_.jsx)("circle",{className:"wpshelf-chart__dot",cx:w.x,cy:w.y,r:4,vectorEffect:"non-scaling-stroke"})]})]}),w&&(0,_.jsxs)("div",{className:"wpshelf-chart__tip",role:"status",style:{left:w.x/R.width*100+"%"},children:[(0,_.jsx)("span",{className:"wpshelf-chart__tip-value",children:(0,l.sprintf)(/* translators: %s: a number of views. */ /* translators: %s: a number of views. */ 8 (0,l._x)("%s views","tooltip readout","gloty"),H(w.total))}),(0,_.jsx)("span",{className:"wpshelf-chart__tip-date",children:I(w.date)}),Object.entries(d[i].perLanguage).length>0&&(0,_.jsx)("ul",{className:"wpshelf-chart__tip-list",children:Object.entries(d[i].perLanguage).map(([e,s])=>(0,_.jsxs)("li",{children:[a[e]||e.toUpperCase()," ",(0,_.jsx)("b",{children:H(s)})]},e))})]}),(0,_.jsx)("p",{className:"wpshelf-chart__note wpshelf-muted",children:(0,l.__)("Hover or focus the chart and use the arrow keys to read a single day. The last day is still in progress.","gloty")})]})}const X=[7,30,90];function Y(){const[e,s]=(0,n.useState)(30),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)(!0),[o,c]=(0,n.useState)(null),d=(0,n.useCallback)(async e=>{r(!0),c(null);try{const s=await y()({path:`/gloty/v1/analytics/traffic?days=${e}`});a(s)}catch(e){c(e?.message||(0,l.__)("Could not load traffic data.","gloty"))}finally{r(!1)}},[]);(0,n.useEffect)(()=>{d(e)},[d,e]);const h=t?.totals||[],g=t?.total_views||0,u=(0,n.useMemo)(()=>function({series:e=[],range:s=null,firstRecorded:t=""}={}){const a=Array.isArray(e)?e:[],l=s?.from||"",n=s?.to||"";if(!l||!n||0===a.length)return{mode:"empty",reason:t?"window":"never",days:[],max:0,peak:null,from:l,to:n};const i=function(e,s){const t=$(e),a=$(s);if(!t||!a||t>a)return[];const l=[],n=new Date(t.getTime());for(;n<=a&&l.length<400;){const e=String(n.getMonth()+1).padStart(2,"0"),s=String(n.getDate()).padStart(2,"0");l.push(`${n.getFullYear()}-${e}-${s}`),n.setDate(n.getDate()+1)}return l}(t&&t>l?t:l,n),r=i.length>0?i:[n],o=new Map;for(const e of a){const s=e?.per_language;e?.date&&s&&o.set(e.date,s)}let c=0,d=null;const h=r.map((e,s)=>{const t=o.get(e)||{};let a=0;for(const e of Object.values(t))a+=Number(e)||0;return a>c&&(c=a,d={index:s,date:e,total:a}),{date:e,total:a,perLanguage:t}});return{mode:h.length<2?"single":"line",reason:null,days:h,max:c,peak:d,from:r[0],to:r[r.length-1]}}({series:t?.series||[],range:t?.range||null,firstRecorded:t?.first_recorded||""}),[t]),m=(0,n.useMemo)(()=>Object.fromEntries((t?.totals||[]).map(e=>[e.code,e.name])),[t]);return(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-analytics-screen",children:[(0,_.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("How much of your traffic reads which language. Counted on this site, in your own database — no visitor data is collected and nothing is sent anywhere.","gloty")}),o&&(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:o}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsxs)(f.CardHeader,{size:"small",children:[(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Views by language","gloty")}),(0,_.jsx)("div",{className:"wpshelf-range-picker",role:"group","aria-label":(0,l.__)("Range","gloty"),children:X.map(t=>(0,_.jsx)(f.Button,{size:"compact",variant:t===e?"primary":"secondary","aria-pressed":t===e,onClick:()=>s(t),children:(0,l.sprintf)(/* translators: %d: number of days. */ /* translators: %d: number of days. */ 9 (0,l.__)("%d days","gloty"),t)},t))})]}),(0,_.jsxs)(f.CardBody,{children:[i&&!t&&(0,_.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,_.jsx)(f.Spinner,{}),(0,_.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading traffic…","gloty")})]}),t&&(0,_.jsxs)("div",{className:i?"wpshelf-analytics-body wpshelf-analytics-body--stale":"wpshelf-analytics-body","aria-busy":i,children:[h.length>0&&(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.sprintf)(/* translators: 1: total views, 2: start date, 3: end date. */ /* translators: 1: total views, 2: start date, 3: end date. */ 10 (0,l.__)("%1$s views between %2$s and %3$s.","gloty"),H(g),t?.range?.from||"",t?.range?.to||"")}),(0,_.jsx)(W,{trend:u,windowDays:t?.range?.days||0,firstRecorded:t?.first_recorded||"",languageNames:m}),h.length>0&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsxs)(p,{className:"wp-list-table widefat striped wpshelf-table",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Language","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Views","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Share","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Trend","gloty")})]})}),(0,_.jsx)("tbody",{children:h.map(e=>{const s=function(e,s){return(e||[]).map(e=>Number(e?.perLanguage?.[s])||0)}(u.days,e.code);return(0,_.jsxs)("tr",{children:[(0,_.jsxs)("td",{children:[e.name," ",(0,_.jsx)("span",{className:"wpshelf-muted",children:e.code.toUpperCase()}),!e.is_translated&&(0,_.jsxs)("span",{className:"wpshelf-muted",children:[" — ",(0,l.__)("source","gloty")]})]}),(0,_.jsx)("td",{children:H(e.views)}),(0,_.jsxs)("td",{children:[e.share,"%"]}),(0,_.jsx)("td",{"data-search":U(V(s)),children:(0,_.jsx)(q,{values:s,label:e.name})})]},e.code)})})]}),(0,_.jsx)("p",{className:"wpshelf-chart__note wpshelf-muted",children:(0,l.__)("Each row’s trend is scaled to its own busiest day, so the shapes are comparable but their heights are not — read magnitude from the Views column.","gloty")})]})]})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("What this counts","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsxs)("ul",{className:"wpshelf-muted",style:{marginTop:0},children:[(0,_.jsx)("li",{children:(0,l.__)("Views, not visitors. Telling one person apart from another needs a cookie or a fingerprint, and this feature exists precisely so that neither is set.","gloty")}),(0,_.jsx)("li",{children:"browser"===t?.counter?(0,l.__)("Counted from the browser, so pages your cache served are included. A visitor with JavaScript disabled is not counted, and neither is most automated traffic.","gloty"):(0,l.__)("Requests that reached WordPress. A full-page cache (WP Rocket, LiteSpeed, Cloudflare) serves pages without starting PHP, so those views cannot be counted here and your real totals are higher. Settings → Analytics can move counting into the browser.","gloty")}),(0,_.jsx)("li",{children:(0,l.__)("Obvious crawlers are left out by their user agent, which is read and discarded. No IP address, page URL, user agent or account is ever stored.","gloty")}),t?.first_recorded&&(0,_.jsx)("li",{children:(0,l.sprintf)(/* translators: %s: date counting began. */ /* translators: %s: date counting began. */ 11 (0,l.__)("Counting began on %s.","gloty"),t.first_recorded)})]})})]})]})}const Z={not_translated:{label:(0,l.__)("Not translated","gloty"),description:(0,l.__)("No translation stored yet. Ready to queue.","gloty"),next:(0,l.__)("Queue translation","gloty"),tone:"muted"},pending:{label:(0,l.__)("Pending","gloty"),description:(0,l.__)("Captured and queued, waiting for dispatch.","gloty"),next:(0,l.__)("Wait or inspect the queue","gloty"),tone:"warn"},processing:{label:(0,l.__)("Processing","gloty"),description:(0,l.__)("In progress with the translation provider.","gloty"),next:(0,l.__)("Wait for the provider","gloty"),tone:"warn"},synced:{label:(0,l.__)("Synced","gloty"),description:(0,l.__)("Machine-translated and stored in local cache.","gloty"),next:null,tone:"success"},stale:{label:(0,l.__)("Out of date","gloty"),description:(0,l.__)("Source changed since the last translation. Needs re-sync.","gloty"),next:(0,l.__)("Re-sync","gloty"),tone:"warn"},failed:{label:(0,l.__)("Failed","gloty"),description:(0,l.__)("Could not be completed. Inspect error details.","gloty"),next:(0,l.__)("Retry or fix config","gloty"),tone:"error"},manually_edited:{label:(0,l.__)("Manually edited","gloty"),description:(0,l.__)("Human-reviewed. Machine sync will not overwrite it.","gloty"),next:(0,l.__)("Protected from overwrite","gloty"),tone:"info"},auto:{label:(0,l.__)("Synced","gloty"),description:(0,l.__)("Machine-translated and stored in local cache.","gloty"),next:null,tone:"success",alias:"synced"},manual:{label:(0,l.__)("Manually edited","gloty"),description:(0,l.__)("Human-reviewed. Machine sync will not overwrite it.","gloty"),next:(0,l.__)("Protected from overwrite","gloty"),tone:"info",alias:"manually_edited"},queued:{label:(0,l.__)("Queued","gloty"),description:(0,l.__)("Job created and waiting for execution.","gloty"),next:(0,l.__)("Wait for dispatch","gloty"),tone:"warn"},completed:{label:(0,l.__)("Completed","gloty"),description:(0,l.__)("Job finished and results persisted.","gloty"),next:null,tone:"success"},complete:{label:(0,l.__)("Completed","gloty"),description:(0,l.__)("Scan finished for all currently discovered entities.","gloty"),next:null,tone:"success",alias:"completed"},cancelled:{label:(0,l.__)("Cancelled","gloty"),description:(0,l.__)("Stopped by an operator action.","gloty"),next:null,tone:"muted"},running:{label:(0,l.__)("Running","gloty"),description:(0,l.__)("Background scan is in progress.","gloty"),next:null,tone:"info"},idle:{label:(0,l.__)("Idle","gloty"),description:(0,l.__)("No active processing right now.","gloty"),next:null,tone:"muted"},paused:{label:(0,l.__)("Paused","gloty"),description:(0,l.__)("Scan paused by an operator and ready to resume.","gloty"),next:(0,l.__)("Resume scan","gloty"),tone:"muted"}},J={success:"wpshelf-chip wpshelf-chip--success",warn:"wpshelf-chip wpshelf-chip--warn",error:"wpshelf-chip wpshelf-chip--error",info:"wpshelf-chip wpshelf-chip--info",muted:"wpshelf-chip wpshelf-chip--muted"};function K(e){const s=Z[e]?.tone;return J[s]||"wpshelf-chip"}function Q({status:e}){const s=Z[e],t=s?.label||e,a=s?.description||"",l=s?.next?`${t}: ${s.next}`:a||t;return(0,n.createElement)("span",{className:K(e),title:a||t,"aria-label":l,"data-status":e},t)}function ee({statuses:e}){return(0,n.createElement)("div",{className:"wpshelf-status-glossary"},e.map(e=>{const s=function(e){return Z[e]||null}(e);return s?(0,n.createElement)("div",{key:e,className:"wpshelf-status-glossary__item"},(0,n.createElement)(Q,{status:e}),(0,n.createElement)("p",{className:"wpshelf-status-glossary__text"},s.description||(s.next?`${(0,l.__)("Next","gloty")}: ${s.next}.`:(0,l.__)("No action needed.","gloty")))):null}))}function se({title:e,subtitle:s,children:t,actions:a}){return(0,_.jsxs)("div",{className:"wpshelf-section-card",children:[(0,_.jsxs)("div",{className:"wpshelf-section-card__header",children:[(0,_.jsxs)("div",{children:[(0,_.jsx)("h2",{className:"wpshelf-section-card__title",children:e}),s&&(0,_.jsx)("p",{className:"wpshelf-section-card__subtitle",children:s})]}),a&&(0,_.jsx)("div",{className:"wpshelf-section-card__actions",children:a})]}),t]})}function te(e){const s=Number(e);return Number.isFinite(s)?s.toLocaleString():String(e??"")}function ae(e){if(!e)return"—";let s=String(e).trim();s.includes("T")||(s=s.replace(" ","T")),/(?:[zZ]|[+-]\d\d:?\d\d)$/.test(s)||(s+="Z");const t=new Date(s).getTime();if(Number.isNaN(t))return"—";const a=(Date.now()-t)/1e3;return a<60?(0,l.__)("just now","gloty"):a<3600?Math.floor(a/60)+(0,l.__)("m ago","gloty"):a<86400?Math.floor(a/3600)+(0,l.__)("h ago","gloty"):Math.floor(a/86400)+(0,l.__)("d ago","gloty")}function le(e){const s=String(e||"");if(""===s)return"";let t=s;try{t="undefined"!=typeof DOMParser?(new DOMParser).parseFromString(s,"text/html").body.textContent||"":s.replace(/<[^>]*>/g," ")}catch(e){t=s.replace(/<[^>]*>/g," ")}return t.replace(/\s+/g," ").trim()}function ne(e){return le(e)||String(e||"").trim()}function ie({icon:e,title:s,hint:t}){return(0,_.jsxs)("div",{className:"wpshelf-empty",children:[e&&(0,_.jsx)("div",{className:"wpshelf-empty__icon",children:e}),(0,_.jsx)("p",{className:"wpshelf-empty__title",children:s}),t&&(0,_.jsx)("p",{className:"wpshelf-empty__hint",children:t})]})}function re({title:e,message:s,confirmLabel:t,isDestructive:a=!0,busy:n=!1,onConfirm:i,onCancel:r}){return(0,_.jsxs)(f.Modal,{title:e,onRequestClose:r,className:"wpshelf-confirm-modal",size:"small",children:[(0,_.jsx)("p",{className:"wpshelf-confirm-modal__message",children:s}),(0,_.jsxs)("div",{className:"wpshelf-confirm-modal__actions",children:[(0,_.jsx)(f.Button,{variant:"tertiary",onClick:r,disabled:n,children:(0,l.__)("Cancel","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",isDestructive:a,onClick:i,isBusy:n,disabled:n,children:t||(0,l.__)("Delete","gloty")})]})]})}function oe({label:e}){return(0,_.jsxs)("span",{className:"wpshelf-inline-busy",role:"status","aria-live":"polite",children:[(0,_.jsx)(f.Spinner,{}),(0,_.jsx)("span",{className:"wpshelf-inline-busy__label",children:e})]})}function ce({text:e}){return(0,_.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,_.jsx)(f.Spinner,{}),e&&(0,_.jsx)("span",{className:"wpshelf-skeleton__text",children:e})]})}function de({cols:e=4,rows:s=5,headers:t}){const a=t?t.length:e;return(0,_.jsxs)("table",{className:"wp-list-table widefat striped wpshelf-table-skeleton",children:[(0,_.jsx)("thead",{children:(0,_.jsx)("tr",{children:Array.from({length:a},(e,s)=>(0,_.jsx)("th",{scope:"col",children:t?.[s]?t[s]:(0,_.jsx)("span",{className:"wpshelf-shimmer wpshelf-shimmer--header"})},s))})}),(0,_.jsx)("tbody",{children:Array.from({length:s},(e,s)=>(0,_.jsx)("tr",{children:Array.from({length:a},(e,t)=>(0,_.jsx)("td",{children:(0,_.jsx)("span",{className:"wpshelf-shimmer",style:{width:55+(7*s+13*t)%35+"%"}})},t))},s))})]})}function he(e){return e>=90?"danger":e>=75?"warn":""}const ge={success:"var(--wpshelf-success)",warn:"var(--wpshelf-warn)",danger:"var(--wpshelf-danger)"},ue={success:"var(--wpshelf-success-dark)",warn:"var(--wpshelf-warn-dark)",danger:"var(--wpshelf-danger)"};function _e({value:e,max:s,label:t,tone:a,scale:l="usage"}){const n=s>0?Math.min(e/s*100,100):0,i=t||`${Math.round(n)}%`,r=a||("completion"===l?function(e){return e>=67?"success":e>=34?"warn":"danger"}(n):he(n)),o=ge[r]||"",c=ue[r]||"";return(0,_.jsxs)("div",{className:"wpshelf-progress",children:[(0,_.jsx)("div",{className:"wpshelf-progress__bar",role:"progressbar","aria-valuenow":Math.round(n),"aria-valuemin":0,"aria-valuemax":100,"aria-valuetext":i,children:(0,_.jsx)("div",{className:"wpshelf-progress__fill",style:{width:`${n}%`,...o?{background:o}:{}}})}),(0,_.jsx)("span",{className:"wpshelf-progress__label","aria-hidden":"true",style:c?{color:c}:void 0,children:i})]})}function pe({steps:e,current:s}){return(0,_.jsx)("ol",{className:"wpshelf-stepper","aria-label":(0,l.__)("Setup progress","gloty"),children:e.map((t,a)=>{const l=a===s;let n="wpshelf-stepper__step";return a<s&&(n+=" wpshelf-stepper__step--done"),l&&(n+=" wpshelf-stepper__step--active"),(0,_.jsxs)("li",{className:n,"aria-current":l?"step":void 0,children:[a<e.length-1&&(0,_.jsx)("span",{className:"wpshelf-stepper__connector","aria-hidden":"true"}),(0,_.jsx)("span",{className:"wpshelf-stepper__label",children:t.label})]},t.key)})})}function me({items:e}){return(0,_.jsx)("div",{className:"wpshelf-milestones",role:"list",children:e.map(e=>{const s=e.done?(0,l.__)("Complete","gloty"):(0,l.__)("Pending","gloty");return(0,_.jsxs)("div",{className:"wpshelf-milestone "+(e.done?"wpshelf-milestone--done":"wpshelf-milestone--todo"),role:"listitem","aria-label":`${e.title}: ${s}`,children:[(0,_.jsx)("div",{className:"wpshelf-milestone__title",children:e.title}),(0,_.jsx)("div",{className:"wpshelf-milestone__state",children:s})]},e.key)})})}function ye({oldText:e,newText:s}){const t=(e||"").split(/(\s+)/),a=(s||"").split(/(\s+)/),l=t.length,n=a.length,i=Array.from({length:l+1},()=>new Array(n+1).fill(0));for(let e=1;e<=l;e++)for(let s=1;s<=n;s++)i[e][s]=t[e-1]===a[s-1]?i[e-1][s-1]+1:Math.max(i[e-1][s],i[e][s-1]);const r=[];let o=l,c=n;for(;o>0||c>0;)o>0&&c>0&&t[o-1]===a[c-1]?(r.unshift({type:"same",text:t[o-1]}),o--,c--):c>0&&(0===o||i[o][c-1]>=i[o-1][c])?(r.unshift({type:"add",text:a[c-1]}),c--):(r.unshift({type:"del",text:t[o-1]}),o--);return(0,_.jsx)("div",{className:"wpshelf-diff__content",children:r.map((e,s)=>"del"===e.type?(0,_.jsx)("del",{className:"wpshelf-diff__del",children:e.text},s):"add"===e.type?(0,_.jsx)("ins",{className:"wpshelf-diff__ins",children:e.text},s):(0,_.jsx)("span",{children:e.text},s))})}async function fe(){try{const e=await y()({path:"/gloty/v1/license/plans"});return Array.isArray(e?.plans)?e.plans:[]}catch{return[]}}function we(e,s){const t=e?.plan_slug||"",a=e?.characters_limit??0;return(s||[]).filter(e=>e.slug!==t).filter(e=>!e.renews||(e.quota?.limit??0)>a).sort((e,s)=>e.price-s.price)}function xe(e){const s=`$${(e.price/100).toLocaleString(void 0,{maximumFractionDigits:2})}`;return e.renews?"year"===e.interval?(0,l.sprintf)(/* translators: %s: price, e.g. $290 */ /* translators: %s: price, e.g. $290 */ 12 12 (0,l.__)("%s / yr","gloty"),s):(0,l.sprintf)(/* translators: %s: price, e.g. $29 */ /* translators: %s: price, e.g. $29 */ 13 13 (0,l.__)("%s / mo","gloty"),s):(0,l.sprintf)(/* translators: %s: price, e.g. $149 */ /* translators: %s: price, e.g. $149 */ 14 (0,l.__)("%s once","gloty"),s)}function xe(e){const s=(e.quota?.limit??0).toLocaleString();return e.renews?(0,l.sprintf)(/* translators: %s: character allowance, e.g. 500,000 */ /* translators: %s: character allowance, e.g. 500,000 */14 (0,l.__)("%s once","gloty"),s)}function ve(e){const s=(e.quota?.limit??0).toLocaleString();return e.renews?(0,l.sprintf)(/* translators: %s: character allowance, e.g. 500,000 */ /* translators: %s: character allowance, e.g. 500,000 */ 15 15 (0,l.__)("%s characters / mo","gloty"),s):(0,l.sprintf)(/* translators: %s: character allowance, e.g. 3,000,000 */ /* translators: %s: character allowance, e.g. 3,000,000 */ 16 (0,l.__)("%s characters, once","gloty"),s)}function ve(e){const s=String(e||"");return/not available for purchase|not configured|stripe/i.test(s)?{status:"warning",message:(0,l.__)("Plan upgrades aren’t available on this server — billing isn’t configured. Translations keep working on your current plan.","gloty")}:{status:"error",message:s||(0,l.__)("Could not create checkout session.","gloty")}}function je(e){let s=null;try{s=window.open(e,"_blank")}catch{s=null}return s?null:{status:"warning",message:(0,l.__)("Your browser blocked the checkout tab. Allow pop-ups for this site and press Upgrade again.","gloty")}}function be({used:e,limit:s}){const t=s>0?Math.min(100,Math.round(e/s*100)):0,a=de(t),n=(0,l.sprintf)(/* translators: 1: characters used, 2: character limit, 3: percentage used. */ /* translators: 1: characters used, 2: character limit, 3: percentage used. */17 (0,l.__)("%1$s / %2$s characters (%3$d%%)","gloty"),e.toLocaleString(),s.toLocaleString(),t);return(0, u.jsxs)("div",{className:"wpshelf-usage-bar",children:[(0,u.jsx)("div",{className:"wpshelf-usage-bar__track",role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":t,"aria-label":n,children:(0,u.jsx)("div",{className:"wpshelf-usage-bar__fill"+(a?` wpshelf-usage-bar__fill--${a}`:""),style:{width:`${t}%`}})}),(0,u.jsx)("span",{className:"wpshelf-usage-bar__label",children:n})]})}function Ne({slug:e}){return(0,u.jsx)("span",{className:"wpshelf-plan-badge",children:e||"free"})}function Ce({boot:e}){const[s,t]=(0,n.useState)(""),[a,i]=(0,n.useState)(e?.connection?.accountEmail||""),[r,o]=(0,n.useState)(e?.connection?.accountName||""),[c,d]=(0,n.useState)("getStarted"),[h,g]=(0,n.useState)(e?.license?.status||null),[_,p]=(0,n.useState)(e?.license?.hasKey||!1),[f,w]=(0,n.useState)(e?.license?.keyMasked||""),[x,v]=(0,n.useState)(!1),[j,b]=(0,n.useState)(!1),[N,C]=(0,n.useState)(null),[S,k]=(0,n.useState)(!1),[T,B]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=!0;return ye().then(s=>{e&&B(s)}),()=>{e=!1}},[]);const E=(0,n.useCallback)(async(e=!1)=>{b(!0);try{const s=e?"/gloty/v1/license/status?force=1":"/gloty/v1/license/status",t=await m()({path:s});p(t?.has_key||!1),g(t?.status||null),t?.key_masked&&w(t.key_masked),window.dispatchEvent(new CustomEvent("gloty-license-checked",{detail:t?.status||null}))}catch{}finally{b(!1)}},[]);(0,n.useEffect)(()=>{const e=()=>{E(!0)};return window.addEventListener("gloty-license-refresh",e),()=>window.removeEventListener("gloty-license-refresh",e)},[E]),(0,n.useEffect)(()=>{_&&!h&&E()},[_,h,E]);const L=e=>{const s=String(e||""),t=/no stripe customer|not configured|not found|stripe/i.test(s);C(t?{status:"warning",message:(0,l.__)("No billing portal is available for this license — there’s no Stripe subscription to manage. This is normal for free or manually-granted plans.","gloty")}:{status:"error",message:s||(0,l.__)("Could not open the billing portal.","gloty")})},M=fe(h,T);return(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsxs)("h3",{className:"wpshelf-settings-card__title",children:[(0,l.__)("License","gloty"),h&&(0,u.jsx)(Ne,{slug:h.plan_slug})]})}),(0,u.jsxs)(y.CardBody,{children:[N&&(0,u.jsx)(y.Notice,{status:N.status,isDismissible:!0,onDismiss:()=>C(null),className:"wpshelf-mb",children:N.message}),!_&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Get started with Gloty translation credits, or enter an existing license key.","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-license-tabs",style:{display:"flex",gap:12,marginBottom:16},children:[(0,u.jsx)(y.Button,{variant:"getStarted"===c?"primary":"secondary",isSmall:!0,onClick:()=>d("getStarted"),children:(0,l.__)("Get Started","gloty")}),(0,u.jsx)(y.Button,{variant:"existingKey"===c?"primary":"secondary",isSmall:!0,onClick:()=>d("existingKey"),children:(0,l.__)("I have a license key","gloty")})]}),"getStarted"===c&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextControl,{label:(0,l.__)("Email","gloty"),value:a,onChange:i,type:"email",__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextControl,{label:(0,l.__)("Name","gloty"),value:r,onChange:o,__nextHasNoMarginBottom:!0})}),(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{if(a.trim()&&r.trim()){v(!0),C(null);try{const e=await m()({path:"/gloty/v1/license/provision",method:"POST",data:{email:a.trim(),name:r.trim()}});e?.ok?(p(!0),C({status:"success",message:(0,l.__)("License provisioned and activated.","gloty")}),await E(!0)):C({status:"error",message:e?.message||(0,l.__)("Provisioning failed.","gloty")})}catch(e){C({status:"error",message:e?.message||(0,l.__)("Provisioning failed.","gloty")})}finally{v(!1)}}},isBusy:x,disabled:x||!a.trim()||!r.trim(),children:(0,l.__)("Get Free License","gloty")})]}),"existingKey"===c&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextControl,{label:(0,l.__)("License Key","gloty"),value:s,onChange:t,placeholder:"GLOTY-XXXX-XXXX-XXXX-XXXX",__nextHasNoMarginBottom:!0})}),(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{if(s.trim()){v(!0),C(null);try{const e=await m()({path:"/gloty/v1/license/activate",method:"POST",data:{license_key:s.trim()}});e?.ok?(p(!0),t(""),C({status:"success",message:(0,l.__)("License activated.","gloty")}),await E()):C({status:"error",message:e?.message||(0,l.__)("Activation failed.","gloty")})}catch(e){C({status:"error",message:e?.message||(0,l.__)("Activation failed.","gloty")})}finally{v(!1)}}},isBusy:x,disabled:x||!s.trim(),children:(0,l.__)("Activate","gloty")})]})]}),_&&h&&(0,u.jsxs)("div",{className:"wpshelf-license-details",children:[f&&(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("License key","gloty")}),(0,u.jsx)("code",{className:"wpshelf-license-key-masked",children:f})]}),(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Plan","gloty")}),(0,u.jsx)("span",{children:h.plan_name||"—"})]}),(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Status","gloty")}),(0,u.jsx)("span",{children:h.status||"—"})]}),(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Sites","gloty")}),(0,u.jsxs)("span",{children:[h.activations_used," / ",h.site_limit]})]}),(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Usage","gloty")}),(0,u.jsx)(be,{used:h.characters_used,limit:h.characters_limit})]}),h.characters_limit>0&&(0,u.jsx)("p",{className:"wpshelf-license-usage-note wpshelf-muted",children:h.characters_used/h.characters_limit>=.8?(0,l.__)("You’re approaching your monthly limit. Translation pauses at 100% until the limit resets or you upgrade — existing translations keep serving.","gloty"):(0,l.__)("Translation pauses when you reach your monthly limit, then resumes after it resets or you upgrade. Already-stored translations always keep serving.","gloty")}),h.period_end&&(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Resets","gloty")}),(0,u.jsx)("span",{children:new Date(h.period_end).toLocaleDateString()})]}),M.length>0&&(0,u.jsxs)("div",{className:"wpshelf-license-plans",children:[(0,u.jsx)("h4",{className:"wpshelf-license-plans__title",children:(0,l.__)("Upgrade","gloty")}),(0,u.jsx)("ul",{className:"wpshelf-license-plans__list",children:M.map(e=>(0,u.jsxs)("li",{className:"wpshelf-license-plans__item",children:[(0,u.jsxs)("div",{children:[(0,u.jsx)("strong",{children:e.name})," ",(0,u.jsx)("span",{className:"wpshelf-muted",children:we(e)}),(0,u.jsxs)("div",{className:"wpshelf-muted wpshelf-license-plans__meta",children:[xe(e)," · ",1===e.siteLimit?(0,l.__)("1 site","gloty"):(0,l.sprintf)(/* translators: %d: number of sites */ /* translators: %d: number of sites */18 (0,l.__)("Up to %d sites","gloty"),e.siteLimit)]})]}),(0, u.jsx)(y.Button,{variant:"primary",onClick:()=>(async e=>{v(!0),C(null);try{const s=await m()({path:"/gloty/v1/license/checkout",method:"POST",data:{plan_slug:e}});C(s?.url?je(s.url):ve(s?.message))}catch(e){C(ve(e?.message))}finally{v(!1)}})(e.slug),isBusy:x,disabled:x,children:e.renews?(0,l.__)("Upgrade","gloty"):(0,l.__)("Buy","gloty")})]},e.slug))})]}),(0,u.jsxs)("div",{className:"wpshelf-license-actions",children:[h.has_billing&&(0,u.jsx)(y.Button,{variant:"secondary",onClick:async()=>{v(!0),C(null);try{const e=await m()({path:"/gloty/v1/license/portal"});e?.url?window.open(e.url,"_blank","noopener,noreferrer"):L(e?.message)}catch(e){L(e?.message)}finally{v(!1)}},isBusy:x,disabled:x,children:(0,l.__)("Manage Subscription","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>E(!0),disabled:x||j,isBusy:j,"aria-live":"polite",children:j?(0,l.__)("Checking…","gloty"):(0,l.__)("Refresh status","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",isDestructive:!0,onClick:()=>k(!0),disabled:x,children:(0,l.__)("Deactivate","gloty")})]}),(0,u.jsx)("p",{className:"wpshelf-license-deactivate-note wpshelf-muted",children:(0,l.__)("Deactivating frees this license for another site. Your translations stay in place — nothing is deleted.","gloty")})]}),S&&(0,u.jsx)(ie,{title:(0,l.__)("Deactivate license on this site?","gloty"),message:(0,l.__)("This frees the license seat for use on another site. Your stored translations stay in place and keep serving, but new translations stop until you reactivate. Nothing is deleted.","gloty"),confirmLabel:(0,l.__)("Deactivate","gloty"),busy:x,onConfirm:()=>{k(!1),(async()=>{v(!0),C(null);try{await m()({path:"/gloty/v1/license/deactivate",method:"POST"}),p(!1),g(null),C({status:"info",message:(0,l.__)("License deactivated.","gloty")})}catch(e){C({status:"error",message:e?.message||(0,l.__)("Deactivation failed.","gloty")})}finally{v(!1)}})()},onCancel:()=>k(!1)}),_&&!h&&(0,u.jsxs)("p",{className:"wpshelf-muted",children:[f&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("code",{className:"wpshelf-license-key-masked",children:f})," — "]}),(0,l.__)("License key is configured but the license server could not be reached.","gloty"),(0,u.jsx)(y.Button,{variant:"link",onClick:()=>E(!0),disabled:j,isBusy:j,style:{marginLeft:8},"aria-live":"polite",children:j?(0,l.__)("Retrying…","gloty"):(0,l.__)("Retry","gloty")})]})]})]})}function Se({boot:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(!1),r=(0,n.useRef)(e?.license?.status||null);return(0,n.useEffect)(()=>{if("undefined"==typeof window)return;const e=new URL(window.location.href),s=e.searchParams.get("checkout");if(!s)return;if(e.searchParams.delete("checkout"),window.history.replaceState({},"",e.toString()),"cancel"===s)return void t({status:"info",message:(0,l.__)("Checkout closed — nothing was charged. Pick a plan below whenever you’re ready.","gloty")});if("success"!==s)return;i(!0),t({status:"info",message:(0,l.__)("Payment received. Waiting for Stripe to confirm it — your plan and allowance update here as soon as it does.","gloty")});let a=0;const n=()=>window.dispatchEvent(new CustomEvent("gloty-license-refresh"));n();const r=window.setInterval(()=>{if(a+=1,a>=12)return window.clearInterval(r),i(!1),void t({status:"warning",message:(0,l.__)("Payment received, but Stripe has not confirmed it here yet. Nothing is lost — use Refresh status in a few minutes, and contact support if your new plan still is not shown.","gloty")});n()},5e3);return()=>window.clearInterval(r)},[]),(0,n.useEffect)(()=>{if(!a)return;const e=e=>{var s,a;s=r.current,(a=e.detail)&&(s?a.has_billing&&!s.has_billing||a.plan_slug!==s.plan_slug||(a.characters_limit??0)>(s.characters_limit??0):Boolean(a.has_billing))&&(i(!1),t({status:"success",message:(0,l.__)("Checkout complete — your plan and allowance are up to date.","gloty")}))};return window.addEventListener("gloty-license-checked",e),()=>window.removeEventListener("gloty-license-checked",e)},[a]),(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-billing-screen",role:"region","aria-label":(0,l.__)("Billing","gloty"),children:[(0,u.jsxs)("p",{className:"wpshelf-screen__lead",children:[(0,l.__)("Manage your Gloty license, view plan usage, and update your subscription.","gloty")," ",(0,u.jsx)(y.ExternalLink,{href:"https://wp-shelf.com/gloty#pricing",children:(0,l.__)("Compare plans and pricing","gloty")})]}),s&&(0,u.jsx)(y.Notice,{status:s.status,isDismissible:!0,onDismiss:()=>t(null),className:"wpshelf-mb",children:s.message}),(0,u.jsx)(Ce,{boot:e})]})}const ke=(0,n.createContext)(null),Te={success:"✓",error:"!",info:"i"};let Be=0;function Ee({children:e}){const[s,t]=(0,n.useState)([]),a=(0,n.useCallback)((e,s="success",a=4e3)=>{const l=++Be;t(t=>[...t,{id:l,message:e,status:s}]),a>0&&window.setTimeout(()=>{t(e=>e.filter(e=>e.id!==l))},a)},[]),l=(0,n.useCallback)(e=>{t(s=>s.filter(s=>s.id!==e))},[]),i={success:e=>a(e,"success"),error:e=>a(e,"error",6e3),info:e=>a(e,"info"),add:a,dismiss:l};return(0,u.jsxs)(ke.Provider,{value:i,children:[e,(0,u.jsx)(Me,{toasts:s,onDismiss:l})]})}function Le(){return(0,n.useContext)(ke)}function Me({toasts:e,onDismiss:s}){return 0===e.length?null:(0,u.jsx)("div",{className:"wpshelf-toast-container","aria-live":"polite",children:e.map(e=>(0,u.jsxs)("div",{className:`wpshelf-toast wpshelf-toast--${e.status}`,role:"status",children:[(0,u.jsx)("span",{className:"wpshelf-toast__icon","aria-hidden":"true",children:Te[e.status]??Te.info}),(0,u.jsx)("span",{className:"wpshelf-toast__message",children:e.message}),(0,u.jsx)("button",{className:"wpshelf-toast__close",onClick:()=>s(e.id),"aria-label":(0,l.__)("Dismiss","gloty"),children:"×"})]},e.id))})}const Ae=[{label:"Surface",tokens:["--wpshelf-bg","--wpshelf-surface","--wpshelf-surface-alt"]},{label:"Ink",tokens:["--wpshelf-ink","--wpshelf-ink-soft","--wpshelf-muted"]},{label:"Line",tokens:["--wpshelf-line","--wpshelf-line-soft"]},{label:"Fill (primary action)",tokens:["--wpshelf-fill","--wpshelf-fill-hover","--wpshelf-fill-ink"]},{label:"Accent",tokens:["--wpshelf-accent","--wpshelf-accent-dark","--wpshelf-accent-50","--wpshelf-accent-100"]},{label:"Success",tokens:["--wpshelf-success","--wpshelf-success-dark","--wpshelf-success-50"]},{label:"Warning",tokens:["--wpshelf-warn","--wpshelf-warn-dark","--wpshelf-warn-50"]},{label:"Danger",tokens:["--wpshelf-danger","--wpshelf-danger-50"]}],De=["--wpshelf-text-2xs","--wpshelf-text-xs","--wpshelf-text-sm","--wpshelf-text-base","--wpshelf-text-md","--wpshelf-text-lg","--wpshelf-text-xl","--wpshelf-text-2xl","--wpshelf-text-stat-md","--wpshelf-text-stat-lg"],Re=["--wpshelf-space-1","--wpshelf-space-2","--wpshelf-space-3","--wpshelf-space-4","--wpshelf-space-5","--wpshelf-space-6","--wpshelf-space-7","--wpshelf-space-8","--wpshelf-space-10","--wpshelf-space-14","--wpshelf-space-16"],Oe=["--wpshelf-radius-xs","--wpshelf-radius-sm","--wpshelf-radius","--wpshelf-radius-lg","--wpshelf-radius-pill"],Pe=["--wpshelf-shadow","--wpshelf-shadow-hover","--wpshelf-shadow-overlay","--wpshelf-shadow-brand","--wpshelf-shadow-mark"],$e=["not_translated","pending","processing","synced","stale","failed","manually_edited"],Ie=["queued","processing","completed","cancelled","paused"],He=[{tone:"loading",label:(0,l.__)("Checking…","gloty")},{tone:"ok",label:(0,l.__)("Connected","gloty")},{tone:"warning",label:(0,l.__)("Degraded","gloty")},{tone:"error",label:(0,l.__)("Disconnected","gloty")}],Ge=[{key:"welcome",label:(0,l.__)("Welcome","gloty")},{key:"connection",label:(0,l.__)("Connection","gloty")},{key:"languages",label:(0,l.__)("Languages","gloty")},{key:"scan",label:(0,l.__)("Content scan","gloty")},{key:"done",label:(0,l.__)("Ready","gloty")}];function ze(e){const[s,t]=(0,n.useState)("");return(0,n.useEffect)(()=>{if("undefined"==typeof window)return;const s=window.getComputedStyle(document.documentElement).getPropertyValue(e).trim();t(s)},[e]),s}function Fe({name:e}){const s=ze(e);return(0,u.jsxs)("div",{className:"wpshelf-ds-swatch",children:[(0,u.jsx)("div",{className:"wpshelf-ds-swatch__chip",style:{background:`var(${e})`}}),(0,u.jsx)("code",{className:"wpshelf-ds-swatch__name",children:e}),(0,u.jsx)("span",{className:"wpshelf-ds-swatch__value",children:s||"—"})]})}function Ve({name:e}){const s=ze(e);return(0,u.jsxs)("div",{className:"wpshelf-ds-type-row",children:[(0,u.jsx)("span",{style:{fontSize:`var(${e})`,lineHeight:1.1},children:(0,l.__)("The quick brown fox","gloty")}),(0,u.jsxs)("span",{className:"wpshelf-ds-type-row__meta",children:[(0,u.jsx)("code",{children:e})," · ",s||"—"]})]})}function Ue({name:e}){const s=ze(e);return(0,u.jsxs)("div",{className:"wpshelf-ds-space-row",children:[(0,u.jsx)("span",{className:"wpshelf-ds-space-row__bar",style:{width:`var(${e})`}}),(0,u.jsx)("code",{children:e}),(0,u.jsx)("span",{className:"wpshelf-ds-swatch__value",children:s||"—"})]})}function qe(){const e=Le(),[s,t]=(0,n.useState)(!1),[a,i]=(0,n.useState)(!1);return(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-ds",role:"region","aria-label":(0,l.__)("Design system preview","gloty"),children:[(0,u.jsx)(ee,{title:(0,l.__)("Design system","gloty"),subtitle:(0,l.__)("Live catalog of every token and shared primitive. Source of truth: docs/design-system/. This screen is developer-facing and hidden from customers.","gloty")}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Color tokens","gloty")}),Ae.map(e=>(0,u.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,u.jsx)("div",{className:"wpshelf-ds-group__label",children:e.label}),(0,u.jsx)("div",{className:"wpshelf-ds-swatch-grid",children:e.tokens.map(e=>(0,u.jsx)(Fe,{name:e},e))})]},e.label)),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Type scale","gloty")}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsx)(y.CardBody,{children:De.map(e=>(0,u.jsx)(Ve,{name:e},e))})}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Spacing scale","gloty")}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsx)(y.CardBody,{children:Re.map(e=>(0,u.jsx)(Ue,{name:e},e))})}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Radius & elevation","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,u.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Radius","gloty")}),(0,u.jsx)("div",{className:"wpshelf-ds-cluster",children:Oe.map(e=>(0,u.jsxs)("div",{className:"wpshelf-ds-radius-box",children:[(0,u.jsx)("div",{className:"wpshelf-ds-radius-box__shape",style:{borderRadius:`var(${e})`}}),(0,u.jsx)("code",{children:e})]},e))})]}),(0,u.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,u.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Shadow","gloty")}),(0,u.jsx)("div",{className:"wpshelf-ds-cluster",children:Pe.map(e=>(0,u.jsxs)("div",{className:"wpshelf-ds-shadow-box",children:[(0,u.jsx)("div",{className:"wpshelf-ds-shadow-box__shape",style:{boxShadow:`var(${e})`}}),(0,u.jsx)("code",{children:e})]},e))})]}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Status vocabulary","gloty")}),(0,u.jsxs)(y.Card,{className:"wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Translation statuses","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-ds-cluster wpshelf-mb",children:$e.map(e=>(0,u.jsx)(K,{status:e},e))}),(0,u.jsx)(Q,{statuses:$e})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Job / scan statuses","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)("div",{className:"wpshelf-ds-cluster",children:Ie.map(e=>(0,u.jsx)(K,{status:e},e))})})]}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Stat cards","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--translated",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Translated","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:"128"}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("of 240 source strings","gloty")})]})}),(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--pending",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Pending","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:"12"}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("awaiting dispatch","gloty")})]})}),(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--stale",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Stale","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:"4"}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("source content changed","gloty")})]})})]}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Progress bar","gloty")}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted wpshelf-mb",children:(0,l.__)('scale="usage" — a full bar is bad (quota, rate limit).',"gloty")}),(0,u.jsx)(ue,{value:3,max:240,label:"3 of 240"}),(0,u.jsx)(ue,{value:180,max:240,label:"180 of 240 (warn ≥75%)"}),(0,u.jsx)(ue,{value:232,max:240,label:"232 of 240 (danger ≥90%)"}),(0,u.jsx)(ue,{value:240,max:240,tone:"success",label:"Complete"})]})}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted wpshelf-mb",children:(0,l.__)('scale="completion" — a full bar is good (translation coverage). The inverse of the scale above, which is why the meaning is declared at the call site rather than inferred from the number.',"gloty")}),(0,u.jsx)(ue,{value:18,max:240,scale:"completion",label:"8% (danger <34%)"}),(0,u.jsx)(ue,{value:120,max:240,scale:"completion",label:"50% (warn ≥34%)"}),(0,u.jsx)(ue,{value:228,max:240,scale:"completion",label:"95% (success ≥67%)"})]})}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Feedback states","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-ds-states",children:[(0,u.jsxs)(y.Card,{children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Loading","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)(oe,{text:(0,l.__)("Loading translations…","gloty")})})]}),(0,u.jsxs)(y.Card,{children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Empty","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)(ne,{icon:"🌐",title:(0,l.__)("No target languages","gloty"),hint:(0,l.__)("Enable at least one language to start translating your site.","gloty")})})]}),(0,u.jsxs)(y.Card,{children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Error","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,children:(0,l.__)("Could not connect to the translator service. Check that your API key is valid in Settings → Connection.","gloty")})})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-mt wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Table skeleton","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)(ce,{rows:3,headers:[(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Updated","gloty")]})})]}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Navigation","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,u.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Health pill","gloty")}),(0,u.jsx)("div",{className:"wpshelf-ds-cluster",children:He.map(e=>(0,u.jsxs)("span",{className:`wpshelf-health-pill wpshelf-health-pill--${e.tone}`,children:[(0,u.jsx)("span",{className:"wpshelf-health-pill__dot","aria-hidden":"true"}),(0,u.jsx)("span",{className:"wpshelf-health-pill__label",children:e.label})]},e.tone))})]}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)(_e,{steps:Ge,current:2}),(0,u.jsx)(pe,{items:[{key:"connection",title:(0,l.__)("Site connected to Gloty","gloty"),done:!0},{key:"languages",title:(0,l.__)("Target languages enabled","gloty"),done:!0},{key:"scan",title:(0,l.__)("Initial content scan started","gloty"),done:!1}]})]})}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Chips & buttons","gloty")}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsxs)("div",{className:"wpshelf-ds-cluster wpshelf-mb",children:[(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success",children:"success"}),(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--warn",children:"warn"}),(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--error",children:"error"}),(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--info",children:"info"}),(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--muted",children:"muted"}),(0,u.jsx)("span",{className:"wpshelf-chip",children:"neutral"})]}),(0,u.jsxs)("div",{className:"wpshelf-ds-cluster",children:[(0,u.jsx)(y.Button,{variant:"primary",children:(0,l.__)("Primary","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",children:(0,l.__)("Secondary","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",children:(0,l.__)("Tertiary","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",isDestructive:!0,children:(0,l.__)("Destructive","gloty")}),(0,u.jsx)(y.Button,{variant:"link",children:(0,l.__)("Link","gloty")})]})]})}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Overlays","gloty")}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsx)(y.CardBody,{children:(0,u.jsxs)("div",{className:"wpshelf-ds-cluster",children:[(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>e.success((0,l.__)("Settings saved.","gloty")),children:(0,l.__)("Success toast","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>e.error((0,l.__)("Could not save changes.","gloty")),children:(0,l.__)("Error toast","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>e.info((0,l.__)("Scan started in background.","gloty")),children:(0,l.__)("Info toast","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>t(!0),children:(0,l.__)("Open confirm modal","gloty")})]})})}),s&&(0,u.jsx)(ie,{title:(0,l.__)("Delete translations","gloty"),message:(0,l.__)("Delete 3 cached translations? They may be regenerated later.","gloty"),confirmLabel:(0,l.__)("Delete","gloty"),busy:a,onConfirm:()=>{i(!0),window.setTimeout(()=>{i(!1),t(!1),e.success((0,l.__)("Deleted 3 translations.","gloty"))},900)},onCancel:()=>t(!1)})]})}function We({boot:e,onNavigate:s}){const t=e?.firstTranslation||{},a=e?.siteUrl||window?.location?.origin||"",i=e?.routing?.url_structure||"subdirectory",[r,o]=(0,n.useState)(!!t.dismissedAt),[c,d]=(0,n.useState)(!1);if(!(0,n.useMemo)(()=>!r&&!!t.at&&function(e){if(!e)return 1/0;const s=String(e).replace(" ","T")+"Z",t=Date.parse(s);return Number.isNaN(t)?1/0:(Date.now()-t)/36e5}(t.at)<48,[r,t.at]))return null;const h=t.lang||"",g=h?h.toUpperCase():"",_=(()=>{if(!h)return a||"/";if("parameter"===i){const e=a.includes("?")?"&":"?";return`${a}${e}lang=${encodeURIComponent(h)}`}return`${a.replace(/\/$/,"")}/${encodeURIComponent(h)}/`})();return(0,u.jsx)(y.Card,{className:"wpshelf-first-translation wpshelf-mb",role:"region","aria-label":(0,l.__)("First translation welcome","gloty"),children:(0,u.jsx)(y.CardBody,{children:(0,u.jsxs)("div",{className:"wpshelf-first-translation__body",children:[(0,u.jsxs)("div",{className:"wpshelf-first-translation__text",children:[(0,u.jsx)("h2",{className:"wpshelf-first-translation__title",children:g?(0,l.sprintf)(/* translators: %s: language code, e.g. FR */ /* translators: %s: language code, e.g. FR */19 (0,l.__)("🎉 Your first %s translation is live","gloty"),g):(0,l.__)("🎉 Your first translation is live","gloty")}),(0, u.jsx)("p",{className:"wpshelf-first-translation__hint wpshelf-muted",children:(0,l.__)("Open the front end in the target language to see it in place. Share the preview link with your team so they can review.","gloty")})]}),(0,u.jsxs)("div",{className:"wpshelf-first-translation__actions",children:[(0,u.jsx)(y.Button,{variant:"primary",href:_,target:"_blank",rel:"noreferrer",children:g?(0,l.sprintf)(/* translators: %s: language code */ /* translators: %s: language code */20 (0,l.__)("View site in %s","gloty"),g):(0,l.__)("View translated site","gloty")}),(0, u.jsx)(y.Button,{variant:"secondary",onClick:async()=>{try{await navigator.clipboard.writeText(_),d(!0),window.setTimeout(()=>d(!1),2e3)}catch{window.prompt((0,l.__)("Copy this link:","gloty"),_)}},children:c?(0,l.__)("Copied!","gloty"):(0,l.__)("Share with your team","gloty")}),s&&(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>s("translations"),children:(0,l.__)("Review translations","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",onClick:async()=>{o(!0);try{await m()({path:"/gloty/v1/first-translation/dismiss",method:"POST"})}catch{}},"aria-label":(0,l.__)("Dismiss welcome","gloty"),children:(0,l.__)("Dismiss","gloty")})]})]})})})}function Xe({position:e,total:s,step:t,onNavigate:a}){let n="wpshelf-gs__step--todo";return t.done?n="wpshelf-gs__step--done":t.active&&(n="wpshelf-gs__step--active"),(0,u.jsxs)("li",{className:`wpshelf-gs__step ${n}`,children:[(0,u.jsx)("span",{className:"wpshelf-gs__marker","aria-hidden":"true",children:t.done?"✓":e}),(0,u.jsxs)("div",{className:"wpshelf-gs__body",children:[(0,u.jsxs)("div",{className:"wpshelf-gs__title",children:[t.title,t.done&&(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success wpshelf-gs__badge",children:(0,l.__)("Done","gloty")})]}),(0,u.jsx)("p",{className:"wpshelf-gs__desc wpshelf-muted",children:t.description})]}),!t.done&&t.action&&a&&(0,u.jsx)("div",{className:"wpshelf-gs__action",children:(0,u.jsx)(y.Button,{variant:t.active?"primary":"secondary",onClick:()=>a(t.action.tab),children:t.action.label})}),e<s&&(0,u.jsx)("span",{className:"wpshelf-gs__connector","aria-hidden":"true"})]})}function Ye({hasLanguages:e,hasSource:s,hasTranslated:t,pendingCount:a=0,onNavigate:n}){if(t)return null;const i=[{key:"languages",done:e,title:(0,l.__)("Choose your languages","gloty"),description:(0,l.__)("Pick the languages you want your site translated into.","gloty"),action:{tab:"languages",label:e?(0,l.__)("Manage languages","gloty"):(0,l.__)("Add a language","gloty")}},{key:"scan",done:s,title:(0,l.__)("Scan your content","gloty"),description:(0,l.__)("Gloty collects every translatable piece of text on your site.","gloty"),action:{tab:"sync",label:s?(0,l.__)("Open Sync","gloty"):(0,l.__)("Run a scan","gloty")}},{key:"translate",done:t,title:(0,l.__)("Translate","gloty"),description:a>0?(0,l.sprintf)(/* translators: %s: number of pending strings */ /* translators: %s: number of pending strings */21 (0,l.__)("%s strings are ready — send them to your AI provider to translate.","gloty"),Number(a).toLocaleString()):(0,l.__)("Send collected strings to your AI provider to translate.","gloty"),action:{tab:"sync",label:(0,l.__)("Translate now","gloty")}}],r=i.findIndex(e=>!e.done);return i.forEach((e,s)=>{e.active=s===r}),(0, u.jsxs)(y.Card,{className:"wpshelf-getting-started wpshelf-mb",role:"region","aria-label":(0,l.__)("Getting started","gloty"),children:[(0,u.jsxs)(y.CardHeader,{children:[(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Get started with Gloty","gloty")}),(0,u.jsxs)("span",{className:"wpshelf-gs__flow wpshelf-muted","aria-hidden":"true",children:[(0,l.__)("Scan","gloty")," ","→"," ",(0,l.__)("Translate","gloty")," ","→"," ",(0,l.__)("Serve","gloty")]})]}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)("ol",{className:"wpshelf-gs__steps",children:i.map((e,s)=>(0,u.jsx)(Xe,{position:s+1,total:i.length,step:e,onNavigate:n},e.key))})})]})}const Ze=[{code:"en",name:"English",native_name:"English"},{code:"es",name:"Spanish",native_name:"Español"},{code:"fr",name:"French",native_name:"Français"},{code:"de",name:"German",native_name:"Deutsch"},{code:"it",name:"Italian",native_name:"Italiano"},{code:"pt",name:"Portuguese",native_name:"Português"},{code:"nl",name:"Dutch",native_name:"Nederlands"},{code:"pl",name:"Polish",native_name:"Polski"},{code:"ru",name:"Russian",native_name:"Русский"},{code:"uk",name:"Ukrainian",native_name:"Українська"},{code:"cs",name:"Czech",native_name:"Čeština"},{code:"sk",name:"Slovak",native_name:"Slovenčina"},{code:"sl",name:"Slovenian",native_name:"Slovenščina"},{code:"hu",name:"Hungarian",native_name:"Magyar"},{code:"ro",name:"Romanian",native_name:"Română"},{code:"bg",name:"Bulgarian",native_name:"Български"},{code:"hr",name:"Croatian",native_name:"Hrvatski"},{code:"sr",name:"Serbian",native_name:"Српски"},{code:"bs",name:"Bosnian",native_name:"Bosanski"},{code:"mk",name:"Macedonian",native_name:"Македонски"},{code:"sq",name:"Albanian",native_name:"Shqip"},{code:"el",name:"Greek",native_name:"Ελληνικά"},{code:"tr",name:"Turkish",native_name:"Türkçe"},{code:"sv",name:"Swedish",native_name:"Svenska"},{code:"no",name:"Norwegian",native_name:"Norsk"},{code:"nb",name:"Norwegian Bokmål",native_name:"Norsk bokmål"},{code:"nn",name:"Norwegian Nynorsk",native_name:"Norsk nynorsk"},{code:"da",name:"Danish",native_name:"Dansk"},{code:"fi",name:"Finnish",native_name:"Suomi"},{code:"is",name:"Icelandic",native_name:"Íslenska"},{code:"et",name:"Estonian",native_name:"Eesti"},{code:"lv",name:"Latvian",native_name:"Latviešu"},{code:"lt",name:"Lithuanian",native_name:"Lietuvių"},{code:"ga",name:"Irish",native_name:"Gaeilge"},{code:"cy",name:"Welsh",native_name:"Cymraeg"},{code:"eu",name:"Basque",native_name:"Euskara"},{code:"ca",name:"Catalan",native_name:"Català"},{code:"gl",name:"Galician",native_name:"Galego"},{code:"mt",name:"Maltese",native_name:"Malti"},{code:"ja",name:"Japanese",native_name:"日本語"},{code:"ko",name:"Korean",native_name:"한국어"},{code:"zh",name:"Chinese",native_name:"中文"},{code:"vi",name:"Vietnamese",native_name:"Tiếng Việt"},{code:"th",name:"Thai",native_name:"ไทย"},{code:"lo",name:"Lao",native_name:"ລາວ"},{code:"km",name:"Khmer",native_name:"ខ្មែរ"},{code:"my",name:"Burmese",native_name:"မြန်မာ"},{code:"id",name:"Indonesian",native_name:"Bahasa Indonesia"},{code:"ms",name:"Malay",native_name:"Bahasa Melayu"},{code:"tl",name:"Tagalog",native_name:"Tagalog"},{code:"fil",name:"Filipino",native_name:"Filipino"},{code:"hi",name:"Hindi",native_name:"हिन्दी"},{code:"bn",name:"Bengali",native_name:"বাংলা"},{code:"ta",name:"Tamil",native_name:"தமிழ்"},{code:"te",name:"Telugu",native_name:"తెలుగు"},{code:"ml",name:"Malayalam",native_name:"മലയാളം"},{code:"kn",name:"Kannada",native_name:"ಕನ್ನಡ"},{code:"mr",name:"Marathi",native_name:"मराठी"},{code:"gu",name:"Gujarati",native_name:"ગુજરાતી"},{code:"pa",name:"Punjabi",native_name:"ਪੰਜਾਬੀ"},{code:"or",name:"Odia",native_name:"ଓଡ଼ିଆ"},{code:"as",name:"Assamese",native_name:"অসমীয়া"},{code:"ne",name:"Nepali",native_name:"नेपाली"},{code:"si",name:"Sinhala",native_name:"සිංහල"},{code:"ur",name:"Urdu",native_name:"اردو",is_rtl:!0},{code:"ar",name:"Arabic",native_name:"العربية",is_rtl:!0},{code:"he",name:"Hebrew",native_name:"עברית",is_rtl:!0},{code:"fa",name:"Persian",native_name:"فارسی",is_rtl:!0},{code:"ps",name:"Pashto",native_name:"پښتو",is_rtl:!0},{code:"ku",name:"Kurdish",native_name:"Kurdî"},{code:"az",name:"Azerbaijani",native_name:"Azərbaycanca"},{code:"hy",name:"Armenian",native_name:"Հայերեն"},{code:"ka",name:"Georgian",native_name:"ქართული"},{code:"kk",name:"Kazakh",native_name:"Қазақша"},{code:"uz",name:"Uzbek",native_name:"Oʻzbekcha"},{code:"ky",name:"Kyrgyz",native_name:"Кыргызча"},{code:"tg",name:"Tajik",native_name:"Тоҷикӣ"},{code:"tk",name:"Turkmen",native_name:"Türkmençe"},{code:"mn",name:"Mongolian",native_name:"Монгол"},{code:"sw",name:"Swahili",native_name:"Kiswahili"},{code:"am",name:"Amharic",native_name:"አማርኛ"},{code:"yo",name:"Yoruba",native_name:"Yorùbá"},{code:"ig",name:"Igbo",native_name:"Igbo"},{code:"ha",name:"Hausa",native_name:"Hausa"},{code:"zu",name:"Zulu",native_name:"isiZulu"},{code:"xh",name:"Xhosa",native_name:"isiXhosa"},{code:"af",name:"Afrikaans",native_name:"Afrikaans"},{code:"so",name:"Somali",native_name:"Soomaali"},{code:"eo",name:"Esperanto",native_name:"Esperanto"},{code:"en-GB",name:"English (United Kingdom)",native_name:"English (UK)"},{code:"en-US",name:"English (United States)",native_name:"English (US)"},{code:"en-AU",name:"English (Australia)",native_name:"English (AU)"},{code:"en-CA",name:"English (Canada)",native_name:"English (CA)"},{code:"en-IE",name:"English (Ireland)",native_name:"English (IE)"},{code:"en-IN",name:"English (India)",native_name:"English (IN)"},{code:"en-NZ",name:"English (New Zealand)",native_name:"English (NZ)"},{code:"en-ZA",name:"English (South Africa)",native_name:"English (ZA)"},{code:"es-ES",name:"Spanish (Spain)",native_name:"Español (España)"},{code:"es-MX",name:"Spanish (Mexico)",native_name:"Español (México)"},{code:"es-AR",name:"Spanish (Argentina)",native_name:"Español (Argentina)"},{code:"es-CL",name:"Spanish (Chile)",native_name:"Español (Chile)"},{code:"es-CO",name:"Spanish (Colombia)",native_name:"Español (Colombia)"},{code:"es-419",name:"Spanish (Latin America)",native_name:"Español (Latinoamérica)"},{code:"pt-BR",name:"Portuguese (Brazil)",native_name:"Português (Brasil)"},{code:"pt-PT",name:"Portuguese (Portugal)",native_name:"Português (Portugal)"},{code:"fr-FR",name:"French (France)",native_name:"Français (France)"},{code:"fr-CA",name:"French (Canada)",native_name:"Français (Canada)"},{code:"fr-BE",name:"French (Belgium)",native_name:"Français (Belgique)"},{code:"fr-CH",name:"French (Switzerland)",native_name:"Français (Suisse)"},{code:"de-DE",name:"German (Germany)",native_name:"Deutsch (Deutschland)"},{code:"de-AT",name:"German (Austria)",native_name:"Deutsch (Österreich)"},{code:"de-CH",name:"German (Switzerland)",native_name:"Deutsch (Schweiz)"},{code:"it-IT",name:"Italian (Italy)",native_name:"Italiano (Italia)"},{code:"it-CH",name:"Italian (Switzerland)",native_name:"Italiano (Svizzera)"},{code:"nl-NL",name:"Dutch (Netherlands)",native_name:"Nederlands (Nederland)"},{code:"nl-BE",name:"Dutch (Belgium)",native_name:"Nederlands (België)"},{code:"zh-CN",name:"Chinese (Simplified)",native_name:"中文 (简体)"},{code:"zh-TW",name:"Chinese (Traditional)",native_name:"中文 (繁體)"},{code:"zh-HK",name:"Chinese (Hong Kong)",native_name:"中文 (香港)"},{code:"zh-SG",name:"Chinese (Singapore)",native_name:"中文 (新加坡)"},{code:"ar-SA",name:"Arabic (Saudi Arabia)",native_name:"العربية (السعودية)",is_rtl:!0},{code:"ar-EG",name:"Arabic (Egypt)",native_name:"العربية (مصر)",is_rtl:!0},{code:"ar-AE",name:"Arabic (UAE)",native_name:"العربية (الإمارات)",is_rtl:!0},{code:"sr-Latn",name:"Serbian (Latin)",native_name:"Srpski"}],Je=new Set(["en","es","fr","de","it","pt","nl","pl","ru","uk","cs","sk","sl","hu","ro","bg","hr","sr","el","tr","sv","no","da","fi","et","lv","lt","ja","ko","zh","vi","th","id","hi","bn","ar","he","sw"]),Ke=Ze.filter(e=>function(e){const s=String(e||"").toLowerCase();return!s.includes("-")&&Je.has(s)}(e.code));function Qe(e){if(!e)return null;const s=String(e).toLowerCase();return Ze.find(e=>e.code.toLowerCase()===s)||null}const es={pt:{kind:"ambiguous",variants:["pt-BR","pt-PT"]},zh:{kind:"ambiguous",variants:["zh-CN","zh-TW"]}},ss={id:null,source_term:"",rule_type:"never_translate",case_sensitive:!1,notes:"",translations:{}};function ts({boot:e}){const s=Le(),t=String(e?.language?.default||"en").toLowerCase(),a=(0,n.useMemo)(()=>Array.isArray(e?.language?.active)?e.language.active:[],[e]),i=(0,n.useMemo)(()=>a.map(e=>String(e).toLowerCase()).filter(e=>e&&e!==t),[a,t]),[r,o]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[h,g]=(0,n.useState)(null),[p,f]=(0,n.useState)(!1),[x,v]=(0,n.useState)(null),[j,b]=(0,n.useState)(!1),[N,C]=(0,n.useState)(null),S=(0,n.useCallback)(async()=>{d(null);try{const e=await m()({path:"/gloty/v1/glossary",parse:!0});o(Array.isArray(e?.terms)?e.terms:[])}catch(e){o([]),d({status:"error",message:e?.message||(0,l.__)("Could not load the glossary.","gloty")})}},[]);(0,n.useEffect)(()=>{S()},[S]);const k=(0,n.useCallback)(e=>{const s=Qe(e);return s?`${s.name} (${e.toUpperCase()})`:e.toUpperCase()},[]),B=(e,s)=>g(t=>({...t,[e]:s})),E=e=>{if("translate_as"!==e.rule_type)return(0,l.__)("Kept exactly as written","gloty");const s=i.map(s=>{const t=e.translations?.[s];return t?`${s.toUpperCase()}: ${t}`:null}).filter(Boolean);return s.length?s.join(" · "):(0,l.__)("No per-language values set yet","gloty")},L=null===r;return(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-glossary-screen",children:[(0,u.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Keep your brand and product names exactly right in every language. Add a term to stop it being translated, or set exactly how it should appear per language.","gloty")}),c&&(0,u.jsx)(y.Notice,{status:c.status,isDismissible:!0,onDismiss:()=>d(null),className:"wpshelf-mb",children:c.message}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card",children:[(0,u.jsxs)(y.CardHeader,{size:"small",children:[(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Glossary terms","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:()=>g({...ss,translations:{}}),disabled:L,children:(0,l.__)("Add term","gloty")})]}),(0,u.jsxs)(y.CardBody,{children:[L&&(0,u.jsx)(ce,{rows:4,headers:[(0,l.__)("Term","gloty"),(0,l.__)("Behavior","gloty"),(0,l.__)("Rendering","gloty"),(0,l.__)("Active","gloty"),""]}),!L&&0===r.length&&(0,u.jsx)(ne,{icon:(0,u.jsx)(w,{icon:T}),title:(0,l.__)("No glossary terms yet","gloty"),hint:(0,l.__)("Add a brand or product name to protect it from translation across your whole site.","gloty")}),!L&&r.length>0&&(0,u.jsxs)(_,{className:"wp-list-table widefat striped wpshelf-table",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Term","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Behavior","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Rendering","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Active","gloty")}),(0,u.jsx)("th",{scope:"col"})]})}),(0,u.jsx)("tbody",{children:r.map(e=>(0,u.jsxs)("tr",{children:[(0,u.jsxs)("td",{children:[(0,u.jsx)("strong",{children:e.source_term}),!!e.case_sensitive&&(0,u.jsxs)("span",{className:"wpshelf-muted",children:[" ","·"," ",(0,l.__)("case-sensitive","gloty")]}),e.notes&&(0,u.jsx)("div",{className:"wpshelf-muted",children:e.notes})]}),(0,u.jsx)("td",{children:"translate_as"===e.rule_type?(0,l.__)("Translate as…","gloty"):(0,l.__)("Never translate","gloty")}),(0,u.jsx)("td",{className:"wpshelf-muted",children:E(e)}),(0,u.jsx)("td",{children:(0,u.jsx)(y.ToggleControl,{__nextHasNoMarginBottom:!0,checked:!!e.is_active,disabled:N===e.id,onChange:t=>(async(e,t)=>{if(N!==e.id){C(e.id),o(s=>s.map(s=>s.id===e.id?{...s,is_active:t?1:0}:s));try{await m()({path:`/gloty/v1/glossary/${e.id}`,method:"PUT",data:{is_active:t?1:0}})}catch(e){s.error(e?.message||(0,l.__)("Could not update the term.","gloty")),await S()}finally{C(null)}}})(e,t),label:""})}),(0,u.jsxs)("td",{children:[(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>(e=>g({id:e.id,source_term:e.source_term||"",rule_type:"translate_as"===e.rule_type?"translate_as":"never_translate",case_sensitive:!!e.case_sensitive,notes:e.notes||"",translations:e.translations&&"object"==typeof e.translations?{...e.translations}:{}}))(e),children:(0,l.__)("Edit","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",isDestructive:!0,onClick:()=>v(e),children:(0,l.__)("Delete","gloty")})]})]},e.id))})]})]})]}),h&&(0,u.jsxs)(y.Modal,{title:h.id?(0,l.__)("Edit glossary term","gloty"):(0,l.__)("Add glossary term","gloty"),onRequestClose:()=>g(null),className:"wpshelf-glossary-modal",children:[(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Term","gloty"),value:h.source_term,onChange:e=>B("source_term",e),placeholder:(0,l.__)("e.g. Chanel N°5","gloty"),help:(0,l.__)("The exact brand or product name as it appears on your site.","gloty")})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.SelectControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Behavior","gloty"),value:h.rule_type,options:[{label:(0,l.__)("Never translate — keep it verbatim","gloty"),value:"never_translate"},{label:(0,l.__)("Translate as… — set it per language","gloty"),value:"translate_as"}],onChange:e=>B("rule_type",e)})}),"translate_as"===h.rule_type&&(0,u.jsx)("div",{className:"wpshelf-settings-field",children:0===i.length?(0,u.jsx)(y.Notice,{status:"info",isDismissible:!1,children:(0,l.__)("Add a target language first to set per-language values. Until then the term is kept verbatim.","gloty")}):i.map(e=>(0,u.jsx)(y.TextControl,{__nextHasNoMarginBottom:!0,label:k(e),value:h.translations?.[e]||"",onChange:s=>((e,s)=>g(t=>({...t,translations:{...t.translations,[e]:s}})))(e,s),placeholder:(0,l.__)("Leave blank to keep verbatim","gloty")},e))}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Case-sensitive match","gloty"),help:(0,l.__)("Only match the exact capitalization above. Leave off for most brands.","gloty"),checked:h.case_sensitive,onChange:e=>B("case_sensitive",e)})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Note (optional)","gloty"),value:h.notes,onChange:e=>B("notes",e)})}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:8,marginTop:16,justifyContent:"flex-end"},children:[(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>g(null),children:(0,l.__)("Cancel","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{if(!h)return;const e=(h.source_term||"").trim();if(!e)return void s.error((0,l.__)("Enter a term first.","gloty"));const t={source_term:e,rule_type:h.rule_type,case_sensitive:h.case_sensitive?1:0,notes:h.notes||"",translations:"translate_as"===h.rule_type?h.translations:{}};f(!0);try{h.id?(await m()({path:`/gloty/v1/glossary/${h.id}`,method:"PUT",data:t}),s.success((0,l.__)("Term updated.","gloty"))):(await m()({path:"/gloty/v1/glossary",method:"POST",data:t}),s.success((0,l.__)("Term added.","gloty"))),g(null),await S()}catch(e){s.error(e?.message||(0,l.__)("Could not save the term.","gloty"))}finally{f(!1)}},isBusy:p,disabled:p,children:h.id?(0,l.__)("Save changes","gloty"):(0,l.__)("Add term","gloty")})]})]}),x&&(0,u.jsx)(ie,{title:(0,l.__)("Remove glossary term","gloty"),message:(M=x.source_term,(0,l.__)("This term will be translated normally again on future syncs.","gloty").concat(M?` (“${M}”)`:"")),confirmLabel:(0,l.__)("Remove term","gloty"),busy:j,onConfirm:async()=>{if(x){b(!0);try{await m()({path:`/gloty/v1/glossary/${x.id}`,method:"DELETE"}),s.success((0,l.__)("Term removed.","gloty")),v(null),await S()}catch(e){s.error(e?.message||(0,l.__)("Could not remove the term.","gloty"))}finally{b(!1)}}},onCancel:()=>v(null)})]});var M}function as(e){if(!e)return"";const s=(Date.now()-e)/1e3;return s<60?(0,l.__)("just now","gloty"):s<3600?Math.floor(s/60)+(0,l.__)("m ago","gloty"):s<86400?Math.floor(s/3600)+(0,l.__)("h ago","gloty"):Math.floor(s/86400)+(0,l.__)("d ago","gloty")}function ls({onNavigate:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(null),r=(0,n.useRef)(!0),o=(0,n.useCallback)(async()=>{try{const e=await m()({path:"/gloty/v1/issues",parse:!0});r.current&&(t(e?.count||{error:0,warning:0,info:0}),i(Date.now()))}catch{}},[]);(0,n.useEffect)(()=>{r.current=!0,o();const e=window.setInterval(o,6e4),s=()=>{"visible"===document.visibilityState&&o()};return document.addEventListener("visibilitychange",s),window.addEventListener("gloty-license-refresh",o),()=>{r.current=!1,window.clearInterval(e),document.removeEventListener("visibilitychange",s),window.removeEventListener("gloty-license-refresh",o)}},[o]);const[,c]=(0,n.useReducer)(e=>e+1,0);(0,n.useEffect)(()=>{const e=window.setInterval(c,3e4);return()=>window.clearInterval(e)},[]);const d=function(e){return e?(e.error||0)>0?{tone:"error",label:(0,l.__)("Disconnected","gloty")}:(e.warning||0)>0?{tone:"warning",label:(0,l.__)("Degraded","gloty")}:{tone:"ok",label:(0,l.__)("Connected","gloty")}:{tone:"loading",label:(0,l.__)("Checking…","gloty")}}(s),h=s&&"ok"!==d.tone&&"loading"!==d.tone?` (${(s.error||0)+(s.warning||0)})`:"";return(0,u.jsxs)("button",{type:"button",className:`wpshelf-health-pill wpshelf-health-pill--${d.tone}`,onClick:()=>e&&e("dashboard"),"aria-label":(0,l.__)("Connection health — click to view details","gloty"),title:(0,l.__)("Connection health. Click to jump to the Overview tab.","gloty"),children:[(0,u.jsx)("span",{className:"wpshelf-health-pill__dot","aria-hidden":"true"}),(0,u.jsxs)("span",{className:"wpshelf-health-pill__label",children:[d.label,h]}),a&&(0,u.jsx)("span",{className:"wpshelf-health-pill__time",children:as(a)})]})}const ns={error:"⚠",warning:"⚠",info:"ℹ"},is={error:(0,l.__)("Critical","gloty"),warning:(0,l.__)("Warning","gloty"),info:(0,l.__)("Info","gloty")};function rs({issue:e,onNavigate:s}){const t=e.severity||"info";return(0,u.jsxs)("li",{className:`wpshelf-issue wpshelf-issue--${t}`,children:[(0,u.jsx)("span",{className:"wpshelf-issue__icon","aria-hidden":"true",children:ns[t]}),(0,u.jsxs)("div",{className:"wpshelf-issue__body",children:[(0,u.jsxs)("div",{className:"wpshelf-issue__title",children:[(0,u.jsxs)("span",{className:"screen-reader-text",children:[is[t],":"]}),e.title]}),e.detail&&(0,u.jsx)("div",{className:"wpshelf-issue__detail wpshelf-muted",children:e.detail})]}),e.action&&s&&(0,u.jsx)(y.Button,{variant:"error"===t?"primary":"secondary",isSmall:!0,onClick:()=>s(e.action.view,e.action.filters||null),children:e.action.label})]})}function os({onNavigate:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(!0),[r,o]=(0,n.useState)(null),c=(0,n.useCallback)(async()=>{i(!0),o(null);try{const e=await m()({path:"/gloty/v1/issues",parse:!0});t(e)}catch(e){o(e?.message||(0,l.__)("Could not load issues.","gloty"))}finally{i(!1)}},[]);if((0,n.useEffect)(()=>{c()},[c]),a&&!s)return null;if(r)return null;const d=s?.count||{error:0,warning:0,info:0},h=d.error+d.warning+d.info,g=s?.issues||[];let _=(0,l.__)("Needs attention","gloty");return 0===h?_=(0,l.__)("All clear","gloty"):d.error>0?_=(0,l.sprintf)(/* translators: %d: number of critical issues */ /* translators: %d: number of critical issues */22 (0,l._n)("Needs attention · %d critical issue","Needs attention · %d critical issues",d.error,"gloty"),d.error):d.warning>0&&( _=(0,l.sprintf)(/* translators: %d: number of warnings */ /* translators: %d: number of warnings */23 (0,l._n)("Needs attention · %d warning","Needs attention · %d warnings",d.warning,"gloty"),d.warning)),(0, u.jsxs)(y.Card,{className:"wpshelf-issues-card wpshelf-mb "+(d.error>0?"wpshelf-issues-card--error":d.warning>0?"wpshelf-issues-card--warning":""),role:"region","aria-label":(0,l.__)("System health","gloty"),children:[(0,u.jsxs)(y.CardHeader,{children:[(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:_}),(0,u.jsx)(y.Button,{variant:"tertiary",size:"small",onClick:c,disabled:a,isBusy:a,"aria-live":"polite",children:a?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]}),(0,u.jsx)(y.CardBody,{children:0===h?(0,u.jsx)("p",{className:"wpshelf-muted",style:{margin:0},children:(0,l.__)("No issues detected. Translator service is reachable and your license is in good standing.","gloty")}):(0,u.jsx)("ul",{className:"wpshelf-issues",children:g.map(s=>(0,u.jsx)(rs,{issue:s,onNavigate:e},s.id))})})]})}function cs(e){return Qe(e)?.name||e}function ds({code:e}){const s=function(e,s=es){const t=String(e||"").toLowerCase();if(!t)return null;const a=Object.keys(s).find(e=>e.toLowerCase()===t);return a?{code:a,kind:s[a].kind,variants:s[a].variants||[]}:null}(e);if(!s)return null;const t=function(e){const s=cs(e.code);if("ambiguous"===e.kind){const t=e.variants.map(e=>`${cs(e)} (${e})`);return(0,l.sprintf)(/* translators: 1: language name, 2: code, 3: one regional variant, 4: another */ /* translators: 1: language name, 2: code, 3: one regional variant, 4: another */16 (0,l.__)("%s characters, once","gloty"),s)}function je(e){const s=String(e||"");return/not available for purchase|not configured|stripe/i.test(s)?{status:"warning",message:(0,l.__)("Plan upgrades aren’t available on this server — billing isn’t configured. Translations keep working on your current plan.","gloty")}:{status:"error",message:s||(0,l.__)("Could not create checkout session.","gloty")}}function be(e){let s=null;try{s=window.open(e,"_blank")}catch{s=null}return s?null:{status:"warning",message:(0,l.__)("Your browser blocked the checkout tab. Allow pop-ups for this site and press Upgrade again.","gloty")}}function Ne({used:e,limit:s}){const t=s>0?Math.min(100,Math.round(e/s*100)):0,a=he(t),n=(0,l.sprintf)(/* translators: 1: characters used, 2: character limit, 3: percentage used. */ /* translators: 1: characters used, 2: character limit, 3: percentage used. */ 17 (0,l.__)("%1$s / %2$s characters (%3$d%%)","gloty"),e.toLocaleString(),s.toLocaleString(),t);return(0,_.jsxs)("div",{className:"wpshelf-usage-bar",children:[(0,_.jsx)("div",{className:"wpshelf-usage-bar__track",role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":t,"aria-label":n,children:(0,_.jsx)("div",{className:"wpshelf-usage-bar__fill"+(a?` wpshelf-usage-bar__fill--${a}`:""),style:{width:`${t}%`}})}),(0,_.jsx)("span",{className:"wpshelf-usage-bar__label",children:n})]})}function Ce({slug:e}){return(0,_.jsx)("span",{className:"wpshelf-plan-badge",children:e||"free"})}function Se({boot:e}){const[s,t]=(0,n.useState)(""),[a,i]=(0,n.useState)(e?.connection?.accountEmail||""),[r,o]=(0,n.useState)(e?.connection?.accountName||""),[c,d]=(0,n.useState)("getStarted"),[h,g]=(0,n.useState)(e?.license?.status||null),[u,p]=(0,n.useState)(e?.license?.hasKey||!1),[m,w]=(0,n.useState)(e?.license?.keyMasked||""),[x,v]=(0,n.useState)(e?.license?.keyRefused||!1),[j,b]=(0,n.useState)(!1),[N,C]=(0,n.useState)(!1),[S,k]=(0,n.useState)(null),[T,B]=(0,n.useState)(!1),[E,L]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=!0;return fe().then(s=>{e&&L(s)}),()=>{e=!1}},[]);const M=(0,n.useCallback)(async(e=!1)=>{C(!0);try{const s=e?"/gloty/v1/license/status?force=1":"/gloty/v1/license/status",t=await y()({path:s});p(t?.has_key||!1),g(t?.status||null),v(t?.key_refused||!1),t?.key_masked&&w(t.key_masked),window.dispatchEvent(new CustomEvent("gloty-license-checked",{detail:t?.status||null}))}catch{}finally{C(!1)}},[]);(0,n.useEffect)(()=>{const e=()=>{M(!0)};return window.addEventListener("gloty-license-refresh",e),()=>window.removeEventListener("gloty-license-refresh",e)},[M]),(0,n.useEffect)(()=>{u&&!h&&M()},[u,h,M]);const A=async()=>{if(s.trim()){b(!0),k(null);try{const e=await y()({path:"/gloty/v1/license/activate",method:"POST",data:{license_key:s.trim()}});e?.ok?(p(!0),v(!1),t(""),k({status:"success",message:(0,l.__)("License activated.","gloty")}),await M()):k({status:"error",message:e?.message||(0,l.__)("Activation failed.","gloty")})}catch(e){k({status:"error",message:e?.message||(0,l.__)("Activation failed.","gloty")})}finally{b(!1)}}},D=e=>{const s=String(e||""),t=/no stripe customer|not configured|not found|stripe/i.test(s);k(t?{status:"warning",message:(0,l.__)("No billing portal is available for this license — there’s no Stripe subscription to manage. This is normal for free or manually-granted plans.","gloty")}:{status:"error",message:s||(0,l.__)("Could not open the billing portal.","gloty")})},R=we(h,E);return(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsxs)("h3",{className:"wpshelf-settings-card__title",children:[(0,l.__)("License","gloty"),h&&(0,_.jsx)(Ce,{slug:h.plan_slug})]})}),(0,_.jsxs)(f.CardBody,{children:[S&&(0,_.jsx)(f.Notice,{status:S.status,isDismissible:!0,onDismiss:()=>k(null),className:"wpshelf-mb",children:S.message}),!u&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Get started with Gloty translation credits, or enter an existing license key.","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-license-tabs",style:{display:"flex",gap:12,marginBottom:16},children:[(0,_.jsx)(f.Button,{variant:"getStarted"===c?"primary":"secondary",isSmall:!0,onClick:()=>d("getStarted"),children:(0,l.__)("Get Started","gloty")}),(0,_.jsx)(f.Button,{variant:"existingKey"===c?"primary":"secondary",isSmall:!0,onClick:()=>d("existingKey"),children:(0,l.__)("I have a license key","gloty")})]}),"getStarted"===c&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{label:(0,l.__)("Email","gloty"),value:a,onChange:i,type:"email",__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{label:(0,l.__)("Name","gloty"),value:r,onChange:o,__nextHasNoMarginBottom:!0})}),(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{if(a.trim()&&r.trim()){b(!0),k(null);try{const e=await y()({path:"/gloty/v1/license/provision",method:"POST",data:{email:a.trim(),name:r.trim()}});e?.ok?(p(!0),k({status:"success",message:(0,l.__)("License provisioned and activated.","gloty")}),await M(!0)):k({status:"error",message:e?.message||(0,l.__)("Provisioning failed.","gloty")})}catch(e){k({status:"error",message:e?.message||(0,l.__)("Provisioning failed.","gloty")})}finally{b(!1)}}},isBusy:j,disabled:j||!a.trim()||!r.trim(),children:(0,l.__)("Get Free License","gloty")})]}),"existingKey"===c&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{label:(0,l.__)("License Key","gloty"),value:s,onChange:t,placeholder:"GLOTY-XXXX-XXXX-XXXX-XXXX",__nextHasNoMarginBottom:!0})}),(0,_.jsx)(f.Button,{variant:"primary",onClick:A,isBusy:j,disabled:j||!s.trim(),children:(0,l.__)("Activate","gloty")})]})]}),u&&h&&(0,_.jsxs)("div",{className:"wpshelf-license-details",children:[m&&(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("License key","gloty")}),(0,_.jsx)("code",{className:"wpshelf-license-key-masked",children:m})]}),(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Plan","gloty")}),(0,_.jsx)("span",{children:h.plan_name||"—"})]}),(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Status","gloty")}),(0,_.jsx)("span",{children:h.status||"—"})]}),(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Sites","gloty")}),(0,_.jsxs)("span",{children:[h.activations_used," / ",h.site_limit]})]}),(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Usage","gloty")}),(0,_.jsx)(Ne,{used:h.characters_used,limit:h.characters_limit})]}),h.characters_limit>0&&(0,_.jsx)("p",{className:"wpshelf-license-usage-note wpshelf-muted",children:h.characters_used/h.characters_limit>=.8?(0,l.__)("You’re approaching your monthly limit. Translation pauses at 100% until the limit resets or you upgrade — existing translations keep serving.","gloty"):(0,l.__)("Translation pauses when you reach your monthly limit, then resumes after it resets or you upgrade. Already-stored translations always keep serving.","gloty")}),h.period_end&&(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Resets","gloty")}),(0,_.jsx)("span",{children:new Date(h.period_end).toLocaleDateString()})]}),R.length>0&&(0,_.jsxs)("div",{className:"wpshelf-license-plans",children:[(0,_.jsx)("h4",{className:"wpshelf-license-plans__title",children:(0,l.__)("Upgrade","gloty")}),(0,_.jsx)("ul",{className:"wpshelf-license-plans__list",children:R.map(e=>(0,_.jsxs)("li",{className:"wpshelf-license-plans__item",children:[(0,_.jsxs)("div",{children:[(0,_.jsx)("strong",{children:e.name})," ",(0,_.jsx)("span",{className:"wpshelf-muted",children:xe(e)}),(0,_.jsxs)("div",{className:"wpshelf-muted wpshelf-license-plans__meta",children:[ve(e)," · ",1===e.siteLimit?(0,l.__)("1 site","gloty"):(0,l.sprintf)(/* translators: %d: number of sites */ /* translators: %d: number of sites */ 18 (0,l.__)("Up to %d sites","gloty"),e.siteLimit)]})]}),(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>(async e=>{b(!0),k(null);try{const s=await y()({path:"/gloty/v1/license/checkout",method:"POST",data:{plan_slug:e}});k(s?.url?be(s.url):je(s?.message))}catch(e){k(je(e?.message))}finally{b(!1)}})(e.slug),isBusy:j,disabled:j,children:e.renews?(0,l.__)("Upgrade","gloty"):(0,l.__)("Buy","gloty")})]},e.slug))})]}),(0,_.jsxs)("div",{className:"wpshelf-license-actions",children:[h.has_billing&&(0,_.jsx)(f.Button,{variant:"secondary",onClick:async()=>{b(!0),k(null);try{const e=await y()({path:"/gloty/v1/license/portal"});e?.url?window.open(e.url,"_blank","noopener,noreferrer"):D(e?.message)}catch(e){D(e?.message)}finally{b(!1)}},isBusy:j,disabled:j,children:(0,l.__)("Manage Subscription","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>M(!0),disabled:j||N,isBusy:N,"aria-live":"polite",children:N?(0,l.__)("Checking…","gloty"):(0,l.__)("Refresh status","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",isDestructive:!0,onClick:()=>B(!0),disabled:j,children:(0,l.__)("Deactivate","gloty")})]}),(0,_.jsx)("p",{className:"wpshelf-license-deactivate-note wpshelf-muted",children:(0,l.__)("Deactivating frees this license for another site. Your translations stay in place — nothing is deleted.","gloty")})]}),T&&(0,_.jsx)(re,{title:(0,l.__)("Deactivate license on this site?","gloty"),message:(0,l.__)("This frees the license seat for use on another site. Your stored translations stay in place and keep serving, but new translations stop until you reactivate. Nothing is deleted.","gloty"),confirmLabel:(0,l.__)("Deactivate","gloty"),busy:j,onConfirm:()=>{B(!1),(async()=>{b(!0),k(null);try{await y()({path:"/gloty/v1/license/deactivate",method:"POST"}),p(!1),g(null),v(!1),k({status:"info",message:(0,l.__)("License deactivated.","gloty")})}catch(e){k({status:"error",message:e?.message||(0,l.__)("Deactivation failed.","gloty")})}finally{b(!1)}})()},onCancel:()=>B(!1)}),u&&!h&&x&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsxs)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mb",children:[(0,_.jsx)("p",{children:(0,_.jsx)("strong",{children:(0,l.__)("This license key is no longer accepted.","gloty")})}),(0,_.jsxs)("p",{children:[(0,l.__)("Translations keep running, but usage is not recorded against your plan. If you were sent a replacement key, or can see one in your WP Shelf account, paste it here and activate it.","gloty")," ",(0,_.jsx)("a",{href:"https://wp-shelf.com/dashboard/licenses",target:"_blank",rel:"noopener noreferrer",children:(0,l.__)("Open your WP Shelf licenses","gloty")})]})]}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{label:(0,l.__)("Replacement license key","gloty"),value:s,onChange:t,placeholder:"GLOTY-XXXX-XXXX-XXXX-XXXX",__nextHasNoMarginBottom:!0})}),(0,_.jsx)(f.Button,{variant:"primary",onClick:A,isBusy:j,disabled:j||!s.trim(),children:(0,l.__)("Activate","gloty")})]}),u&&!h&&!x&&(0,_.jsxs)("p",{className:"wpshelf-muted",children:[m&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("code",{className:"wpshelf-license-key-masked",children:m})," — "]}),(0,l.__)("License key is configured but the license server could not be reached.","gloty"),(0,_.jsx)(f.Button,{variant:"link",onClick:()=>M(!0),disabled:N,isBusy:N,style:{marginLeft:8},"aria-live":"polite",children:N?(0,l.__)("Retrying…","gloty"):(0,l.__)("Retry","gloty")})]})]})]})}function ke({boot:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(!1),r=(0,n.useRef)(e?.license?.status||null);return(0,n.useEffect)(()=>{if("undefined"==typeof window)return;const e=new URL(window.location.href),s=e.searchParams.get("checkout");if(!s)return;if(e.searchParams.delete("checkout"),window.history.replaceState({},"",e.toString()),"cancel"===s)return void t({status:"info",message:(0,l.__)("Checkout closed — nothing was charged. Pick a plan below whenever you’re ready.","gloty")});if("success"!==s)return;i(!0),t({status:"info",message:(0,l.__)("Payment received. Waiting for Stripe to confirm it — your plan and allowance update here as soon as it does.","gloty")});let a=0;const n=()=>window.dispatchEvent(new CustomEvent("gloty-license-refresh"));n();const r=window.setInterval(()=>{if(a+=1,a>=12)return window.clearInterval(r),i(!1),void t({status:"warning",message:(0,l.__)("Payment received, but Stripe has not confirmed it here yet. Nothing is lost — use Refresh status in a few minutes, and contact support if your new plan still is not shown.","gloty")});n()},5e3);return()=>window.clearInterval(r)},[]),(0,n.useEffect)(()=>{if(!a)return;const e=e=>{var s,a;s=r.current,(a=e.detail)&&(s?a.has_billing&&!s.has_billing||a.plan_slug!==s.plan_slug||(a.characters_limit??0)>(s.characters_limit??0):Boolean(a.has_billing))&&(i(!1),t({status:"success",message:(0,l.__)("Checkout complete — your plan and allowance are up to date.","gloty")}))};return window.addEventListener("gloty-license-checked",e),()=>window.removeEventListener("gloty-license-checked",e)},[a]),(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-billing-screen",role:"region","aria-label":(0,l.__)("Billing","gloty"),children:[(0,_.jsxs)("p",{className:"wpshelf-screen__lead",children:[(0,l.__)("Manage your Gloty license, view plan usage, and update your subscription.","gloty")," ",(0,_.jsx)(f.ExternalLink,{href:"https://wp-shelf.com/gloty#pricing",children:(0,l.__)("Compare plans and pricing","gloty")})]}),s&&(0,_.jsx)(f.Notice,{status:s.status,isDismissible:!0,onDismiss:()=>t(null),className:"wpshelf-mb",children:s.message}),(0,_.jsx)(Se,{boot:e})]})}const Te=(0,n.createContext)(null),Be={success:"✓",error:"!",info:"i"};let Ee=0;function Le({children:e}){const[s,t]=(0,n.useState)([]),a=(0,n.useCallback)((e,s="success",a=4e3)=>{const l=++Ee;t(t=>[...t,{id:l,message:e,status:s}]),a>0&&window.setTimeout(()=>{t(e=>e.filter(e=>e.id!==l))},a)},[]),l=(0,n.useCallback)(e=>{t(s=>s.filter(s=>s.id!==e))},[]),i={success:e=>a(e,"success"),error:e=>a(e,"error",6e3),info:e=>a(e,"info"),add:a,dismiss:l};return(0,_.jsxs)(Te.Provider,{value:i,children:[e,(0,_.jsx)(Ae,{toasts:s,onDismiss:l})]})}function Me(){return(0,n.useContext)(Te)}function Ae({toasts:e,onDismiss:s}){return 0===e.length?null:(0,_.jsx)("div",{className:"wpshelf-toast-container","aria-live":"polite",children:e.map(e=>(0,_.jsxs)("div",{className:`wpshelf-toast wpshelf-toast--${e.status}`,role:"status",children:[(0,_.jsx)("span",{className:"wpshelf-toast__icon","aria-hidden":"true",children:Be[e.status]??Be.info}),(0,_.jsx)("span",{className:"wpshelf-toast__message",children:e.message}),(0,_.jsx)("button",{className:"wpshelf-toast__close",onClick:()=>s(e.id),"aria-label":(0,l.__)("Dismiss","gloty"),children:"×"})]},e.id))})}const De=[{label:"Surface",tokens:["--wpshelf-bg","--wpshelf-surface","--wpshelf-surface-alt"]},{label:"Ink",tokens:["--wpshelf-ink","--wpshelf-ink-soft","--wpshelf-muted"]},{label:"Line",tokens:["--wpshelf-line","--wpshelf-line-soft"]},{label:"Fill (primary action)",tokens:["--wpshelf-fill","--wpshelf-fill-hover","--wpshelf-fill-ink"]},{label:"Accent",tokens:["--wpshelf-accent","--wpshelf-accent-dark","--wpshelf-accent-50","--wpshelf-accent-100"]},{label:"Success",tokens:["--wpshelf-success","--wpshelf-success-dark","--wpshelf-success-50"]},{label:"Warning",tokens:["--wpshelf-warn","--wpshelf-warn-dark","--wpshelf-warn-50"]},{label:"Danger",tokens:["--wpshelf-danger","--wpshelf-danger-50"]}],Re=["--wpshelf-text-2xs","--wpshelf-text-xs","--wpshelf-text-sm","--wpshelf-text-base","--wpshelf-text-md","--wpshelf-text-lg","--wpshelf-text-xl","--wpshelf-text-2xl","--wpshelf-text-stat-md","--wpshelf-text-stat-lg"],Oe=["--wpshelf-space-1","--wpshelf-space-2","--wpshelf-space-3","--wpshelf-space-4","--wpshelf-space-5","--wpshelf-space-6","--wpshelf-space-7","--wpshelf-space-8","--wpshelf-space-10","--wpshelf-space-14","--wpshelf-space-16"],Pe=["--wpshelf-radius-xs","--wpshelf-radius-sm","--wpshelf-radius","--wpshelf-radius-lg","--wpshelf-radius-pill"],$e=["--wpshelf-shadow","--wpshelf-shadow-hover","--wpshelf-shadow-overlay","--wpshelf-shadow-brand","--wpshelf-shadow-mark"],Ie=["not_translated","pending","processing","synced","stale","failed","manually_edited"],He=["queued","processing","completed","cancelled","paused"],Ge=[{tone:"loading",label:(0,l.__)("Checking…","gloty")},{tone:"ok",label:(0,l.__)("Connected","gloty")},{tone:"warning",label:(0,l.__)("Degraded","gloty")},{tone:"error",label:(0,l.__)("Disconnected","gloty")}],ze=[{key:"welcome",label:(0,l.__)("Welcome","gloty")},{key:"connection",label:(0,l.__)("Connection","gloty")},{key:"languages",label:(0,l.__)("Languages","gloty")},{key:"scan",label:(0,l.__)("Content scan","gloty")},{key:"done",label:(0,l.__)("Ready","gloty")}];function Fe(e){const[s,t]=(0,n.useState)("");return(0,n.useEffect)(()=>{if("undefined"==typeof window)return;const s=window.getComputedStyle(document.documentElement).getPropertyValue(e).trim();t(s)},[e]),s}function Ve({name:e}){const s=Fe(e);return(0,_.jsxs)("div",{className:"wpshelf-ds-swatch",children:[(0,_.jsx)("div",{className:"wpshelf-ds-swatch__chip",style:{background:`var(${e})`}}),(0,_.jsx)("code",{className:"wpshelf-ds-swatch__name",children:e}),(0,_.jsx)("span",{className:"wpshelf-ds-swatch__value",children:s||"—"})]})}function Ue({name:e}){const s=Fe(e);return(0,_.jsxs)("div",{className:"wpshelf-ds-type-row",children:[(0,_.jsx)("span",{style:{fontSize:`var(${e})`,lineHeight:1.1},children:(0,l.__)("The quick brown fox","gloty")}),(0,_.jsxs)("span",{className:"wpshelf-ds-type-row__meta",children:[(0,_.jsx)("code",{children:e})," · ",s||"—"]})]})}function qe({name:e}){const s=Fe(e);return(0,_.jsxs)("div",{className:"wpshelf-ds-space-row",children:[(0,_.jsx)("span",{className:"wpshelf-ds-space-row__bar",style:{width:`var(${e})`}}),(0,_.jsx)("code",{children:e}),(0,_.jsx)("span",{className:"wpshelf-ds-swatch__value",children:s||"—"})]})}function We(){const e=Me(),[s,t]=(0,n.useState)(!1),[a,i]=(0,n.useState)(!1);return(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-ds",role:"region","aria-label":(0,l.__)("Design system preview","gloty"),children:[(0,_.jsx)(se,{title:(0,l.__)("Design system","gloty"),subtitle:(0,l.__)("Live catalog of every token and shared primitive. Source of truth: docs/design-system/. This screen is developer-facing and hidden from customers.","gloty")}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Color tokens","gloty")}),De.map(e=>(0,_.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,_.jsx)("div",{className:"wpshelf-ds-group__label",children:e.label}),(0,_.jsx)("div",{className:"wpshelf-ds-swatch-grid",children:e.tokens.map(e=>(0,_.jsx)(Ve,{name:e},e))})]},e.label)),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Type scale","gloty")}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsx)(f.CardBody,{children:Re.map(e=>(0,_.jsx)(Ue,{name:e},e))})}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Spacing scale","gloty")}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsx)(f.CardBody,{children:Oe.map(e=>(0,_.jsx)(qe,{name:e},e))})}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Radius & elevation","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,_.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Radius","gloty")}),(0,_.jsx)("div",{className:"wpshelf-ds-cluster",children:Pe.map(e=>(0,_.jsxs)("div",{className:"wpshelf-ds-radius-box",children:[(0,_.jsx)("div",{className:"wpshelf-ds-radius-box__shape",style:{borderRadius:`var(${e})`}}),(0,_.jsx)("code",{children:e})]},e))})]}),(0,_.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,_.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Shadow","gloty")}),(0,_.jsx)("div",{className:"wpshelf-ds-cluster",children:$e.map(e=>(0,_.jsxs)("div",{className:"wpshelf-ds-shadow-box",children:[(0,_.jsx)("div",{className:"wpshelf-ds-shadow-box__shape",style:{boxShadow:`var(${e})`}}),(0,_.jsx)("code",{children:e})]},e))})]}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Status vocabulary","gloty")}),(0,_.jsxs)(f.Card,{className:"wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Translation statuses","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-ds-cluster wpshelf-mb",children:Ie.map(e=>(0,_.jsx)(Q,{status:e},e))}),(0,_.jsx)(ee,{statuses:Ie})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Job / scan statuses","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)("div",{className:"wpshelf-ds-cluster",children:He.map(e=>(0,_.jsx)(Q,{status:e},e))})})]}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Stat cards","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--translated",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Translated","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:"128"}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("of 240 source strings","gloty")})]})}),(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--pending",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Pending","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:"12"}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("awaiting dispatch","gloty")})]})}),(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--stale",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Stale","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:"4"}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("source content changed","gloty")})]})})]}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Progress bar","gloty")}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted wpshelf-mb",children:(0,l.__)('scale="usage" — a full bar is bad (quota, rate limit).',"gloty")}),(0,_.jsx)(_e,{value:3,max:240,label:"3 of 240"}),(0,_.jsx)(_e,{value:180,max:240,label:"180 of 240 (warn ≥75%)"}),(0,_.jsx)(_e,{value:232,max:240,label:"232 of 240 (danger ≥90%)"}),(0,_.jsx)(_e,{value:240,max:240,tone:"success",label:"Complete"})]})}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted wpshelf-mb",children:(0,l.__)('scale="completion" — a full bar is good (translation coverage). The inverse of the scale above, which is why the meaning is declared at the call site rather than inferred from the number.',"gloty")}),(0,_.jsx)(_e,{value:18,max:240,scale:"completion",label:"8% (danger <34%)"}),(0,_.jsx)(_e,{value:120,max:240,scale:"completion",label:"50% (warn ≥34%)"}),(0,_.jsx)(_e,{value:228,max:240,scale:"completion",label:"95% (success ≥67%)"})]})}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Feedback states","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-ds-states",children:[(0,_.jsxs)(f.Card,{children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Loading","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)(ce,{text:(0,l.__)("Loading translations…","gloty")})})]}),(0,_.jsxs)(f.Card,{children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Empty","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)(ie,{icon:"🌐",title:(0,l.__)("No target languages","gloty"),hint:(0,l.__)("Enable at least one language to start translating your site.","gloty")})})]}),(0,_.jsxs)(f.Card,{children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Error","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,children:(0,l.__)("Could not connect to the translator service. Check that your API key is valid in Settings → Connection.","gloty")})})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-mt wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Table skeleton","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)(de,{rows:3,headers:[(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Updated","gloty")]})})]}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Navigation","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,_.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Health pill","gloty")}),(0,_.jsx)("div",{className:"wpshelf-ds-cluster",children:Ge.map(e=>(0,_.jsxs)("span",{className:`wpshelf-health-pill wpshelf-health-pill--${e.tone}`,children:[(0,_.jsx)("span",{className:"wpshelf-health-pill__dot","aria-hidden":"true"}),(0,_.jsx)("span",{className:"wpshelf-health-pill__label",children:e.label})]},e.tone))})]}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)(pe,{steps:ze,current:2}),(0,_.jsx)(me,{items:[{key:"connection",title:(0,l.__)("Site connected to Gloty","gloty"),done:!0},{key:"languages",title:(0,l.__)("Target languages enabled","gloty"),done:!0},{key:"scan",title:(0,l.__)("Initial content scan started","gloty"),done:!1}]})]})}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Chips & buttons","gloty")}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsxs)("div",{className:"wpshelf-ds-cluster wpshelf-mb",children:[(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success",children:"success"}),(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--warn",children:"warn"}),(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--error",children:"error"}),(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--info",children:"info"}),(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--muted",children:"muted"}),(0,_.jsx)("span",{className:"wpshelf-chip",children:"neutral"})]}),(0,_.jsxs)("div",{className:"wpshelf-ds-cluster",children:[(0,_.jsx)(f.Button,{variant:"primary",children:(0,l.__)("Primary","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",children:(0,l.__)("Secondary","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",children:(0,l.__)("Tertiary","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",isDestructive:!0,children:(0,l.__)("Destructive","gloty")}),(0,_.jsx)(f.Button,{variant:"link",children:(0,l.__)("Link","gloty")})]})]})}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Overlays","gloty")}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsx)(f.CardBody,{children:(0,_.jsxs)("div",{className:"wpshelf-ds-cluster",children:[(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>e.success((0,l.__)("Settings saved.","gloty")),children:(0,l.__)("Success toast","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>e.error((0,l.__)("Could not save changes.","gloty")),children:(0,l.__)("Error toast","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>e.info((0,l.__)("Scan started in background.","gloty")),children:(0,l.__)("Info toast","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>t(!0),children:(0,l.__)("Open confirm modal","gloty")})]})})}),s&&(0,_.jsx)(re,{title:(0,l.__)("Delete translations","gloty"),message:(0,l.__)("Delete 3 cached translations? They may be regenerated later.","gloty"),confirmLabel:(0,l.__)("Delete","gloty"),busy:a,onConfirm:()=>{i(!0),window.setTimeout(()=>{i(!1),t(!1),e.success((0,l.__)("Deleted 3 translations.","gloty"))},900)},onCancel:()=>t(!1)})]})}function Xe({boot:e,onNavigate:s}){const t=e?.firstTranslation||{},a=e?.siteUrl||window?.location?.origin||"",i=e?.routing?.url_structure||"subdirectory",[r,o]=(0,n.useState)(!!t.dismissedAt),[c,d]=(0,n.useState)(!1);if(!(0,n.useMemo)(()=>!r&&!!t.at&&function(e){if(!e)return 1/0;const s=String(e).replace(" ","T")+"Z",t=Date.parse(s);return Number.isNaN(t)?1/0:(Date.now()-t)/36e5}(t.at)<48,[r,t.at]))return null;const h=t.lang||"",g=h?h.toUpperCase():"",u=(()=>{if(!h)return a||"/";if("parameter"===i){const e=a.includes("?")?"&":"?";return`${a}${e}lang=${encodeURIComponent(h)}`}return`${a.replace(/\/$/,"")}/${encodeURIComponent(h)}/`})();return(0,_.jsx)(f.Card,{className:"wpshelf-first-translation wpshelf-mb",role:"region","aria-label":(0,l.__)("First translation welcome","gloty"),children:(0,_.jsx)(f.CardBody,{children:(0,_.jsxs)("div",{className:"wpshelf-first-translation__body",children:[(0,_.jsxs)("div",{className:"wpshelf-first-translation__text",children:[(0,_.jsx)("h2",{className:"wpshelf-first-translation__title",children:g?(0,l.sprintf)(/* translators: %s: language code, e.g. FR */ /* translators: %s: language code, e.g. FR */ 19 (0,l.__)("🎉 Your first %s translation is live","gloty"),g):(0,l.__)("🎉 Your first translation is live","gloty")}),(0,_.jsx)("p",{className:"wpshelf-first-translation__hint wpshelf-muted",children:(0,l.__)("Open the front end in the target language to see it in place. Share the preview link with your team so they can review.","gloty")})]}),(0,_.jsxs)("div",{className:"wpshelf-first-translation__actions",children:[(0,_.jsx)(f.Button,{variant:"primary",href:u,target:"_blank",rel:"noreferrer",children:g?(0,l.sprintf)(/* translators: %s: language code */ /* translators: %s: language code */ 20 (0,l.__)("View site in %s","gloty"),g):(0,l.__)("View translated site","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:async()=>{try{await navigator.clipboard.writeText(u),d(!0),window.setTimeout(()=>d(!1),2e3)}catch{window.prompt((0,l.__)("Copy this link:","gloty"),u)}},children:c?(0,l.__)("Copied!","gloty"):(0,l.__)("Share with your team","gloty")}),s&&(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>s("translations"),children:(0,l.__)("Review translations","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",onClick:async()=>{o(!0);try{await y()({path:"/gloty/v1/first-translation/dismiss",method:"POST"})}catch{}},"aria-label":(0,l.__)("Dismiss welcome","gloty"),children:(0,l.__)("Dismiss","gloty")})]})]})})})}function Ye({position:e,total:s,step:t,onNavigate:a}){let n="wpshelf-gs__step--todo";return t.done?n="wpshelf-gs__step--done":t.active&&(n="wpshelf-gs__step--active"),(0,_.jsxs)("li",{className:`wpshelf-gs__step ${n}`,children:[(0,_.jsx)("span",{className:"wpshelf-gs__marker","aria-hidden":"true",children:t.done?"✓":e}),(0,_.jsxs)("div",{className:"wpshelf-gs__body",children:[(0,_.jsxs)("div",{className:"wpshelf-gs__title",children:[t.title,t.done&&(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success wpshelf-gs__badge",children:(0,l.__)("Done","gloty")})]}),(0,_.jsx)("p",{className:"wpshelf-gs__desc wpshelf-muted",children:t.description})]}),!t.done&&t.action&&a&&(0,_.jsx)("div",{className:"wpshelf-gs__action",children:(0,_.jsx)(f.Button,{variant:t.active?"primary":"secondary",onClick:()=>a(t.action.tab),children:t.action.label})}),e<s&&(0,_.jsx)("span",{className:"wpshelf-gs__connector","aria-hidden":"true"})]})}function Ze({hasLanguages:e,hasSource:s,hasTranslated:t,pendingCount:a=0,onNavigate:n}){if(t)return null;const i=[{key:"languages",done:e,title:(0,l.__)("Choose your languages","gloty"),description:(0,l.__)("Pick the languages you want your site translated into.","gloty"),action:{tab:"languages",label:e?(0,l.__)("Manage languages","gloty"):(0,l.__)("Add a language","gloty")}},{key:"scan",done:s,title:(0,l.__)("Scan your content","gloty"),description:(0,l.__)("Gloty collects every translatable piece of text on your site.","gloty"),action:{tab:"sync",label:s?(0,l.__)("Open Sync","gloty"):(0,l.__)("Run a scan","gloty")}},{key:"translate",done:t,title:(0,l.__)("Translate","gloty"),description:a>0?(0,l.sprintf)(/* translators: %s: number of pending strings */ /* translators: %s: number of pending strings */ 21 (0,l.__)("%s strings are ready — send them to your AI provider to translate.","gloty"),Number(a).toLocaleString()):(0,l.__)("Send collected strings to your AI provider to translate.","gloty"),action:{tab:"sync",label:(0,l.__)("Translate now","gloty")}}],r=i.findIndex(e=>!e.done);return i.forEach((e,s)=>{e.active=s===r}),(0,_.jsxs)(f.Card,{className:"wpshelf-getting-started wpshelf-mb",role:"region","aria-label":(0,l.__)("Getting started","gloty"),children:[(0,_.jsxs)(f.CardHeader,{children:[(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Get started with Gloty","gloty")}),(0,_.jsxs)("span",{className:"wpshelf-gs__flow wpshelf-muted","aria-hidden":"true",children:[(0,l.__)("Scan","gloty")," ","→"," ",(0,l.__)("Translate","gloty")," ","→"," ",(0,l.__)("Serve","gloty")]})]}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)("ol",{className:"wpshelf-gs__steps",children:i.map((e,s)=>(0,_.jsx)(Ye,{position:s+1,total:i.length,step:e,onNavigate:n},e.key))})})]})}const Je=[{code:"en",name:"English",native_name:"English"},{code:"es",name:"Spanish",native_name:"Español"},{code:"fr",name:"French",native_name:"Français"},{code:"de",name:"German",native_name:"Deutsch"},{code:"it",name:"Italian",native_name:"Italiano"},{code:"pt",name:"Portuguese",native_name:"Português"},{code:"nl",name:"Dutch",native_name:"Nederlands"},{code:"pl",name:"Polish",native_name:"Polski"},{code:"ru",name:"Russian",native_name:"Русский"},{code:"uk",name:"Ukrainian",native_name:"Українська"},{code:"cs",name:"Czech",native_name:"Čeština"},{code:"sk",name:"Slovak",native_name:"Slovenčina"},{code:"sl",name:"Slovenian",native_name:"Slovenščina"},{code:"hu",name:"Hungarian",native_name:"Magyar"},{code:"ro",name:"Romanian",native_name:"Română"},{code:"bg",name:"Bulgarian",native_name:"Български"},{code:"hr",name:"Croatian",native_name:"Hrvatski"},{code:"sr",name:"Serbian",native_name:"Српски"},{code:"bs",name:"Bosnian",native_name:"Bosanski"},{code:"mk",name:"Macedonian",native_name:"Македонски"},{code:"sq",name:"Albanian",native_name:"Shqip"},{code:"el",name:"Greek",native_name:"Ελληνικά"},{code:"tr",name:"Turkish",native_name:"Türkçe"},{code:"sv",name:"Swedish",native_name:"Svenska"},{code:"no",name:"Norwegian",native_name:"Norsk"},{code:"nb",name:"Norwegian Bokmål",native_name:"Norsk bokmål"},{code:"nn",name:"Norwegian Nynorsk",native_name:"Norsk nynorsk"},{code:"da",name:"Danish",native_name:"Dansk"},{code:"fi",name:"Finnish",native_name:"Suomi"},{code:"is",name:"Icelandic",native_name:"Íslenska"},{code:"et",name:"Estonian",native_name:"Eesti"},{code:"lv",name:"Latvian",native_name:"Latviešu"},{code:"lt",name:"Lithuanian",native_name:"Lietuvių"},{code:"ga",name:"Irish",native_name:"Gaeilge"},{code:"cy",name:"Welsh",native_name:"Cymraeg"},{code:"eu",name:"Basque",native_name:"Euskara"},{code:"ca",name:"Catalan",native_name:"Català"},{code:"gl",name:"Galician",native_name:"Galego"},{code:"mt",name:"Maltese",native_name:"Malti"},{code:"ja",name:"Japanese",native_name:"日本語"},{code:"ko",name:"Korean",native_name:"한국어"},{code:"zh",name:"Chinese",native_name:"中文"},{code:"vi",name:"Vietnamese",native_name:"Tiếng Việt"},{code:"th",name:"Thai",native_name:"ไทย"},{code:"lo",name:"Lao",native_name:"ລາວ"},{code:"km",name:"Khmer",native_name:"ខ្មែរ"},{code:"my",name:"Burmese",native_name:"မြန်မာ"},{code:"id",name:"Indonesian",native_name:"Bahasa Indonesia"},{code:"ms",name:"Malay",native_name:"Bahasa Melayu"},{code:"tl",name:"Tagalog",native_name:"Tagalog"},{code:"fil",name:"Filipino",native_name:"Filipino"},{code:"hi",name:"Hindi",native_name:"हिन्दी"},{code:"bn",name:"Bengali",native_name:"বাংলা"},{code:"ta",name:"Tamil",native_name:"தமிழ்"},{code:"te",name:"Telugu",native_name:"తెలుగు"},{code:"ml",name:"Malayalam",native_name:"മലയാളം"},{code:"kn",name:"Kannada",native_name:"ಕನ್ನಡ"},{code:"mr",name:"Marathi",native_name:"मराठी"},{code:"gu",name:"Gujarati",native_name:"ગુજરાતી"},{code:"pa",name:"Punjabi",native_name:"ਪੰਜਾਬੀ"},{code:"or",name:"Odia",native_name:"ଓଡ଼ିଆ"},{code:"as",name:"Assamese",native_name:"অসমীয়া"},{code:"ne",name:"Nepali",native_name:"नेपाली"},{code:"si",name:"Sinhala",native_name:"සිංහල"},{code:"ur",name:"Urdu",native_name:"اردو",is_rtl:!0},{code:"ar",name:"Arabic",native_name:"العربية",is_rtl:!0},{code:"he",name:"Hebrew",native_name:"עברית",is_rtl:!0},{code:"fa",name:"Persian",native_name:"فارسی",is_rtl:!0},{code:"ps",name:"Pashto",native_name:"پښتو",is_rtl:!0},{code:"ku",name:"Kurdish",native_name:"Kurdî"},{code:"az",name:"Azerbaijani",native_name:"Azərbaycanca"},{code:"hy",name:"Armenian",native_name:"Հայերեն"},{code:"ka",name:"Georgian",native_name:"ქართული"},{code:"kk",name:"Kazakh",native_name:"Қазақша"},{code:"uz",name:"Uzbek",native_name:"Oʻzbekcha"},{code:"ky",name:"Kyrgyz",native_name:"Кыргызча"},{code:"tg",name:"Tajik",native_name:"Тоҷикӣ"},{code:"tk",name:"Turkmen",native_name:"Türkmençe"},{code:"mn",name:"Mongolian",native_name:"Монгол"},{code:"sw",name:"Swahili",native_name:"Kiswahili"},{code:"am",name:"Amharic",native_name:"አማርኛ"},{code:"yo",name:"Yoruba",native_name:"Yorùbá"},{code:"ig",name:"Igbo",native_name:"Igbo"},{code:"ha",name:"Hausa",native_name:"Hausa"},{code:"zu",name:"Zulu",native_name:"isiZulu"},{code:"xh",name:"Xhosa",native_name:"isiXhosa"},{code:"af",name:"Afrikaans",native_name:"Afrikaans"},{code:"so",name:"Somali",native_name:"Soomaali"},{code:"eo",name:"Esperanto",native_name:"Esperanto"},{code:"en-GB",name:"English (United Kingdom)",native_name:"English (UK)"},{code:"en-US",name:"English (United States)",native_name:"English (US)"},{code:"en-AU",name:"English (Australia)",native_name:"English (AU)"},{code:"en-CA",name:"English (Canada)",native_name:"English (CA)"},{code:"en-IE",name:"English (Ireland)",native_name:"English (IE)"},{code:"en-IN",name:"English (India)",native_name:"English (IN)"},{code:"en-NZ",name:"English (New Zealand)",native_name:"English (NZ)"},{code:"en-ZA",name:"English (South Africa)",native_name:"English (ZA)"},{code:"es-ES",name:"Spanish (Spain)",native_name:"Español (España)"},{code:"es-MX",name:"Spanish (Mexico)",native_name:"Español (México)"},{code:"es-AR",name:"Spanish (Argentina)",native_name:"Español (Argentina)"},{code:"es-CL",name:"Spanish (Chile)",native_name:"Español (Chile)"},{code:"es-CO",name:"Spanish (Colombia)",native_name:"Español (Colombia)"},{code:"es-419",name:"Spanish (Latin America)",native_name:"Español (Latinoamérica)"},{code:"pt-BR",name:"Portuguese (Brazil)",native_name:"Português (Brasil)"},{code:"pt-PT",name:"Portuguese (Portugal)",native_name:"Português (Portugal)"},{code:"fr-FR",name:"French (France)",native_name:"Français (France)"},{code:"fr-CA",name:"French (Canada)",native_name:"Français (Canada)"},{code:"fr-BE",name:"French (Belgium)",native_name:"Français (Belgique)"},{code:"fr-CH",name:"French (Switzerland)",native_name:"Français (Suisse)"},{code:"de-DE",name:"German (Germany)",native_name:"Deutsch (Deutschland)"},{code:"de-AT",name:"German (Austria)",native_name:"Deutsch (Österreich)"},{code:"de-CH",name:"German (Switzerland)",native_name:"Deutsch (Schweiz)"},{code:"it-IT",name:"Italian (Italy)",native_name:"Italiano (Italia)"},{code:"it-CH",name:"Italian (Switzerland)",native_name:"Italiano (Svizzera)"},{code:"nl-NL",name:"Dutch (Netherlands)",native_name:"Nederlands (Nederland)"},{code:"nl-BE",name:"Dutch (Belgium)",native_name:"Nederlands (België)"},{code:"zh-CN",name:"Chinese (Simplified)",native_name:"中文 (简体)"},{code:"zh-TW",name:"Chinese (Traditional)",native_name:"中文 (繁體)"},{code:"zh-HK",name:"Chinese (Hong Kong)",native_name:"中文 (香港)"},{code:"zh-SG",name:"Chinese (Singapore)",native_name:"中文 (新加坡)"},{code:"ar-SA",name:"Arabic (Saudi Arabia)",native_name:"العربية (السعودية)",is_rtl:!0},{code:"ar-EG",name:"Arabic (Egypt)",native_name:"العربية (مصر)",is_rtl:!0},{code:"ar-AE",name:"Arabic (UAE)",native_name:"العربية (الإمارات)",is_rtl:!0},{code:"sr-Latn",name:"Serbian (Latin)",native_name:"Srpski"}],Ke=new Set(["en","es","fr","de","it","pt","nl","pl","ru","uk","cs","sk","sl","hu","ro","bg","hr","sr","el","tr","sv","no","da","fi","et","lv","lt","ja","ko","zh","vi","th","id","hi","bn","ar","he","sw"]),Qe=Je.filter(e=>function(e){const s=String(e||"").toLowerCase();return!s.includes("-")&&Ke.has(s)}(e.code));function es(e){if(!e)return null;const s=String(e).toLowerCase();return Je.find(e=>e.code.toLowerCase()===s)||null}const ss={pt:{kind:"ambiguous",variants:["pt-BR","pt-PT"]},zh:{kind:"ambiguous",variants:["zh-CN","zh-TW"]}},ts={id:null,source_term:"",rule_type:"never_translate",case_sensitive:!1,notes:"",translations:{}};function as({boot:e}){const s=Me(),t=String(e?.language?.default||"en").toLowerCase(),a=(0,n.useMemo)(()=>Array.isArray(e?.language?.active)?e.language.active:[],[e]),i=(0,n.useMemo)(()=>a.map(e=>String(e).toLowerCase()).filter(e=>e&&e!==t),[a,t]),[r,o]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[h,g]=(0,n.useState)(null),[u,m]=(0,n.useState)(!1),[w,v]=(0,n.useState)(null),[j,b]=(0,n.useState)(!1),[N,C]=(0,n.useState)(null),S=(0,n.useCallback)(async()=>{d(null);try{const e=await y()({path:"/gloty/v1/glossary",parse:!0});o(Array.isArray(e?.terms)?e.terms:[])}catch(e){o([]),d({status:"error",message:e?.message||(0,l.__)("Could not load the glossary.","gloty")})}},[]);(0,n.useEffect)(()=>{S()},[S]);const k=(0,n.useCallback)(e=>{const s=es(e);return s?`${s.name} (${e.toUpperCase()})`:e.toUpperCase()},[]),T=(e,s)=>g(t=>({...t,[e]:s})),E=e=>{if("translate_as"!==e.rule_type)return(0,l.__)("Kept exactly as written","gloty");const s=i.map(s=>{const t=e.translations?.[s];return t?`${s.toUpperCase()}: ${t}`:null}).filter(Boolean);return s.length?s.join(" · "):(0,l.__)("No per-language values set yet","gloty")},L=null===r;return(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-glossary-screen",children:[(0,_.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Keep your brand and product names exactly right in every language. Add a term to stop it being translated, or set exactly how it should appear per language.","gloty")}),c&&(0,_.jsx)(f.Notice,{status:c.status,isDismissible:!0,onDismiss:()=>d(null),className:"wpshelf-mb",children:c.message}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card",children:[(0,_.jsxs)(f.CardHeader,{size:"small",children:[(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Glossary terms","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>g({...ts,translations:{}}),disabled:L,children:(0,l.__)("Add term","gloty")})]}),(0,_.jsxs)(f.CardBody,{children:[L&&(0,_.jsx)(de,{rows:4,headers:[(0,l.__)("Term","gloty"),(0,l.__)("Behavior","gloty"),(0,l.__)("Rendering","gloty"),(0,l.__)("Active","gloty"),""]}),!L&&0===r.length&&(0,_.jsx)(ie,{icon:(0,_.jsx)(x,{icon:B}),title:(0,l.__)("No glossary terms yet","gloty"),hint:(0,l.__)("Add a brand or product name to protect it from translation across your whole site.","gloty")}),!L&&r.length>0&&(0,_.jsxs)(p,{className:"wp-list-table widefat striped wpshelf-table",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Term","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Behavior","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Rendering","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Active","gloty")}),(0,_.jsx)("th",{scope:"col"})]})}),(0,_.jsx)("tbody",{children:r.map(e=>(0,_.jsxs)("tr",{children:[(0,_.jsxs)("td",{children:[(0,_.jsx)("strong",{children:e.source_term}),!!e.case_sensitive&&(0,_.jsxs)("span",{className:"wpshelf-muted",children:[" ","·"," ",(0,l.__)("case-sensitive","gloty")]}),e.notes&&(0,_.jsx)("div",{className:"wpshelf-muted",children:e.notes})]}),(0,_.jsx)("td",{children:"translate_as"===e.rule_type?(0,l.__)("Translate as…","gloty"):(0,l.__)("Never translate","gloty")}),(0,_.jsx)("td",{className:"wpshelf-muted",children:E(e)}),(0,_.jsx)("td",{children:(0,_.jsx)(f.ToggleControl,{__nextHasNoMarginBottom:!0,checked:!!e.is_active,disabled:N===e.id,onChange:t=>(async(e,t)=>{if(N!==e.id){C(e.id),o(s=>s.map(s=>s.id===e.id?{...s,is_active:t?1:0}:s));try{await y()({path:`/gloty/v1/glossary/${e.id}`,method:"PUT",data:{is_active:t?1:0}})}catch(e){s.error(e?.message||(0,l.__)("Could not update the term.","gloty")),await S()}finally{C(null)}}})(e,t),label:""})}),(0,_.jsxs)("td",{children:[(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>(e=>g({id:e.id,source_term:e.source_term||"",rule_type:"translate_as"===e.rule_type?"translate_as":"never_translate",case_sensitive:!!e.case_sensitive,notes:e.notes||"",translations:e.translations&&"object"==typeof e.translations?{...e.translations}:{}}))(e),children:(0,l.__)("Edit","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",isDestructive:!0,onClick:()=>v(e),children:(0,l.__)("Delete","gloty")})]})]},e.id))})]})]})]}),h&&(0,_.jsxs)(f.Modal,{title:h.id?(0,l.__)("Edit glossary term","gloty"):(0,l.__)("Add glossary term","gloty"),onRequestClose:()=>g(null),className:"wpshelf-glossary-modal",children:[(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Term","gloty"),value:h.source_term,onChange:e=>T("source_term",e),placeholder:(0,l.__)("e.g. Chanel N°5","gloty"),help:(0,l.__)("The exact brand or product name as it appears on your site.","gloty")})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.SelectControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Behavior","gloty"),value:h.rule_type,options:[{label:(0,l.__)("Never translate — keep it verbatim","gloty"),value:"never_translate"},{label:(0,l.__)("Translate as… — set it per language","gloty"),value:"translate_as"}],onChange:e=>T("rule_type",e)})}),"translate_as"===h.rule_type&&(0,_.jsx)("div",{className:"wpshelf-settings-field",children:0===i.length?(0,_.jsx)(f.Notice,{status:"info",isDismissible:!1,children:(0,l.__)("Add a target language first to set per-language values. Until then the term is kept verbatim.","gloty")}):i.map(e=>(0,_.jsx)(f.TextControl,{__nextHasNoMarginBottom:!0,label:k(e),value:h.translations?.[e]||"",onChange:s=>((e,s)=>g(t=>({...t,translations:{...t.translations,[e]:s}})))(e,s),placeholder:(0,l.__)("Leave blank to keep verbatim","gloty")},e))}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Case-sensitive match","gloty"),help:(0,l.__)("Only match the exact capitalization above. Leave off for most brands.","gloty"),checked:h.case_sensitive,onChange:e=>T("case_sensitive",e)})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Note (optional)","gloty"),value:h.notes,onChange:e=>T("notes",e)})}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:8,marginTop:16,justifyContent:"flex-end"},children:[(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>g(null),children:(0,l.__)("Cancel","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{if(!h)return;const e=(h.source_term||"").trim();if(!e)return void s.error((0,l.__)("Enter a term first.","gloty"));const t={source_term:e,rule_type:h.rule_type,case_sensitive:h.case_sensitive?1:0,notes:h.notes||"",translations:"translate_as"===h.rule_type?h.translations:{}};m(!0);try{h.id?(await y()({path:`/gloty/v1/glossary/${h.id}`,method:"PUT",data:t}),s.success((0,l.__)("Term updated.","gloty"))):(await y()({path:"/gloty/v1/glossary",method:"POST",data:t}),s.success((0,l.__)("Term added.","gloty"))),g(null),await S()}catch(e){s.error(e?.message||(0,l.__)("Could not save the term.","gloty"))}finally{m(!1)}},isBusy:u,disabled:u,children:h.id?(0,l.__)("Save changes","gloty"):(0,l.__)("Add term","gloty")})]})]}),w&&(0,_.jsx)(re,{title:(0,l.__)("Remove glossary term","gloty"),message:(M=w.source_term,(0,l.__)("This term will be translated normally again on future syncs.","gloty").concat(M?` (“${M}”)`:"")),confirmLabel:(0,l.__)("Remove term","gloty"),busy:j,onConfirm:async()=>{if(w){b(!0);try{await y()({path:`/gloty/v1/glossary/${w.id}`,method:"DELETE"}),s.success((0,l.__)("Term removed.","gloty")),v(null),await S()}catch(e){s.error(e?.message||(0,l.__)("Could not remove the term.","gloty"))}finally{b(!1)}}},onCancel:()=>v(null)})]});var M}function ls(e){if(!e)return"";const s=(Date.now()-e)/1e3;return s<60?(0,l.__)("just now","gloty"):s<3600?Math.floor(s/60)+(0,l.__)("m ago","gloty"):s<86400?Math.floor(s/3600)+(0,l.__)("h ago","gloty"):Math.floor(s/86400)+(0,l.__)("d ago","gloty")}function ns({onNavigate:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(null),r=(0,n.useRef)(!0),o=(0,n.useCallback)(async()=>{try{const e=await y()({path:"/gloty/v1/issues",parse:!0});r.current&&(t(e?.count||{error:0,warning:0,info:0}),i(Date.now()))}catch{}},[]);(0,n.useEffect)(()=>{r.current=!0,o();const e=window.setInterval(o,6e4),s=()=>{"visible"===document.visibilityState&&o()};return document.addEventListener("visibilitychange",s),window.addEventListener("gloty-license-refresh",o),()=>{r.current=!1,window.clearInterval(e),document.removeEventListener("visibilitychange",s),window.removeEventListener("gloty-license-refresh",o)}},[o]);const[,c]=(0,n.useReducer)(e=>e+1,0);(0,n.useEffect)(()=>{const e=window.setInterval(c,3e4);return()=>window.clearInterval(e)},[]);const d=function(e){return e?(e.error||0)>0?{tone:"error",label:(0,l.__)("Disconnected","gloty")}:(e.warning||0)>0?{tone:"warning",label:(0,l.__)("Degraded","gloty")}:{tone:"ok",label:(0,l.__)("Connected","gloty")}:{tone:"loading",label:(0,l.__)("Checking…","gloty")}}(s),h=s&&"ok"!==d.tone&&"loading"!==d.tone?` (${(s.error||0)+(s.warning||0)})`:"";return(0,_.jsxs)("button",{type:"button",className:`wpshelf-health-pill wpshelf-health-pill--${d.tone}`,onClick:()=>e&&e("dashboard"),"aria-label":(0,l.__)("Connection health — click to view details","gloty"),title:(0,l.__)("Connection health. Click to jump to the Overview tab.","gloty"),children:[(0,_.jsx)("span",{className:"wpshelf-health-pill__dot","aria-hidden":"true"}),(0,_.jsxs)("span",{className:"wpshelf-health-pill__label",children:[d.label,h]}),a&&(0,_.jsx)("span",{className:"wpshelf-health-pill__time",children:ls(a)})]})}const is={error:"⚠",warning:"⚠",info:"ℹ"},rs={error:(0,l.__)("Critical","gloty"),warning:(0,l.__)("Warning","gloty"),info:(0,l.__)("Info","gloty")};function os({issue:e,onNavigate:s}){const t=e.severity||"info";return(0,_.jsxs)("li",{className:`wpshelf-issue wpshelf-issue--${t}`,children:[(0,_.jsx)("span",{className:"wpshelf-issue__icon","aria-hidden":"true",children:is[t]}),(0,_.jsxs)("div",{className:"wpshelf-issue__body",children:[(0,_.jsxs)("div",{className:"wpshelf-issue__title",children:[(0,_.jsxs)("span",{className:"screen-reader-text",children:[rs[t],":"]}),e.title]}),e.detail&&(0,_.jsx)("div",{className:"wpshelf-issue__detail wpshelf-muted",children:e.detail})]}),e.action&&s&&(0,_.jsx)(f.Button,{variant:"error"===t?"primary":"secondary",isSmall:!0,onClick:()=>s(e.action.view,e.action.filters||null),children:e.action.label})]})}function cs({onNavigate:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(!0),[r,o]=(0,n.useState)(null),c=(0,n.useCallback)(async()=>{i(!0),o(null);try{const e=await y()({path:"/gloty/v1/issues",parse:!0});t(e)}catch(e){o(e?.message||(0,l.__)("Could not load issues.","gloty"))}finally{i(!1)}},[]);if((0,n.useEffect)(()=>{c()},[c]),a&&!s)return null;if(r)return null;const d=s?.count||{error:0,warning:0,info:0},h=d.error+d.warning+d.info,g=s?.issues||[];let u=(0,l.__)("Needs attention","gloty");return 0===h?u=(0,l.__)("All clear","gloty"):d.error>0?u=(0,l.sprintf)(/* translators: %d: number of critical issues */ /* translators: %d: number of critical issues */ 22 (0,l._n)("Needs attention · %d critical issue","Needs attention · %d critical issues",d.error,"gloty"),d.error):d.warning>0&&(u=(0,l.sprintf)(/* translators: %d: number of warnings */ /* translators: %d: number of warnings */ 23 (0,l._n)("Needs attention · %d warning","Needs attention · %d warnings",d.warning,"gloty"),d.warning)),(0,_.jsxs)(f.Card,{className:"wpshelf-issues-card wpshelf-mb "+(d.error>0?"wpshelf-issues-card--error":d.warning>0?"wpshelf-issues-card--warning":""),role:"region","aria-label":(0,l.__)("System health","gloty"),children:[(0,_.jsxs)(f.CardHeader,{children:[(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:u}),(0,_.jsx)(f.Button,{variant:"tertiary",size:"small",onClick:c,disabled:a,isBusy:a,"aria-live":"polite",children:a?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]}),(0,_.jsx)(f.CardBody,{children:0===h?(0,_.jsx)("p",{className:"wpshelf-muted",style:{margin:0},children:(0,l.__)("No issues detected. Translator service is reachable and your license is in good standing.","gloty")}):(0,_.jsx)("ul",{className:"wpshelf-issues",children:g.map(s=>(0,_.jsx)(os,{issue:s,onNavigate:e},s.id))})})]})}function ds(e){return es(e)?.name||e}function hs({code:e}){const s=function(e,s=ss){const t=String(e||"").toLowerCase();if(!t)return null;const a=Object.keys(s).find(e=>e.toLowerCase()===t);return a?{code:a,kind:s[a].kind,variants:s[a].variants||[]}:null}(e);if(!s)return null;const t=function(e){const s=ds(e.code);if("ambiguous"===e.kind){const t=e.variants.map(e=>`${ds(e)} (${e})`);return(0,l.sprintf)(/* translators: 1: language name, 2: code, 3: one regional variant, 4: another */ /* translators: 1: language name, 2: code, 3: one regional variant, 4: another */ 24 24 (0,l.__)("%1$s (%2$s) covers more than one regional variant. Which one the translation engine writes is its choice, not a setting — %3$s and %4$s differ in vocabulary and idiom, not only spelling. Review the first translated pages before you make this language public.","gloty"),s,e.code,t[0]||"",t[1]||"")}return"unverified"===e.kind?(0,l.sprintf)(/* translators: 1: language name, 2: BCP 47 code */ /* translators: 1: language name, 2: BCP 47 code */ 25 (0,l.__)("Translation quality for %1$s (%2$s) is unverified. It is offered because a vendor lists it or somebody asked for it, not because anyone has read the output — review the first translated pages before you make this language public.","gloty"),s,e.code):""}(s);return t?(0, u.jsx)(y.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mb",politeness:"polite",children:t}):null}const hs=[{label:(0,l.__)("Dropdown","gloty"),value:"dropdown"},{label:(0,l.__)("Inline Links","gloty"),value:"inline"},{label:(0,l.__)("Flags Only","gloty"),value:"flags"}],gs=[{label:(0,l.__)("Automatic (let the engine decide)","gloty"),value:""},{label:(0,l.__)("Formal","gloty"),value:"formal"},{label:(0,l.__)("Informal","gloty"),value:"informal"}],us=[{label:(0,l.__)("Top Left","gloty"),value:"top_left"},{label:(0,l.__)("Top Right","gloty"),value:"top_right"},{label:(0,l.__)("Bottom Left","gloty"),value:"bottom_left"},{label:(0,l.__)("Bottom Right","gloty"),value:"bottom_right"},{label:(0,l.__)("Footer bar","gloty"),value:"footer"},{label:(0,l.__)("Manual (shortcode / widget only)","gloty"),value:"manual"}];function _s(e){const s=e?new Date(e).getTime():NaN;if(Number.isNaN(s))return"";const t=Math.max(0,Math.round((Date.now()-s)/1e3));if(t<60)return(0,l.__)("just now","gloty");const a=Math.round(t/60);if(a<60)25 (0,l.__)("Translation quality for %1$s (%2$s) is unverified. It is offered because a vendor lists it or somebody asked for it, not because anyone has read the output — review the first translated pages before you make this language public.","gloty"),s,e.code):""}(s);return t?(0,_.jsx)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mb",politeness:"polite",children:t}):null}const gs=[{label:(0,l.__)("Dropdown","gloty"),value:"dropdown"},{label:(0,l.__)("Inline Links","gloty"),value:"inline"},{label:(0,l.__)("Flags Only","gloty"),value:"flags"}],us=[{label:(0,l.__)("Automatic (let the engine decide)","gloty"),value:""},{label:(0,l.__)("Formal","gloty"),value:"formal"},{label:(0,l.__)("Informal","gloty"),value:"informal"}],_s=[{label:(0,l.__)("Top Left","gloty"),value:"top_left"},{label:(0,l.__)("Top Right","gloty"),value:"top_right"},{label:(0,l.__)("Bottom Left","gloty"),value:"bottom_left"},{label:(0,l.__)("Bottom Right","gloty"),value:"bottom_right"},{label:(0,l.__)("Footer bar","gloty"),value:"footer"},{label:(0,l.__)("Manual (shortcode / widget only)","gloty"),value:"manual"}];function ps(e){const s=e?new Date(e).getTime():NaN;if(Number.isNaN(s))return"";const t=Math.max(0,Math.round((Date.now()-s)/1e3));if(t<60)return(0,l.__)("just now","gloty");const a=Math.round(t/60);if(a<60) 26 26 // translators: %d is a number of minutes. 27 27 return(0,l.sprintf)((0,l._n)("%d minute ago","%d minutes ago",a,"gloty"),a);const n=Math.round(a/60);if(n<24) … … 29 29 return(0,l.sprintf)((0,l._n)("%d hour ago","%d hours ago",n,"gloty"),n);const i=Math.round(n/24); 30 30 // translators: %d is a number of days. 31 return(0,l.sprintf)((0,l._n)("%d day ago","%d days ago",i,"gloty"),i)}function ps(){const e=Le(),[s,t]=(0,n.useState)([]),[a,i]=(0,n.useState)([]),[r,o]=(0,n.useState)(""),[c,d]=(0,n.useState)(!0),[h,g]=(0,n.useState)(!1);(0,n.useEffect)(()=>{let e=!1;return m()({path:"/gloty/v1/settings/translators"}).then(s=>{if(e)return;const a=s?.roles||[];t(s?.available||[]),i(a),o(JSON.stringify([...a].sort()))}).catch(()=>{}).finally(()=>!e&&d(!1)),()=>{e=!0}},[]);const _=JSON.stringify([...a].sort())!==r;return(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Who may correct translations","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("People in these roles can open Gloty and correct translations. They cannot change settings, spend your plan, or delete anything. Administrators always can.","gloty")}),c?(0,u.jsx)(y.Spinner,{}):(0,u.jsxs)(u.Fragment,{children:[s.map(e=>(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.CheckboxControl,{label:e.name,checked:a.includes(e.slug),onChange:s=>{return t=e.slug,a=s,i(e=>a?[...e,t]:e.filter(e=>e!==t));var t,a},__nextHasNoMarginBottom:!0})},e.slug)),(0,u.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("A role also needs to be able to edit posts. To limit someone to particular languages, edit their user profile.","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:async()=>{g(!0);try{const s=await m()({path:"/gloty/v1/settings/translators",method:"POST",data:{roles:a}}),t=s?.roles||[];i(t),o(JSON.stringify([...t].sort())),e.success((0,l.__)("Translator roles saved.","gloty"))}catch(s){e.error(s?.message||(0,l.__)("Failed to save translator roles.","gloty"))}finally{g(!1)}},isBusy:h,disabled:h||!_,children:h?(0,l.__)("Saving…","gloty"):(0,l.__)("Save roles","gloty")})]})]})]})}function ms({boot:e}){const s=Le(),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)({}),[o,c]=(0,n.useState)(!0),[d,h]=(0,n.useState)(!1),[g,_]=(0,n.useState)(null),p=(0,n.useCallback)(async()=>{c(!0),_(null);try{const e=await m()({path:"/gloty/v1/settings/plugin",parse:!0});a(e),r(e)}catch(e){_({status:"error",message:e?.message||(0,l.__)("Failed to load settings.","gloty")})}finally{c(!1)}},[]);(0,n.useEffect)(()=>{p()},[p]);const f=(0,n.useCallback)((e,s)=>{r(t=>({...t,[e]:s}))},[]),w=(0,n.useMemo)(()=>!!t&&JSON.stringify(i)!==JSON.stringify(t),[i,t]),x=async()=>{h(!0),_(null);try{await m()({path:"/gloty/v1/settings/plugin",method:"POST",data:i}),_({status:"success",message:(0,l.__)("Settings saved.","gloty")}),s.success((0,l.__)("Settings saved.","gloty")),await p()}catch(e){const t=e?.message||(0,l.__)("Failed to save settings.","gloty");_({status:"error",message:t}),s.error(t)}finally{h(!1)}};if(o)return(0,u.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,u.jsx)(y.Spinner,{}),(0,u.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading settings…","gloty")})]});const v=e?.sync?.lastDispatchAt||"",j=!!e?.sync?.cronStalled;return(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-settings-screen",children:[(0,u.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Control how translations are generated and customise the language switcher appearance.","gloty")}),g&&(0,u.jsx)(y.Notice,{status:g.status,isDismissible:!0,onDismiss:()=>_(null),className:"wpshelf-mb",children:g.message}),(0,u.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:x,isBusy:d,disabled:d||!w,children:d?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),w&&(0,u.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Translation","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Control how and when translations are created.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Formality","gloty"),value:i.translation_formality||"",options:gs,onChange:e=>f("translation_formality",e),help:(0,l.__)('How your site addresses visitors — for example "Sie" or "du" in German. Applies to translations created from now on; content already translated keeps its current wording.',"gloty"),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextareaControl,{label:(0,l.__)("Brand voice","gloty"),value:i.translation_tone||"",onChange:e=>f("translation_tone",e),rows:2,maxLength:300,help:(0,l.__)('Optional. A short note on how your brand should sound, e.g. "warm and plain-spoken, no exclamation marks". Sent with every translation request.',"gloty"),__nextHasNoMarginBottom:!0})}),(0,u.jsxs)("div",{className:"wpshelf-settings-field",children:[(0,u.jsx)(y.TextControl,{label:(0,l.__)("Dispatch batch size","gloty"),value:String(i.batch_size||40),onChange:e=>f("batch_size",Math.max(1,Math.min(500,parseInt(e,10)||1))),type:"number",min:1,max:500,help:(0,l.__)("Strings sent to the translator per background run (1–500). The background job runs about once a minute when WordPress cron is healthy, so a higher value clears a backlog faster — 100–250 suits a large initial translation.","gloty"),__nextHasNoMarginBottom:!0}),(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:8,marginBottom:0},children:v?(0,l.sprintf)(31 return(0,l.sprintf)((0,l._n)("%d day ago","%d days ago",i,"gloty"),i)}function ms(){const e=Me(),[s,t]=(0,n.useState)([]),[a,i]=(0,n.useState)([]),[r,o]=(0,n.useState)(""),[c,d]=(0,n.useState)(!0),[h,g]=(0,n.useState)(!1);(0,n.useEffect)(()=>{let e=!1;return y()({path:"/gloty/v1/settings/translators"}).then(s=>{if(e)return;const a=s?.roles||[];t(s?.available||[]),i(a),o(JSON.stringify([...a].sort()))}).catch(()=>{}).finally(()=>!e&&d(!1)),()=>{e=!0}},[]);const u=JSON.stringify([...a].sort())!==r;return(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Who may correct translations","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("People in these roles can open Gloty and correct translations. They cannot change settings, spend your plan, or delete anything. Administrators always can.","gloty")}),c?(0,_.jsx)(f.Spinner,{}):(0,_.jsxs)(_.Fragment,{children:[s.map(e=>(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.CheckboxControl,{label:e.name,checked:a.includes(e.slug),onChange:s=>{return t=e.slug,a=s,i(e=>a?[...e,t]:e.filter(e=>e!==t));var t,a},__nextHasNoMarginBottom:!0})},e.slug)),(0,_.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("A role also needs to be able to edit posts. To limit someone to particular languages, edit their user profile.","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:async()=>{g(!0);try{const s=await y()({path:"/gloty/v1/settings/translators",method:"POST",data:{roles:a}}),t=s?.roles||[];i(t),o(JSON.stringify([...t].sort())),e.success((0,l.__)("Translator roles saved.","gloty"))}catch(s){e.error(s?.message||(0,l.__)("Failed to save translator roles.","gloty"))}finally{g(!1)}},isBusy:h,disabled:h||!u,children:h?(0,l.__)("Saving…","gloty"):(0,l.__)("Save roles","gloty")})]})]})]})}function ys({boot:e}){const s=Me(),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)({}),[o,c]=(0,n.useState)(!0),[d,h]=(0,n.useState)(!1),[g,u]=(0,n.useState)(null),p=(0,n.useCallback)(async()=>{c(!0),u(null);try{const e=await y()({path:"/gloty/v1/settings/plugin",parse:!0});a(e),r(e)}catch(e){u({status:"error",message:e?.message||(0,l.__)("Failed to load settings.","gloty")})}finally{c(!1)}},[]);(0,n.useEffect)(()=>{p()},[p]);const m=(0,n.useCallback)((e,s)=>{r(t=>({...t,[e]:s}))},[]),w=(0,n.useMemo)(()=>!!t&&JSON.stringify(i)!==JSON.stringify(t),[i,t]),x=async()=>{h(!0),u(null);try{await y()({path:"/gloty/v1/settings/plugin",method:"POST",data:i}),u({status:"success",message:(0,l.__)("Settings saved.","gloty")}),s.success((0,l.__)("Settings saved.","gloty")),await p()}catch(e){const t=e?.message||(0,l.__)("Failed to save settings.","gloty");u({status:"error",message:t}),s.error(t)}finally{h(!1)}};if(o)return(0,_.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,_.jsx)(f.Spinner,{}),(0,_.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading settings…","gloty")})]});const v=e?.sync?.lastDispatchAt||"",j=!!e?.sync?.cronStalled;return(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-settings-screen",children:[(0,_.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Control how translations are generated and customise the language switcher appearance.","gloty")}),g&&(0,_.jsx)(f.Notice,{status:g.status,isDismissible:!0,onDismiss:()=>u(null),className:"wpshelf-mb",children:g.message}),(0,_.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:x,isBusy:d,disabled:d||!w,children:d?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),w&&(0,_.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Translation","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Control how and when translations are created.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Formality","gloty"),value:i.translation_formality||"",options:us,onChange:e=>m("translation_formality",e),help:(0,l.__)('How your site addresses visitors — for example "Sie" or "du" in German. Applies to translations created from now on; content already translated keeps its current wording.',"gloty"),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextareaControl,{label:(0,l.__)("Brand voice","gloty"),value:i.translation_tone||"",onChange:e=>m("translation_tone",e),rows:2,maxLength:300,help:(0,l.__)('Optional. A short note on how your brand should sound, e.g. "warm and plain-spoken, no exclamation marks". Sent with every translation request.',"gloty"),__nextHasNoMarginBottom:!0})}),(0,_.jsxs)("div",{className:"wpshelf-settings-field",children:[(0,_.jsx)(f.TextControl,{label:(0,l.__)("Dispatch batch size","gloty"),value:String(i.batch_size||40),onChange:e=>m("batch_size",Math.max(1,Math.min(500,parseInt(e,10)||1))),type:"number",min:1,max:500,help:(0,l.__)("Strings sent to the translator per background run (1–500). The background job runs about once a minute when WordPress cron is healthy, so a higher value clears a backlog faster — 100–250 suits a large initial translation.","gloty"),__nextHasNoMarginBottom:!0}),(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:8,marginBottom:0},children:v?(0,l.sprintf)( 32 32 // translators: %s is a relative time, e.g. "2 minutes ago". 33 33 // translators: %s is a relative time, e.g. "2 minutes ago". 34 (0,l.__)("Background dispatch last ran %s.","gloty"), _s(v)):(0,l.__)("Background dispatch has not run yet.","gloty")}),j&&(0,u.jsx)("div",{style:{marginTop:8},children:(0,u.jsx)(y.Notice,{status:"warning",isDismissible:!1,children:(0,l.__)("Translations dispatch on WordPress cron, which only fires when your site gets traffic — so on a quiet site they trickle out slowly. For steady throughput, point a real cron (or a 1-minute uptime ping) at wp-cron.php. The translator itself is fast; it just needs to be fed.","gloty")})})]}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Cache translations","gloty"),help:(0,l.__)("Reuse stored translations for identical text instead of re-sending it to the translator. Recommended — leave on unless you are debugging translation output.","gloty"),checked:void 0===i.translation_cache||!!i.translation_cache,onChange:e=>f("translation_cache",e),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextareaControl,{label:(0,l.__)("Exclusion selectors","gloty"),value:i.exclude_selectors||"",onChange:e=>f("exclude_selectors",e),placeholder:".no-translate, #site-credit, code",help:(0,l.__)("Comma-separated CSS selectors for elements to leave untranslated — e.g. brand names, code samples, author credits. Example: .no-translate, #site-credit, code. Leave blank to translate everything.","gloty"),rows:3,__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Translate page addresses","gloty"),help:(0,l.__)("Give each translated page an address in its own language — /de/ueber-uns/ instead of /de/about-us/. The address is worked out from the translated title, so it costs no extra translation. Your existing addresses keep working, so nothing you have shared or that Google has indexed will break.","gloty"),checked:!!i.translate_slugs,onChange:e=>f("translate_slugs",e),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextareaControl,{label:(0,l.__)("Pages to leave untranslated","gloty"),value:i.exclude_paths||"",onChange:e=>f("exclude_paths",e),placeholder:"/checkout/*\n/terms-and-conditions",help:(0,l.__)("One path per line. Use * as a wildcard — /checkout/* covers everything below /checkout/. Write the path without a language prefix and it applies in every language. These pages render in your site language and cost no quota.","gloty"),rows:3,__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextareaControl,{label:(0,l.__)("Content loaded after the page","gloty"),value:i.ajax_actions||"",onChange:e=>f("ajax_actions",e),placeholder:"load_more_posts\nfilter_products",help:(0,l.__)("One AJAX action name per line. If your theme loads more posts, filters a product grid or opens a search panel without reloading the page, that content skips translation — naming the action here fixes it. Leave empty unless you have that problem: your theme or plugin documentation, or the browser network tab, will tell you the action name. WooCommerce’s own cart and checkout are already handled.","gloty"),rows:2,__nextHasNoMarginBottom:!0})})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Visitor redirection","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Automatically greet international visitors in the version of your site that matches their browser language.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Auto-redirect by browser language","gloty"),help:(0,l.__)("On their first visit, send visitors to their preferred language when you offer it. Applied once per visitor — a manual choice from the switcher is always respected afterwards, and search engine crawlers are never redirected.","gloty"),checked:!!i.auto_redirect,onChange:e=>f("auto_redirect",e),__nextHasNoMarginBottom:!0})})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Analytics","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Gloty counts views per language so you can see which languages are worth translating. Counting is local either way — no visitor data is stored and nothing is sent off your site.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Count views from the browser","gloty"),help:(0,l.__)("Turn this on if you run a page cache (WP Rocket, LiteSpeed, Cloudflare). Cached pages are served without starting PHP, so Gloty cannot see those views and your per-language split is both low and uneven. With this on, a small script counts the view from the browser instead, sending only the language of the page — no IP address, no page address, no referrer, no identifier of any kind. Server-side counting switches off at the same time, so each view is still counted once. The cost: a visitor with JavaScript disabled is not counted, and if a plugin combines your site’s JavaScript, exclude the “gloty-page-view-beacon” handle from it.","gloty"),checked:!!i.analytics_beacon,onChange:e=>f("analytics_beacon",e),__nextHasNoMarginBottom:!0})})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Language Switcher","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Customise the appearance and placement of the language switcher on your site.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Style","gloty"),value:i.switcher_style||"dropdown",options:hs,onChange:e=>f("switcher_style",e),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Position","gloty"),value:i.switcher_position||"bottom_right",options:us,help:(0,l.__)("The four corners float the switcher over the page. Footer bar puts it in a strip at the end of the page instead, in the style chosen above.","gloty"),onChange:e=>f("switcher_position",e),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Show flags","gloty"),help:(0,l.__)("Display country flags next to language names in the switcher.","gloty"),checked:void 0===i.show_flags||!!i.show_flags,onChange:e=>f("show_flags",e),__nextHasNoMarginBottom:!0})})]})]}),(0,u.jsx)(ps,{}),(0,u.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:x,isBusy:d,disabled:d||!w,children:d?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),w&&(0,u.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]})]})}const ys="gloty_quota_80_dismissed";function fs({license:e,hideOnboarding:s=!1}){const[t,a]=(0,n.useState)(!1),[i,r]=(0,n.useState)([]),[o,c]=(0,n.useState)(null),[d,h]=(0,n.useState)(()=>{if("undefined"==typeof window)return!1;try{return"1"===window.sessionStorage.getItem(ys)}catch{return!1}}),g=e?.status,_=g?.characters_used??0,p=g?.characters_limit??0,f=p>0?Math.round(_/p*100):0;(0,n.useEffect)(()=>{let e=!0;return ye().then(s=>{e&&r(s)}),()=>{e=!1}},[]);const w=fe(g,i)[0]||null,x=(0,n.useCallback)(async()=>{if(w){a(!0),c(null);try{const e=await m()({path:"/gloty/v1/license/checkout",method:"POST",data:{plan_slug:w.slug}});c(e?.url?je(e.url):ve(e?.message))}catch(e){c(ve(e?.message))}finally{a(!1)}}},[w]);if(s||!e?.hasKey||!g||f<80)return null;const v=f>=100;if(!v&&d)return null;const j=v?(0,l.__)("Translation quota exceeded. New translations are paused until the next billing period.","gloty"):(0,l.__)("You have used over 80% of your translation quota this period.","gloty");return(0,u.jsxs)(y.Notice,{status:v?"error":"warning",spokenMessage:j,isDismissible:!v,onDismiss:v?void 0:()=>{try{window.sessionStorage.setItem(ys,"1")}catch{}h(!0)},className:"wpshelf-mb",children:[(0,u.jsxs)("span",{children:[j," ",(0,u.jsxs)("strong",{children:[_.toLocaleString()," / ",p.toLocaleString()," ",(0,l.__)("characters","gloty")," (",f,"%)"]})]}),w&&(0,u.jsx)(y.Button,{variant:"link",onClick:x,isBusy:t,disabled:t,style:{marginLeft:8},children:(0,l.sprintf)(/* translators: %s: plan name, e.g. Starter */ /* translators: %s: plan name, e.g. Starter */35 (0,l.__)("Upgrade to %s","gloty"),w.name)}),o&&(0, u.jsx)("p",{className:"wpshelf-quota-notice__problem",children:o.message})]})}const ws=[{key:"hreflang",label:(0,l.__)("Output hreflang tags","gloty"),help:(0,l.__)("Tell search engines which language and regional URL to serve. Each page declares every active language plus an x-default — the single most important multilingual SEO signal.","gloty")},{key:"meta",label:(0,l.__)("Translate metadata & Open Graph","gloty"),help:(0,l.__)("Emit a translated meta description plus Open Graph and Twitter Card tags so shared links and search snippets appear in the visitor’s language.","gloty")},{key:"sitemap",label:(0,l.__)("Publish a sitemap of your translated pages","gloty"),help:(0,l.__)("A sitemap listing every translated URL, so search engines can find them. Separate from your main sitemap on purpose: Yoast, Rank Math, AIOSEO and SEOPress each replace the WordPress one with their own, and none of them know about translations.","gloty")},{key:"schema",label:(0,l.__)("Output language schema (JSON-LD)","gloty"),help:(0,l.__)("Declare the page language in structured data (schema.org WebSite inLanguage) for richer search results.","gloty")}];function xs({boot:e}){const s=Le(),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)(()=>({hreflang:e?.seo?.hreflang??!0,meta:e?.seo?.meta??!0,sitemap:e?.seo?.sitemap??!0,schema:e?.seo?.schema??!0})),[o,c]=(0,n.useState)(""),[d,h]=(0,n.useState)(!!e?.seo?.seoPluginActive),[g,_]=(0,n.useState)(!0),[p,f]=(0,n.useState)(!1),[w,x]=(0,n.useState)(null),v=(0,n.useCallback)(async()=>{_(!0),x(null);try{const e=await m()({path:"/gloty/v1/settings/seo",parse:!0}),s={hreflang:!!e.hreflang,meta:!!e.meta,sitemap:!!e.sitemap,schema:!!e.schema};a(s),r(s),h(!!e.seo_plugin_active),c(e.language_sitemap_url||"")}catch(e){x({status:"error",message:e?.message||(0,l.__)("Failed to load SEO settings.","gloty")})}finally{_(!1)}},[]);(0,n.useEffect)(()=>{v()},[v]);const j=(0,n.useCallback)((e,s)=>{r(t=>({...t,[e]:s}))},[]),b=(0,n.useMemo)(()=>!!t&&JSON.stringify(i)!==JSON.stringify(t),[i,t]);if(g)return(0,u.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,u.jsx)(y.Spinner,{}),(0,u.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading SEO settings…","gloty")})]});const N=(0,u.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{f(!0),x(null);try{await m()({path:"/gloty/v1/settings/seo",method:"POST",data:i}),a(i),x({status:"success",message:(0,l.__)("SEO settings saved.","gloty")}),s.success((0,l.__)("SEO settings saved.","gloty"))}catch(e){const t=e?.message||(0,l.__)("Failed to save SEO settings.","gloty");x({status:"error",message:t}),s.error(t)}finally{f(!1)}},isBusy:p,disabled:p||!b,children:p?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),b&&(0,u.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]});return(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-seo-screen",children:[(0,u.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Make every translated page discoverable. Gloty follows Google’s multilingual SEO guidance — declaring language alternates, translating metadata, and keeping the right URL canonical for each language.","gloty")}),w&&(0,u.jsx)(y.Notice,{status:w.status,isDismissible:!0,onDismiss:()=>x(null),className:"wpshelf-mb",children:w.message}),N,(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Search engine optimization","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("These run automatically on the front end. Translated titles, descriptions, and canonical URLs stay in sync with your translations — no per-page setup.","gloty")}),d&&(0,u.jsx)(y.Notice,{status:"info",isDismissible:!1,className:"wpshelf-mb",children:(0,l.__)("A dedicated SEO plugin (e.g. Yoast or Rank Math) is active, so Gloty translates its meta tags instead of emitting its own. The “Translate metadata & Open Graph” toggle only affects Gloty’s native tags, which stand down while that plugin is active.","gloty")}),i.sitemap&&o&&(0,u.jsxs)(y.Notice,{status:"info",isDismissible:!1,className:"wpshelf-mb",children:[(0,l.__)("Your translated-pages sitemap is at:","gloty")," ",(0,u.jsx)("a",{href:o,children:o}),(0,u.jsx)("br",{}),(0,l.__)("Gloty adds this to robots.txt, but an SEO plugin that manages robots.txt will replace that line with its own. If yours does, submit the address above to Google Search Console once and it is done.","gloty")]}),ws.map(e=>(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:e.label,help:e.help,checked:!!i[e.key],onChange:s=>j(e.key,s),__nextHasNoMarginBottom:!0})},e.key))]})]}),N]})}function vs({boot:e,onNavigate:s}={}){const t=e?.connection?.connected??!(!e?.connection?.serviceUrl||!e?.connection?.remoteSiteId),[a,i]=(0,n.useState)(null),[r,o]=(0,n.useState)(!1),[c,d]=(0,n.useState)("full"),[h,g]=(0,n.useState)(!0),[p,f]=(0,n.useState)(!1),[w,x]=(0,n.useState)(!1),[v,j]=(0,n.useState)(null),[b,N]=(0,n.useState)(null),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(null),[B,E]=(0,n.useState)(!1),[L,M]=(0,n.useState)(null),[A,D]=(0,n.useState)(!1),[R,O]=(0,n.useState)(null),[P,$]=(0,n.useState)([]),[I,H]=(0,n.useState)(null),[G,z]=(0,n.useState)([]),[F,V]=(0,n.useState)(""),[U,q]=(0,n.useState)(!1),[W,X]=(0,n.useState)(!0),[Y,Z]=(0,n.useState)(null),J=(0,n.useCallback)(async()=>{Z(null);try{const e=F?`/gloty/v1/activity?type=${encodeURIComponent(F)}`:"/gloty/v1/activity",[s,t,a,l]=await Promise.all([m()({path:"/gloty/v1/dashboard",parse:!0}),m()({path:"/gloty/v1/scan/status",parse:!0}),m()({path:"/gloty/v1/jobs",parse:!0}),m()({path:e,parse:!0})]),n=s?.overview||{};j(n.pending_count??0),N(n.processing_count??0),S(n.source_count??0),T(n.needs_sync_sources??0),i(t),$(a?.jobs||[]),z(l?.events||[])}catch(e){Z(e?.message||(0,l.__)("Failed to load sync data","gloty"))}finally{X(!1)}},[F]);(0,n.useEffect)(()=>{J()},[J]);const[Q,ae]=(0,n.useState)(!1),le=(0,n.useCallback)(async()=>{ae(!0);try{await J()}finally{ae(!1)}},[J]),re=(0,n.useCallback)(async()=>{try{const[e,s]=await Promise.all([m()({path:"/gloty/v1/jobs",parse:!0}),m()({path:"/gloty/v1/dashboard",parse:!0})]);$(e?.jobs||[]);const t=s?.overview||{};j(t.pending_count??0),N(t.processing_count??0)}catch{}},[]),oe=(0,n.useMemo)(()=>P.some(e=>"queued"===e.status||"processing"===e.status),[P]);(0,n.useEffect)(()=>{if(!oe)return;const e=window.setInterval(re,3e3);return()=>window.clearInterval(e)},[oe,re]);const[de,he]=(0,n.useState)(!1);(0,n.useEffect)(()=>{de&&!oe&&J(),he(oe)},[oe,J,de]);const ge=async()=>{o(!0),Z(null);try{await m()({path:"/gloty/v1/scan/start",method:"POST",data:{batch_size:20,mode:c}}),g(!0),await J()}catch(e){Z(e?.message||(0,l.__)("Scan failed","gloty"))}finally{o(!1)}},ue=(0,n.useCallback)(async()=>{o(!0),Z(null);try{await m()({path:"/gloty/v1/scan/step",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Scan step failed","gloty"))}finally{o(!1)}},[J]),_e=async(e,s)=>{H(e.id),Z(null);try{await m()({path:`/gloty/v1/jobs/${e.id}/${s}`,method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Job action failed","gloty"))}finally{H(null)}},pe=a?.cursor||{},me=a?.stats||{},ye="running"===pe.status||"processing"===pe.status,fe="paused"===pe.status,we="complete"===pe.status,xe=pe.mode||me.mode||c,ve=Number(me.processed||0),je=Number(me.queued||0),be=Number(me.last_batch||0),Ne=Number(me.failure_count||0),Ce=Number(me.phase_processed??pe.offset??0),Se=Number(me.phase_total||0),ke=Number(me.total_entities||0),Te=ke>0?Math.min(Math.round(ve/ke*100),100):0,Be=Se>0?Math.min(Math.round(Ce/Se*100),100):0,Ee=ye?(0,l.__)("Scanning now","gloty"):fe?(0,l.__)("Paused by operator","gloty"):we?(0,l.__)("Completed","gloty"):(0,l.__)("Waiting to start","gloty");(0,n.useEffect)(()=>{if(!h||!ye||r)return;const e=window.setTimeout(()=>{ue()},2500);return()=>window.clearTimeout(e)},[h,ye,r,ue]);let Le=(0,u.jsx)(y.Button,{variant:"primary",onClick:ge,isBusy:r,disabled:r,children:(0,l.__)("Scan content","gloty")});ye?Le=(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:ue,isBusy:r,disabled:r,children:(0,l.__)("Continue scan","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>x(!0),disabled:r,children:(0,l.__)("Restart","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",onClick:async()=>{o(!0),Z(null);try{await m()({path:"/gloty/v1/scan/pause",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Could not pause scan","gloty"))}finally{o(!1)}},disabled:r,children:(0,l.__)("Pause","gloty")})]}):fe?Le=(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{o(!0),Z(null);try{await m()({path:"/gloty/v1/scan/resume",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Could not resume scan","gloty"))}finally{o(!1)}},isBusy:r,disabled:r,children:(0,l.__)("Resume scan","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>x(!0),disabled:r,children:(0,l.__)("Restart","gloty")})]}):we&&(Le=(0,u.jsx)(y.Button,{variant:"secondary",onClick:ge,disabled:r,children:(0,l.__)("Run again","gloty")}));const Me=(0,n.useMemo)(()=>{const e={queued:0,processing:0,completed:0,failed:0};return P.forEach(s=>{void 0!==e[s.status]&&e[s.status]++}),e},[P]),Ae=e=>e?.payload?.job_id?`job #${e.payload.job_id}`:e?.payload?.remote_job_id?`remote ${e.payload.remote_job_id}`:e?.payload?.correlation?`corr ${e.payload.correlation}`:"—";return W?(0,u.jsx)("div",{className:"wpshelf-screen",children:(0,u.jsx)(ce,{cols:5,rows:4,headers:[(0,l.__)("Job","gloty"),(0,l.__)("Language","gloty"),(0,l.__)("Segments","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Created","gloty")]})}):(0,u.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Sync workspace","gloty"),children:[(0,u.jsx)(ee,{title:(0,l.__)("Sync workspace","gloty"),subtitle:(0,l.__)("Run scan and dispatch actions, then inspect jobs and events in one place.","gloty")}),Y&&(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:Y}),(0,u.jsx)("div",{"aria-live":"polite","aria-atomic":"true",className:"screen-reader-text",children:L||""}),(0,u.jsxs)("div",{className:"wpshelf-sync-actions",children:[(0,u.jsxs)(y.Card,{className:"wpshelf-sync-card wpshelf-sync-card--scan",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsxs)("div",{className:"wpshelf-sync-card__heading",children:[(0,u.jsx)("span",{className:"wpshelf-sync-card__step",children:(0,l.__)("Step 1","gloty")}),(0,u.jsx)("h3",{className:"wpshelf-sync-card__title",children:(0,l.__)("Scan content","gloty")})]})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-sync-card__desc",children:(0,l.__)("Discover posts, pages, and other content that needs translation.","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-sync-card__status",children:[(0,u.jsx)(K,{status:pe.status||"idle"}),(0,u.jsx)("span",{className:"wpshelf-sync-card__statetext","aria-live":"polite",children:ye?(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(y.Spinner,{}),(0,l.__)("Scanning your content…","gloty")]}):Ee})]}),(0,u.jsxs)("p",{className:"wpshelf-sync-card__summary wpshelf-muted",children:[(0,l.sprintf)(/* translators: %s: number of translatable strings found */ /* translators: %s: number of translatable strings found */34 (0,l.__)("Background dispatch last ran %s.","gloty"),ps(v)):(0,l.__)("Background dispatch has not run yet.","gloty")}),j&&(0,_.jsx)("div",{style:{marginTop:8},children:(0,_.jsx)(f.Notice,{status:"warning",isDismissible:!1,children:(0,l.__)("Translations dispatch on WordPress cron, which only fires when your site gets traffic — so on a quiet site they trickle out slowly. For steady throughput, point a real cron (or a 1-minute uptime ping) at wp-cron.php. The translator itself is fast; it just needs to be fed.","gloty")})})]}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Cache translations","gloty"),help:(0,l.__)("Reuse stored translations for identical text instead of re-sending it to the translator. Recommended — leave on unless you are debugging translation output.","gloty"),checked:void 0===i.translation_cache||!!i.translation_cache,onChange:e=>m("translation_cache",e),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextareaControl,{label:(0,l.__)("Exclusion selectors","gloty"),value:i.exclude_selectors||"",onChange:e=>m("exclude_selectors",e),placeholder:".no-translate, #site-credit, code",help:(0,l.__)("Comma-separated CSS selectors for elements to leave untranslated — e.g. brand names, code samples, author credits. Example: .no-translate, #site-credit, code. Leave blank to translate everything.","gloty"),rows:3,__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Translate page addresses","gloty"),help:(0,l.__)("Give each translated page an address in its own language — /de/ueber-uns/ instead of /de/about-us/. The address is worked out from the translated title, so it costs no extra translation. Your existing addresses keep working, so nothing you have shared or that Google has indexed will break.","gloty"),checked:!!i.translate_slugs,onChange:e=>m("translate_slugs",e),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextareaControl,{label:(0,l.__)("Pages to leave untranslated","gloty"),value:i.exclude_paths||"",onChange:e=>m("exclude_paths",e),placeholder:"/checkout/*\n/terms-and-conditions",help:(0,l.__)("One path per line. Use * as a wildcard — /checkout/* covers everything below /checkout/. Write the path without a language prefix and it applies in every language. These pages render in your site language and cost no quota.","gloty"),rows:3,__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextareaControl,{label:(0,l.__)("Content loaded after the page","gloty"),value:i.ajax_actions||"",onChange:e=>m("ajax_actions",e),placeholder:"load_more_posts\nfilter_products",help:(0,l.__)("One AJAX action name per line. If your theme loads more posts, filters a product grid or opens a search panel without reloading the page, that content skips translation — naming the action here fixes it. Leave empty unless you have that problem: your theme or plugin documentation, or the browser network tab, will tell you the action name. WooCommerce’s own cart and checkout are already handled.","gloty"),rows:2,__nextHasNoMarginBottom:!0})})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Visitor redirection","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Automatically greet international visitors in the version of your site that matches their browser language.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Auto-redirect by browser language","gloty"),help:(0,l.__)("On their first visit, send visitors to their preferred language when you offer it. Applied once per visitor — a manual choice from the switcher is always respected afterwards, and search engine crawlers are never redirected.","gloty"),checked:!!i.auto_redirect,onChange:e=>m("auto_redirect",e),__nextHasNoMarginBottom:!0})})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Analytics","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Gloty counts views per language so you can see which languages are worth translating. Counting is local either way — no visitor data is stored and nothing is sent off your site.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Count views from the browser","gloty"),help:(0,l.__)("Turn this on if you run a page cache (WP Rocket, LiteSpeed, Cloudflare). Cached pages are served without starting PHP, so Gloty cannot see those views and your per-language split is both low and uneven. With this on, a small script counts the view from the browser instead, sending only the language of the page — no IP address, no page address, no referrer, no identifier of any kind. Server-side counting switches off at the same time, so each view is still counted once. The cost: a visitor with JavaScript disabled is not counted, and if a plugin combines your site’s JavaScript, exclude the “gloty-page-view-beacon” handle from it.","gloty"),checked:!!i.analytics_beacon,onChange:e=>m("analytics_beacon",e),__nextHasNoMarginBottom:!0})})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Language Switcher","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Customise the appearance and placement of the language switcher on your site.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Style","gloty"),value:i.switcher_style||"dropdown",options:gs,onChange:e=>m("switcher_style",e),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Position","gloty"),value:i.switcher_position||"bottom_right",options:_s,help:(0,l.__)("The four corners float the switcher over the page. Footer bar puts it in a strip at the end of the page instead, in the style chosen above.","gloty"),onChange:e=>m("switcher_position",e),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Show flags","gloty"),help:(0,l.__)("Display country flags next to language names in the switcher.","gloty"),checked:void 0===i.show_flags||!!i.show_flags,onChange:e=>m("show_flags",e),__nextHasNoMarginBottom:!0})})]})]}),(0,_.jsx)(ms,{}),(0,_.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:x,isBusy:d,disabled:d||!w,children:d?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),w&&(0,_.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]})]})}const fs="gloty_quota_80_dismissed";function ws({license:e,hideOnboarding:s=!1}){const[t,a]=(0,n.useState)(!1),[i,r]=(0,n.useState)([]),[o,c]=(0,n.useState)(null),[d,h]=(0,n.useState)(()=>{if("undefined"==typeof window)return!1;try{return"1"===window.sessionStorage.getItem(fs)}catch{return!1}}),g=e?.status,u=g?.characters_used??0,p=g?.characters_limit??0,m=p>0?Math.round(u/p*100):0;(0,n.useEffect)(()=>{let e=!0;return fe().then(s=>{e&&r(s)}),()=>{e=!1}},[]);const w=we(g,i)[0]||null,x=(0,n.useCallback)(async()=>{if(w){a(!0),c(null);try{const e=await y()({path:"/gloty/v1/license/checkout",method:"POST",data:{plan_slug:w.slug}});c(e?.url?be(e.url):je(e?.message))}catch(e){c(je(e?.message))}finally{a(!1)}}},[w]);if(s||!e?.hasKey||!g||m<80)return null;const v=m>=100;if(!v&&d)return null;const j=v?(0,l.__)("Translation quota exceeded. New translations are paused until the next billing period.","gloty"):(0,l.__)("You have used over 80% of your translation quota this period.","gloty");return(0,_.jsxs)(f.Notice,{status:v?"error":"warning",spokenMessage:j,isDismissible:!v,onDismiss:v?void 0:()=>{try{window.sessionStorage.setItem(fs,"1")}catch{}h(!0)},className:"wpshelf-mb",children:[(0,_.jsxs)("span",{children:[j," ",(0,_.jsxs)("strong",{children:[u.toLocaleString()," / ",p.toLocaleString()," ",(0,l.__)("characters","gloty")," (",m,"%)"]})]}),w&&(0,_.jsx)(f.Button,{variant:"link",onClick:x,isBusy:t,disabled:t,style:{marginLeft:8},children:(0,l.sprintf)(/* translators: %s: plan name, e.g. Starter */ /* translators: %s: plan name, e.g. Starter */ 35 (0,l.__)("Upgrade to %s","gloty"),w.name)}),o&&(0,_.jsx)("p",{className:"wpshelf-quota-notice__problem",children:o.message})]})}const xs=[{key:"hreflang",label:(0,l.__)("Output hreflang tags","gloty"),help:(0,l.__)("Tell search engines which language and regional URL to serve. Each page declares every active language plus an x-default — the single most important multilingual SEO signal.","gloty")},{key:"meta",label:(0,l.__)("Translate metadata & Open Graph","gloty"),help:(0,l.__)("Emit a translated meta description plus Open Graph and Twitter Card tags so shared links and search snippets appear in the visitor’s language.","gloty")},{key:"sitemap",label:(0,l.__)("Publish a sitemap of your translated pages","gloty"),help:(0,l.__)("A sitemap listing every translated URL, so search engines can find them. Separate from your main sitemap on purpose: Yoast, Rank Math, AIOSEO and SEOPress each replace the WordPress one with their own, and none of them know about translations.","gloty")},{key:"schema",label:(0,l.__)("Output language schema (JSON-LD)","gloty"),help:(0,l.__)("Declare the page language in structured data (schema.org WebSite inLanguage) for richer search results.","gloty")}];function vs({boot:e}){const s=Me(),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)(()=>({hreflang:e?.seo?.hreflang??!0,meta:e?.seo?.meta??!0,sitemap:e?.seo?.sitemap??!0,schema:e?.seo?.schema??!0})),[o,c]=(0,n.useState)(""),[d,h]=(0,n.useState)(!!e?.seo?.seoPluginActive),[g,u]=(0,n.useState)(!0),[p,m]=(0,n.useState)(!1),[w,x]=(0,n.useState)(null),v=(0,n.useCallback)(async()=>{u(!0),x(null);try{const e=await y()({path:"/gloty/v1/settings/seo",parse:!0}),s={hreflang:!!e.hreflang,meta:!!e.meta,sitemap:!!e.sitemap,schema:!!e.schema};a(s),r(s),h(!!e.seo_plugin_active),c(e.language_sitemap_url||"")}catch(e){x({status:"error",message:e?.message||(0,l.__)("Failed to load SEO settings.","gloty")})}finally{u(!1)}},[]);(0,n.useEffect)(()=>{v()},[v]);const j=(0,n.useCallback)((e,s)=>{r(t=>({...t,[e]:s}))},[]),b=(0,n.useMemo)(()=>!!t&&JSON.stringify(i)!==JSON.stringify(t),[i,t]);if(g)return(0,_.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,_.jsx)(f.Spinner,{}),(0,_.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading SEO settings…","gloty")})]});const N=(0,_.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{m(!0),x(null);try{await y()({path:"/gloty/v1/settings/seo",method:"POST",data:i}),a(i),x({status:"success",message:(0,l.__)("SEO settings saved.","gloty")}),s.success((0,l.__)("SEO settings saved.","gloty"))}catch(e){const t=e?.message||(0,l.__)("Failed to save SEO settings.","gloty");x({status:"error",message:t}),s.error(t)}finally{m(!1)}},isBusy:p,disabled:p||!b,children:p?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),b&&(0,_.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]});return(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-seo-screen",children:[(0,_.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Make every translated page discoverable. Gloty follows Google’s multilingual SEO guidance — declaring language alternates, translating metadata, and keeping the right URL canonical for each language.","gloty")}),w&&(0,_.jsx)(f.Notice,{status:w.status,isDismissible:!0,onDismiss:()=>x(null),className:"wpshelf-mb",children:w.message}),N,(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Search engine optimization","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("These run automatically on the front end. Translated titles, descriptions, and canonical URLs stay in sync with your translations — no per-page setup.","gloty")}),d&&(0,_.jsx)(f.Notice,{status:"info",isDismissible:!1,className:"wpshelf-mb",children:(0,l.__)("A dedicated SEO plugin (e.g. Yoast or Rank Math) is active, so Gloty translates its meta tags instead of emitting its own. The “Translate metadata & Open Graph” toggle only affects Gloty’s native tags, which stand down while that plugin is active.","gloty")}),i.sitemap&&o&&(0,_.jsxs)(f.Notice,{status:"info",isDismissible:!1,className:"wpshelf-mb",children:[(0,l.__)("Your translated-pages sitemap is at:","gloty")," ",(0,_.jsx)("a",{href:o,children:o}),(0,_.jsx)("br",{}),(0,l.__)("Gloty adds this to robots.txt, but an SEO plugin that manages robots.txt will replace that line with its own. If yours does, submit the address above to Google Search Console once and it is done.","gloty")]}),xs.map(e=>(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:e.label,help:e.help,checked:!!i[e.key],onChange:s=>j(e.key,s),__nextHasNoMarginBottom:!0})},e.key))]})]}),N]})}function js({boot:e,onNavigate:s}={}){const t=e?.connection?.connected??!(!e?.connection?.serviceUrl||!e?.connection?.remoteSiteId),[a,i]=(0,n.useState)(null),[r,o]=(0,n.useState)(!1),[c,d]=(0,n.useState)("full"),[h,g]=(0,n.useState)(!0),[u,m]=(0,n.useState)(!1),[w,x]=(0,n.useState)(!1),[v,j]=(0,n.useState)(null),[b,N]=(0,n.useState)(null),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(null),[B,E]=(0,n.useState)(!1),[L,M]=(0,n.useState)(null),[A,D]=(0,n.useState)(!1),[R,O]=(0,n.useState)(null),[P,$]=(0,n.useState)([]),[I,H]=(0,n.useState)(null),[G,z]=(0,n.useState)([]),[F,V]=(0,n.useState)(""),[U,q]=(0,n.useState)(!1),[W,X]=(0,n.useState)(!0),[Y,Z]=(0,n.useState)(null),J=(0,n.useCallback)(async()=>{Z(null);try{const e=F?`/gloty/v1/activity?type=${encodeURIComponent(F)}`:"/gloty/v1/activity",[s,t,a,l]=await Promise.all([y()({path:"/gloty/v1/dashboard",parse:!0}),y()({path:"/gloty/v1/scan/status",parse:!0}),y()({path:"/gloty/v1/jobs",parse:!0}),y()({path:e,parse:!0})]),n=s?.overview||{};j(n.pending_count??0),N(n.processing_count??0),S(n.source_count??0),T(n.needs_sync_sources??0),i(t),$(a?.jobs||[]),z(l?.events||[])}catch(e){Z(e?.message||(0,l.__)("Failed to load sync data","gloty"))}finally{X(!1)}},[F]);(0,n.useEffect)(()=>{J()},[J]);const[K,ee]=(0,n.useState)(!1),le=(0,n.useCallback)(async()=>{ee(!0);try{await J()}finally{ee(!1)}},[J]),ne=(0,n.useCallback)(async()=>{try{const[e,s]=await Promise.all([y()({path:"/gloty/v1/jobs",parse:!0}),y()({path:"/gloty/v1/dashboard",parse:!0})]);$(e?.jobs||[]);const t=s?.overview||{};j(t.pending_count??0),N(t.processing_count??0)}catch{}},[]),oe=(0,n.useMemo)(()=>P.some(e=>"queued"===e.status||"processing"===e.status),[P]);(0,n.useEffect)(()=>{if(!oe)return;const e=window.setInterval(ne,3e3);return()=>window.clearInterval(e)},[oe,ne]);const[ce,he]=(0,n.useState)(!1);(0,n.useEffect)(()=>{ce&&!oe&&J(),he(oe)},[oe,J,ce]);const ge=async()=>{o(!0),Z(null);try{await y()({path:"/gloty/v1/scan/start",method:"POST",data:{batch_size:20,mode:c}}),g(!0),await J()}catch(e){Z(e?.message||(0,l.__)("Scan failed","gloty"))}finally{o(!1)}},ue=(0,n.useCallback)(async()=>{o(!0),Z(null);try{await y()({path:"/gloty/v1/scan/step",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Scan step failed","gloty"))}finally{o(!1)}},[J]),_e=async(e,s)=>{H(e.id),Z(null);try{await y()({path:`/gloty/v1/jobs/${e.id}/${s}`,method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Job action failed","gloty"))}finally{H(null)}},pe=a?.cursor||{},me=a?.stats||{},ye="running"===pe.status||"processing"===pe.status,fe="paused"===pe.status,we="complete"===pe.status,xe=pe.mode||me.mode||c,ve=Number(me.processed||0),je=Number(me.queued||0),be=Number(me.last_batch||0),Ne=Number(me.failure_count||0),Ce=Number(me.phase_processed??pe.offset??0),Se=Number(me.phase_total||0),ke=Number(me.total_entities||0),Te=ke>0?Math.min(Math.round(ve/ke*100),100):0,Be=Se>0?Math.min(Math.round(Ce/Se*100),100):0,Ee=ye?(0,l.__)("Scanning now","gloty"):fe?(0,l.__)("Paused by operator","gloty"):we?(0,l.__)("Completed","gloty"):(0,l.__)("Waiting to start","gloty");(0,n.useEffect)(()=>{if(!h||!ye||r)return;const e=window.setTimeout(()=>{ue()},2500);return()=>window.clearTimeout(e)},[h,ye,r,ue]);let Le=(0,_.jsx)(f.Button,{variant:"primary",onClick:ge,isBusy:r,disabled:r,children:(0,l.__)("Scan content","gloty")});ye?Le=(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:ue,isBusy:r,disabled:r,children:(0,l.__)("Continue scan","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>x(!0),disabled:r,children:(0,l.__)("Restart","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",onClick:async()=>{o(!0),Z(null);try{await y()({path:"/gloty/v1/scan/pause",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Could not pause scan","gloty"))}finally{o(!1)}},disabled:r,children:(0,l.__)("Pause","gloty")})]}):fe?Le=(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{o(!0),Z(null);try{await y()({path:"/gloty/v1/scan/resume",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Could not resume scan","gloty"))}finally{o(!1)}},isBusy:r,disabled:r,children:(0,l.__)("Resume scan","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>x(!0),disabled:r,children:(0,l.__)("Restart","gloty")})]}):we&&(Le=(0,_.jsx)(f.Button,{variant:"secondary",onClick:ge,disabled:r,children:(0,l.__)("Run again","gloty")}));const Me=(0,n.useMemo)(()=>{const e={queued:0,processing:0,completed:0,failed:0};return P.forEach(s=>{void 0!==e[s.status]&&e[s.status]++}),e},[P]),Ae=e=>e?.payload?.job_id?`job #${e.payload.job_id}`:e?.payload?.remote_job_id?`remote ${e.payload.remote_job_id}`:e?.payload?.correlation?`corr ${e.payload.correlation}`:"—";return W?(0,_.jsx)("div",{className:"wpshelf-screen",children:(0,_.jsx)(de,{cols:5,rows:4,headers:[(0,l.__)("Job","gloty"),(0,l.__)("Language","gloty"),(0,l.__)("Segments","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Created","gloty")]})}):(0,_.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Sync workspace","gloty"),children:[(0,_.jsx)(se,{title:(0,l.__)("Sync workspace","gloty"),subtitle:(0,l.__)("Run scan and dispatch actions, then inspect jobs and events in one place.","gloty")}),Y&&(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:Y}),(0,_.jsx)("div",{"aria-live":"polite","aria-atomic":"true",className:"screen-reader-text",children:L||""}),(0,_.jsxs)("div",{className:"wpshelf-sync-actions",children:[(0,_.jsxs)(f.Card,{className:"wpshelf-sync-card wpshelf-sync-card--scan",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsxs)("div",{className:"wpshelf-sync-card__heading",children:[(0,_.jsx)("span",{className:"wpshelf-sync-card__step",children:(0,l.__)("Step 1","gloty")}),(0,_.jsx)("h3",{className:"wpshelf-sync-card__title",children:(0,l.__)("Scan content","gloty")})]})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-sync-card__desc",children:(0,l.__)("Discover posts, pages, and other content that needs translation.","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-sync-card__status",children:[(0,_.jsx)(Q,{status:pe.status||"idle"}),(0,_.jsx)("span",{className:"wpshelf-sync-card__statetext","aria-live":"polite",children:ye?(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(f.Spinner,{}),(0,l.__)("Scanning your content…","gloty")]}):Ee})]}),(0,_.jsxs)("p",{className:"wpshelf-sync-card__summary wpshelf-muted",children:[(0,l.sprintf)(/* translators: %s: number of translatable strings found */ /* translators: %s: number of translatable strings found */ 36 36 (0,l.__)("%s translatable strings found so far.","gloty"),Number(C??0).toLocaleString()),(k??0)>0&&" "+(0,l.sprintf)(/* translators: %s: number of strings not yet sent */ /* translators: %s: number of strings not yet sent */ 37 (0,l.__)("%s not yet sent for translation.","gloty"),Number(k).toLocaleString())]}),(0, u.jsxs)("div",{className:"wpshelf-sync-progress",children:[(0,u.jsxs)("div",{className:"wpshelf-sync-progress__row",children:[(0,u.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Run progress","gloty")}),(0,u.jsxs)("strong",{children:[se(ve),"/",ke?se(ke):"—"," ","(",Te,"%)"]})]}),(0,u.jsx)("div",{className:"wpshelf-sync-progress__bar"+(ye?" wpshelf-sync-progress__bar--active":""),role:"progressbar","aria-label":(0,l.__)("Scan run progress","gloty"),"aria-valuenow":Math.round(Te),"aria-valuemin":0,"aria-valuemax":100,"aria-valuetext":`${ve} of ${ke||0}`,children:(0,u.jsx)("div",{className:"wpshelf-sync-progress__fill",style:{width:`${Te}%`}})}),(0,u.jsxs)("div",{className:"wpshelf-sync-progress__row",children:[(0,u.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Current phase progress","gloty")}),(0,u.jsxs)("strong",{children:[se(Ce),"/",Se?se(Se):"—"," ","(",Be,"%)"]})]})]}),(0,u.jsx)("div",{style:{maxWidth:220,marginTop:10},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Scan mode","gloty"),value:c,options:[{label:(0,l.__)("Quick scan","gloty"),value:"quick"},{label:(0,l.__)("Full backfill","gloty"),value:"full"},{label:(0,l.__)("Incremental rescan","gloty"),value:"incremental"}],onChange:d,disabled:ye||fe||r,__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{marginTop:10},children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Auto-advance scan batches (recommended)","gloty"),help:(0,l.__)("Recommended. Runs the next scan batch automatically every few seconds so the scan finishes on its own. Turn off only if you want to step through batches manually.","gloty"),checked:h,disabled:!ye||r,onChange:g,__nextHasNoMarginBottom:!0})}),be>0&&(0,u.jsxs)("p",{className:"wpshelf-muted",style:{marginTop:10},children:[`Last batch: ${be} item(s)`,Ne>0?` • failures: ${Ne}`:""]}),(0,u.jsx)("div",{className:"wpshelf-row",style:{marginTop:12},children:Le}),(0,u.jsxs)("button",{type:"button",className:"wpshelf-collapsible-header wpshelf-collapsible-header--sm",onClick:()=>f(e=>!e),"aria-expanded":p,"aria-controls":"gloty-scan-details",children:[(0,u.jsx)("span",{className:"wpshelf-collapsible-header__arrow",children:p?"▾":"▸"}),(0,u.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Technical details","gloty")})]}),p&&(0,u.jsxs)("dl",{id:"gloty-scan-details",className:"wpshelf-sync-detail-grid",children:[(0,u.jsx)("dt",{children:(0,l.__)("Mode","gloty")}),(0,u.jsx)("dd",{children:xe}),(0,u.jsx)("dt",{children:(0,l.__)("Phase","gloty")}),(0,u.jsx)("dd",{children:pe.phase||(0,l.__)("posts","gloty")}),(0,u.jsx)("dt",{children:(0,l.__)("Checkpoint","gloty")}),(0,u.jsx)("dd",{children:pe.offset??0}),(0,u.jsx)("dt",{children:(0,l.__)("This run — discovered","gloty")}),(0,u.jsx)("dd",{children:ve}),(0,u.jsx)("dt",{children:(0,l.__)("This run — queued","gloty")}),(0,u.jsx)("dd",{children:je}),(0,u.jsx)("dt",{children:(0,l.__)("Registry sources","gloty")}),(0,u.jsx)("dd",{children:C??0})]})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-sync-card wpshelf-sync-card--translate",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsxs)("div",{className:"wpshelf-sync-card__heading",children:[(0,u.jsx)("span",{className:"wpshelf-sync-card__step",children:(0,l.__)("Step 2","gloty")}),(0,u.jsx)("h3",{className:"wpshelf-sync-card__title",children:(0,l.__)("Generate translations","gloty")})]})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-sync-card__desc",children:(0,l.__)("Send pending strings to your translation provider for processing.","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-sync-card__meta",children:[(0,u.jsxs)("span",{children:[(0,u.jsx)("strong",{children:Number(v??0).toLocaleString()})," ",(0,l.__)("translations queued to send","gloty")]}),0===(v??0)&&(k??0)>0&&(0,u.jsxs)("span",{className:"wpshelf-muted",style:{display:"block",marginTop:6},children:[(0,u.jsx)("strong",{children:se(k)})," ",(0,l.__)("source item(s) discovered and waiting to be sent","gloty")]}),(b??0)>0&&(0,u.jsxs)("span",{className:"wpshelf-muted",style:{display:"block",marginTop:6},children:[(0,u.jsx)("strong",{children:se(b)})," ",(0,l.__)("currently being translated by the provider","gloty")]})]}),(v??0)>0&&(0,u.jsx)("p",{className:"wpshelf-sync-card__hint wpshelf-muted",children:(0,l.__)("These are sent to your AI provider and count toward your monthly character quota. Translations usually appear within a minute or two — track progress in Recent jobs below.","gloty")}),L&&(0,u.jsx)(y.Notice,{status:A?"error":"success",isDismissible:!1,className:"wpshelf-mt",children:L}),R&&R.dispatched>0&&(0,u.jsxs)("p",{className:"wpshelf-muted wpshelf-mt",children:[`${R.dispatched} batch(es) dispatched`,R.remaining>0?` • ${R.remaining} string(s) still processing`:" • backlog cleared"]}),t?(0,u.jsxs)(u.Fragment,{children:[0===(v??0)&&0===(k??0)&&(0,u.jsx)("p",{className:"wpshelf-sync-card__hint wpshelf-muted",children:(0,l.__)("Nothing pending yet — run a scan in Step 1 to discover translatable content first.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-row",style:{marginTop:12},children:(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{E(!0),M(null),D(!1),O(null);let e=0;try{for(let s=0;s<100;s++){const s=await m()({path:"/gloty/v1/jobs/dispatch",method:"POST",parse:!0});if(!1===s?.ok){D(!0),M(s?.error||s?.message||(0,l.__)("Failed to dispatch translation jobs.","gloty"));break}const t=Number(s?.dispatched||0),a=Number(s?.remaining||0);if(e+=t,M(s?.message||(0,l.__)("Dispatching translation jobs…","gloty")),O({dispatched:e,remaining:a,stage:s?.stage||""}),await J(),0===a||!1===s?.quota_ok||0===t)break;await new Promise(e=>setTimeout(e,2e3))}}catch(e){M(e?.message||(0,l.__)("Failed to start translations","gloty")),D(!0)}finally{E(!1)}},isBusy:B,disabled:B||0===(v??0)&&0===(k??0),children:(0,l.__)("Translate now","gloty")})})]}):(0,u.jsxs)(y.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",spokenMessage:(0,l.__)("Translator service not connected. Translations can’t be sent until this site is connected to the Gloty service.","gloty"),children:[(0,u.jsx)("strong",{children:(0,l.__)("Translator service not connected.","gloty")})," ",(0,l.__)("Translations can’t be sent until this site is connected to the Gloty service.","gloty"),s&&(0,u.jsx)("div",{className:"wpshelf-row",style:{marginTop:10},children:(0,u.jsx)(y.Button,{variant:"primary",onClick:()=>s("onboarding"),children:(0,l.__)("Connect now","gloty")})})]})]})]})]}),(0,u.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",children:[(0,u.jsx)("h3",{className:"wpshelf-section-heading",style:{margin:0,border:0,padding:0},children:(0,l.__)("Recent jobs","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",onClick:le,isSmall:!0,isBusy:Q,disabled:Q,"aria-live":"polite",children:Q?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]}),P.length>0&&(0,u.jsx)("div",{className:"wpshelf-row",style:{gap:16,margin:"8px 0 12px"},children:Object.entries(Me).filter(([,e])=>e>0).map(([e,s])=>(0,u.jsxs)("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[(0,u.jsx)(K,{status:e}),(0,u.jsx)("strong",{children:s})]},e))}),0===P.length?(0,u.jsx)(ne,{title:(0,l.__)("No jobs yet","gloty"),hint:(0,l.__)('Jobs appear here after you click "Translate now".',"gloty")}):(0,u.jsxs)(_,{className:"wp-list-table widefat striped",style:{marginBottom:24},children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Status","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Segments","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Correlation","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Created","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Updated","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Diagnostics","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Actions","gloty")})]})}),(0,u.jsx)("tbody",{children:P.map(e=>(0,u.jsxs)("tr",{children:[(0,u.jsx)("td",{children:(0,u.jsx)(K,{status:e.status})}),(0,u.jsx)("td",{children:se(e.segment_count||0)}),(0,u.jsx)("td",{children:(0,u.jsx)("code",{children:e.correlation_id||"—"})}),(0,u.jsx)("td",{className:"wpshelf-muted",children:te(e.created_at)}),(0,u.jsx)("td",{className:"wpshelf-muted",children:te(e.updated_at)}),(0,u.jsx)("td",{children:e.error_message?(0,u.jsx)("span",{className:"wpshelf-sync-diagnostic wpshelf-sync-diagnostic--error",children:e.error_message}):(0,u.jsx)("span",{className:"wpshelf-muted",children:e.remote_job_id?`remote: ${e.remote_job_id}`:(0,l.__)("No errors","gloty")})}),(0,u.jsx)("td",{children:(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:["failed"===e.status&&(0,u.jsx)(y.Button,{variant:"secondary",isSmall:!0,onClick:()=>_e(e,"retry"),disabled:null!==I,isBusy:I===e.id,children:(0,l.__)("Retry","gloty")}),("queued"===e.status||"processing"===e.status)&&(0,u.jsx)(y.Button,{variant:"tertiary",isSmall:!0,onClick:()=>_e(e,"cancel"),disabled:null!==I,isBusy:I===e.id,children:(0,l.__)("Cancel","gloty")})]})})]},e.id))})]}),(0,u.jsxs)("button",{type:"button",className:"wpshelf-collapsible-header",onClick:()=>q(!U),"aria-expanded":U,"aria-controls":"gloty-event-log",children:[(0,u.jsx)("span",{className:"wpshelf-collapsible-header__arrow",children:U?"▾":"▸"}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",style:{margin:0,border:0,padding:0},children:(0,l.__)("Event log","gloty")})]}),U&&(0,u.jsxs)("div",{id:"gloty-event-log",children:[(0,u.jsx)("div",{style:{maxWidth:280,margin:"12px 0"},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Filter by type","gloty"),value:F,options:[{label:(0,l.__)("All types","gloty"),value:""},{label:(0,l.__)("Sync","gloty"),value:"sync.dispatch"},{label:(0,l.__)("Webhook","gloty"),value:"sync.webhook"},{label:(0,l.__)("Translation","gloty"),value:"translation.update"},{label:(0,l.__)("Scan","gloty"),value:"scan.progress"}],onChange:V,__nextHasNoMarginBottom:!0})}),0===G.length?(0,u.jsx)(ne,{title:(0,l.__)("No events yet","gloty"),hint:(0,l.__)("Events appear after scans, syncs, and translation updates.","gloty")}):(0,u.jsxs)(_,{className:"wp-list-table widefat striped",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{scope:"col",children:(0,l.__)("When","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Type","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Message","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Context","gloty")})]})}),(0,u.jsx)("tbody",{children:G.map(e=>(0,u.jsxs)("tr",{children:[(0,u.jsx)("td",{className:"wpshelf-muted",children:te(e.created_at)}),(0,u.jsx)("td",{children:(0,u.jsx)("code",{children:e.type})}),(0,u.jsx)("td",{children:e.message}),(0,u.jsx)("td",{className:"wpshelf-muted",children:Ae(e)})]},e.id))})]})]}),w&&(0,u.jsx)(ie,{title:(0,l.__)("Restart scan?","gloty"),message:(0,l.__)("This starts the scan over from the beginning. Already-discovered strings stay saved — nothing is deleted — but the current run’s progress resets to zero.","gloty"),confirmLabel:(0,l.__)("Restart scan","gloty"),isDestructive:!1,busy:r,onConfirm:()=>{x(!1),ge()},onCancel:()=>x(!1)})]})}var js=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})}),bs=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})}),Ns=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z"})});function Cs(e){const s=ae(e?.original_text),t=ae(e?.translated_text),a=function(e,s,t){return""===e?(0,l.__)("This row has no plain text to use as a term.","gloty"):""===s?(0,l.__)("Translate this row first — there is nothing to promote yet.","gloty"):""===t?(0,l.__)("This row has no target language.","gloty"):e.length>191?(0,l.sprintf)(/* translators: %d: maximum number of characters a glossary term may have. */ /* translators: %d: maximum number of characters a glossary term may have. */38 (0,l.__)("Glossary terms are brand and product names, up to %d characters. This row is longer than that.","gloty"),191):""}(s,t,String(e?.target_language||"").trim().toLowerCase());return{eligible:""===a,reason:a,term:s,translated:t,verbatim:""!==s&&s===t}}function Ss(e,s=80){return e?e.length>s?e.slice(0,s)+"…":e:"—"}function ks(e){const s=String(e||"");if(!s)return{label:"—",title:""};const t=s.split(":");if("gloty"===t[0]&&"e"===t[1]){const e=t[2];if("post"===e||"term"===e){const a=t[3],n="post"===e?(0,l.__)("Post","gloty"):(0,l.__)("Term","gloty");let i=t.slice(4).join(":");const r=i.match(/^content:s(\d+)$/);r&&(i=(0,l.sprintf)(/* translators: %s: segment number within a post body */ /* translators: %s: segment number within a post body */37 (0,l.__)("%s not yet sent for translation.","gloty"),Number(k).toLocaleString())]}),(0,_.jsxs)("div",{className:"wpshelf-sync-progress",children:[(0,_.jsxs)("div",{className:"wpshelf-sync-progress__row",children:[(0,_.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Run progress","gloty")}),(0,_.jsxs)("strong",{children:[te(ve),"/",ke?te(ke):"—"," ","(",Te,"%)"]})]}),(0,_.jsx)("div",{className:"wpshelf-sync-progress__bar"+(ye?" wpshelf-sync-progress__bar--active":""),role:"progressbar","aria-label":(0,l.__)("Scan run progress","gloty"),"aria-valuenow":Math.round(Te),"aria-valuemin":0,"aria-valuemax":100,"aria-valuetext":`${ve} of ${ke||0}`,children:(0,_.jsx)("div",{className:"wpshelf-sync-progress__fill",style:{width:`${Te}%`}})}),(0,_.jsxs)("div",{className:"wpshelf-sync-progress__row",children:[(0,_.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Current phase progress","gloty")}),(0,_.jsxs)("strong",{children:[te(Ce),"/",Se?te(Se):"—"," ","(",Be,"%)"]})]})]}),(0,_.jsx)("div",{style:{maxWidth:220,marginTop:10},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Scan mode","gloty"),value:c,options:[{label:(0,l.__)("Quick scan","gloty"),value:"quick"},{label:(0,l.__)("Full backfill","gloty"),value:"full"},{label:(0,l.__)("Incremental rescan","gloty"),value:"incremental"}],onChange:d,disabled:ye||fe||r,__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{marginTop:10},children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Auto-advance scan batches (recommended)","gloty"),help:(0,l.__)("Recommended. Runs the next scan batch automatically every few seconds so the scan finishes on its own. Turn off only if you want to step through batches manually.","gloty"),checked:h,disabled:!ye||r,onChange:g,__nextHasNoMarginBottom:!0})}),be>0&&(0,_.jsxs)("p",{className:"wpshelf-muted",style:{marginTop:10},children:[`Last batch: ${be} item(s)`,Ne>0?` • failures: ${Ne}`:""]}),(0,_.jsx)("div",{className:"wpshelf-row",style:{marginTop:12},children:Le}),(0,_.jsxs)("button",{type:"button",className:"wpshelf-collapsible-header wpshelf-collapsible-header--sm",onClick:()=>m(e=>!e),"aria-expanded":u,"aria-controls":"gloty-scan-details",children:[(0,_.jsx)("span",{className:"wpshelf-collapsible-header__arrow",children:u?"▾":"▸"}),(0,_.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Technical details","gloty")})]}),u&&(0,_.jsxs)("dl",{id:"gloty-scan-details",className:"wpshelf-sync-detail-grid",children:[(0,_.jsx)("dt",{children:(0,l.__)("Mode","gloty")}),(0,_.jsx)("dd",{children:xe}),(0,_.jsx)("dt",{children:(0,l.__)("Phase","gloty")}),(0,_.jsx)("dd",{children:pe.phase||(0,l.__)("posts","gloty")}),(0,_.jsx)("dt",{children:(0,l.__)("Checkpoint","gloty")}),(0,_.jsx)("dd",{children:pe.offset??0}),(0,_.jsx)("dt",{children:(0,l.__)("This run — discovered","gloty")}),(0,_.jsx)("dd",{children:ve}),(0,_.jsx)("dt",{children:(0,l.__)("This run — queued","gloty")}),(0,_.jsx)("dd",{children:je}),(0,_.jsx)("dt",{children:(0,l.__)("Registry sources","gloty")}),(0,_.jsx)("dd",{children:C??0})]})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-sync-card wpshelf-sync-card--translate",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsxs)("div",{className:"wpshelf-sync-card__heading",children:[(0,_.jsx)("span",{className:"wpshelf-sync-card__step",children:(0,l.__)("Step 2","gloty")}),(0,_.jsx)("h3",{className:"wpshelf-sync-card__title",children:(0,l.__)("Generate translations","gloty")})]})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-sync-card__desc",children:(0,l.__)("Send pending strings to your translation provider for processing.","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-sync-card__meta",children:[(0,_.jsxs)("span",{children:[(0,_.jsx)("strong",{children:Number(v??0).toLocaleString()})," ",(0,l.__)("translations queued to send","gloty")]}),0===(v??0)&&(k??0)>0&&(0,_.jsxs)("span",{className:"wpshelf-muted",style:{display:"block",marginTop:6},children:[(0,_.jsx)("strong",{children:te(k)})," ",(0,l.__)("source item(s) discovered and waiting to be sent","gloty")]}),(b??0)>0&&(0,_.jsxs)("span",{className:"wpshelf-muted",style:{display:"block",marginTop:6},children:[(0,_.jsx)("strong",{children:te(b)})," ",(0,l.__)("currently being translated by the provider","gloty")]})]}),(v??0)>0&&(0,_.jsx)("p",{className:"wpshelf-sync-card__hint wpshelf-muted",children:(0,l.__)("These are sent to your AI provider and count toward your monthly character quota. Translations usually appear within a minute or two — track progress in Recent jobs below.","gloty")}),L&&(0,_.jsx)(f.Notice,{status:A?"error":"success",isDismissible:!1,className:"wpshelf-mt",children:L}),R&&R.dispatched>0&&(0,_.jsxs)("p",{className:"wpshelf-muted wpshelf-mt",children:[`${R.dispatched} batch(es) dispatched`,R.remaining>0?` • ${R.remaining} string(s) still processing`:" • backlog cleared"]}),t?(0,_.jsxs)(_.Fragment,{children:[0===(v??0)&&0===(k??0)&&(0,_.jsx)("p",{className:"wpshelf-sync-card__hint wpshelf-muted",children:(0,l.__)("Nothing pending yet — run a scan in Step 1 to discover translatable content first.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-row",style:{marginTop:12},children:(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{E(!0),M(null),D(!1),O(null);let e=0;try{for(let s=0;s<100;s++){const s=await y()({path:"/gloty/v1/jobs/dispatch",method:"POST",parse:!0});if(!1===s?.ok){D(!0),M(s?.error||s?.message||(0,l.__)("Failed to dispatch translation jobs.","gloty"));break}const t=Number(s?.dispatched||0),a=Number(s?.remaining||0);if(e+=t,M(s?.message||(0,l.__)("Dispatching translation jobs…","gloty")),O({dispatched:e,remaining:a,stage:s?.stage||""}),await J(),0===a||!1===s?.quota_ok||0===t)break;await new Promise(e=>setTimeout(e,2e3))}}catch(e){M(e?.message||(0,l.__)("Failed to start translations","gloty")),D(!0)}finally{E(!1)}},isBusy:B,disabled:B||0===(v??0)&&0===(k??0),children:(0,l.__)("Translate now","gloty")})})]}):(0,_.jsxs)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",spokenMessage:(0,l.__)("Translator service not connected. Translations can’t be sent until this site is connected to the Gloty service.","gloty"),children:[(0,_.jsx)("strong",{children:(0,l.__)("Translator service not connected.","gloty")})," ",(0,l.__)("Translations can’t be sent until this site is connected to the Gloty service.","gloty"),s&&(0,_.jsx)("div",{className:"wpshelf-row",style:{marginTop:10},children:(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>s("onboarding"),children:(0,l.__)("Connect now","gloty")})})]})]})]})]}),(0,_.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",children:[(0,_.jsx)("h3",{className:"wpshelf-section-heading",style:{margin:0,border:0,padding:0},children:(0,l.__)("Recent jobs","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",onClick:le,isSmall:!0,isBusy:K,disabled:K,"aria-live":"polite",children:K?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]}),P.length>0&&(0,_.jsx)("div",{className:"wpshelf-row",style:{gap:16,margin:"8px 0 12px"},children:Object.entries(Me).filter(([,e])=>e>0).map(([e,s])=>(0,_.jsxs)("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[(0,_.jsx)(Q,{status:e}),(0,_.jsx)("strong",{children:s})]},e))}),0===P.length?(0,_.jsx)(ie,{title:(0,l.__)("No jobs yet","gloty"),hint:(0,l.__)('Jobs appear here after you click "Translate now".',"gloty")}):(0,_.jsxs)(p,{className:"wp-list-table widefat striped",style:{marginBottom:24},children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Status","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Segments","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Correlation","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Created","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Updated","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Diagnostics","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Actions","gloty")})]})}),(0,_.jsx)("tbody",{children:P.map(e=>(0,_.jsxs)("tr",{children:[(0,_.jsx)("td",{children:(0,_.jsx)(Q,{status:e.status})}),(0,_.jsx)("td",{children:te(e.segment_count||0)}),(0,_.jsx)("td",{children:(0,_.jsx)("code",{children:e.correlation_id||"—"})}),(0,_.jsx)("td",{className:"wpshelf-muted",children:ae(e.created_at)}),(0,_.jsx)("td",{className:"wpshelf-muted",children:ae(e.updated_at)}),(0,_.jsx)("td",{children:e.error_message?(0,_.jsx)("span",{className:"wpshelf-sync-diagnostic wpshelf-sync-diagnostic--error",children:e.error_message}):(0,_.jsx)("span",{className:"wpshelf-muted",children:e.remote_job_id?`remote: ${e.remote_job_id}`:(0,l.__)("No errors","gloty")})}),(0,_.jsx)("td",{children:(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:["failed"===e.status&&(0,_.jsx)(f.Button,{variant:"secondary",isSmall:!0,onClick:()=>_e(e,"retry"),disabled:null!==I,isBusy:I===e.id,children:(0,l.__)("Retry","gloty")}),("queued"===e.status||"processing"===e.status)&&(0,_.jsx)(f.Button,{variant:"tertiary",isSmall:!0,onClick:()=>_e(e,"cancel"),disabled:null!==I,isBusy:I===e.id,children:(0,l.__)("Cancel","gloty")})]})})]},e.id))})]}),(0,_.jsxs)("button",{type:"button",className:"wpshelf-collapsible-header",onClick:()=>q(!U),"aria-expanded":U,"aria-controls":"gloty-event-log",children:[(0,_.jsx)("span",{className:"wpshelf-collapsible-header__arrow",children:U?"▾":"▸"}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",style:{margin:0,border:0,padding:0},children:(0,l.__)("Event log","gloty")})]}),U&&(0,_.jsxs)("div",{id:"gloty-event-log",children:[(0,_.jsx)("div",{style:{maxWidth:280,margin:"12px 0"},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Filter by type","gloty"),value:F,options:[{label:(0,l.__)("All types","gloty"),value:""},{label:(0,l.__)("Sync","gloty"),value:"sync.dispatch"},{label:(0,l.__)("Webhook","gloty"),value:"sync.webhook"},{label:(0,l.__)("Translation","gloty"),value:"translation.update"},{label:(0,l.__)("Scan","gloty"),value:"scan.progress"}],onChange:V,__nextHasNoMarginBottom:!0})}),0===G.length?(0,_.jsx)(ie,{title:(0,l.__)("No events yet","gloty"),hint:(0,l.__)("Events appear after scans, syncs, and translation updates.","gloty")}):(0,_.jsxs)(p,{className:"wp-list-table widefat striped",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{scope:"col",children:(0,l.__)("When","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Type","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Message","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Context","gloty")})]})}),(0,_.jsx)("tbody",{children:G.map(e=>(0,_.jsxs)("tr",{children:[(0,_.jsx)("td",{className:"wpshelf-muted",children:ae(e.created_at)}),(0,_.jsx)("td",{children:(0,_.jsx)("code",{children:e.type})}),(0,_.jsx)("td",{children:e.message}),(0,_.jsx)("td",{className:"wpshelf-muted",children:Ae(e)})]},e.id))})]})]}),w&&(0,_.jsx)(re,{title:(0,l.__)("Restart scan?","gloty"),message:(0,l.__)("This starts the scan over from the beginning. Already-discovered strings stay saved — nothing is deleted — but the current run’s progress resets to zero.","gloty"),confirmLabel:(0,l.__)("Restart scan","gloty"),isDestructive:!1,busy:r,onConfirm:()=>{x(!1),ge()},onCancel:()=>x(!1)})]})}var bs=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})}),Ns=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})}),Cs=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z"})});function Ss(e){const s=le(e?.original_text),t=le(e?.translated_text),a=function(e,s,t){return""===e?(0,l.__)("This row has no plain text to use as a term.","gloty"):""===s?(0,l.__)("Translate this row first — there is nothing to promote yet.","gloty"):""===t?(0,l.__)("This row has no target language.","gloty"):e.length>191?(0,l.sprintf)(/* translators: %d: maximum number of characters a glossary term may have. */ /* translators: %d: maximum number of characters a glossary term may have. */ 38 (0,l.__)("Glossary terms are brand and product names, up to %d characters. This row is longer than that.","gloty"),191):""}(s,t,String(e?.target_language||"").trim().toLowerCase());return{eligible:""===a,reason:a,term:s,translated:t,verbatim:""!==s&&s===t}}function ks(e,s=80){return e?e.length>s?e.slice(0,s)+"…":e:"—"}function Ts(e){const s=String(e||"");if(!s)return{label:"—",title:""};const t=s.split(":");if("gloty"===t[0]&&"e"===t[1]){const e=t[2];if("post"===e||"term"===e){const a=t[3],n="post"===e?(0,l.__)("Post","gloty"):(0,l.__)("Term","gloty");let i=t.slice(4).join(":");const r=i.match(/^content:s(\d+)$/);r&&(i=(0,l.sprintf)(/* translators: %s: segment number within a post body */ /* translators: %s: segment number within a post body */ 39 39 (0,l.__)("content, part %s","gloty"),r[1]));let o=a?`${n} #${a}`:n;return i&&(o+=` · ${i}`),{label:o,title:s}}if("option"===e)return{label:(0,l.sprintf)(/* translators: %s: WordPress option name */ /* translators: %s: WordPress option name */ 40 (0,l.__)("Site option: %s","gloty"),t.slice(3).join(":")),title:s}}return"gloty"===t[0]?{label:(0,l.__)("Theme / UI string","gloty"),title:s}:{label:s,title:s}}function Ts({boot:e,filters:s=null}){const t=Le(),[a,i]=(0,n.useState)([]),[r,o]=(0,n.useState)(0),[c,d]=(0,n.useState)(1),[h,g]=(0,n.useState)(1),[p,f]=(0,n.useState)(!0),[w,x]=(0,n.useState)(null),[v,j]=(0,n.useState)(()=>s?.target_language||""),[b,N]=(0,n.useState)(()=>s?.status||""),[S,k]=(0,n.useState)(()=>s?.stale||""),[B,E]=(0,n.useState)(()=>s?.echoed||""),[L,M]=(0,n.useState)(""),[A,D]=(0,n.useState)(""),[R,O]=(0,n.useState)(null),[P,$]=(0,n.useState)(null),[I,H]=(0,n.useState)(""),[G,z]=(0,n.useState)(!1),[F,V]=(0,n.useState)(()=>new Set),[U,q]=(0,n.useState)(!1),[W,X]=(0,n.useState)(null),[Y,Z]=(0,n.useState)(null),[J,Q]=(0,n.useState)(""),[oe,de]=(0,n.useState)(!1),he=(0,n.useRef)(null),ge=(0,n.useMemo)(()=>{const s=e?.language?.active||[],t=e?.language?.default||"en";return s.filter(e=>e!==t)},[e]),ue=(0,n.useMemo)(()=>[{label:(0,l.__)("All languages","gloty"),value:""},...ge.map(e=>{const s=Qe(e);return{label:s?.native_name?`${s.native_name} (${e})`:e,value:e}})],[ge]),_e=(0,n.useCallback)(async()=>{f(!0),x(null),V(new Set);try{const e=function({page:e,perPage:s,langFilter:t="",statusFilter:a="",staleFilter:l="",searchQuery:n="",echoedFilter:i=""}){const r=new URLSearchParams({page:String(e),per_page:String(s)});return t&&r.set("target_language",t),"1"===i?(r.set("echoed","1"),r):(a&&r.set("status",a),l&&r.set("stale",l),n&&r.set("search",n),r)}({page:h,perPage:25,langFilter:v,statusFilter:b,staleFilter:S,searchQuery:L,echoedFilter:B}),s=await m()({path:`/gloty/v1/translations?${e}`,parse:!0});i(s.items||[]),o(s.total||0),d(s.total_pages||1)}catch(e){x(e?.message||(0,l.__)("Failed to load translations.","gloty"))}finally{f(!1)}},[h,v,b,S,L,B]);(0,n.useEffect)(()=>{_e()},[_e]),(0,n.useEffect)(()=>{s&&(j(s.target_language||""),N(s.status||""),k(s.stale||""),E(s.echoed||""),D(""),M(""),g(1))},[s]),(0,n.useEffect)(()=>{!p&&0===a.length&&h>1&&h>c&&g(Math.max(1,c))},[p,a.length,h,c]),(0,n.useEffect)(()=>{if(A===L)return;const e=window.setTimeout(()=>{M(A),g(1)},400);return()=>window.clearTimeout(e)},[A,L]);const pe=(0,n.useMemo)(()=>a.map(e=>Number(e.id)),[a]),ye=pe.length>0&&pe.every(e=>F.has(e)),fe=!ye&&pe.some(e=>F.has(e)),we=()=>V(new Set),xe=e=>{Z(Number(e.id)),Q(e.translated_text||""),window.requestAnimationFrame(()=>{he.current&&he.current.focus()})},ve=async()=>{if(!Y)return;const e=a.find(e=>Number(e.id)===Y);if(e&&J===(e.translated_text||""))Z(null);else if(""!==J){if(!oe){de(!0);try{await m()({path:`/gloty/v1/translations/${Y}`,method:"POST",data:{translated_text:J}}),t.success((0,l.__)("Translation saved.","gloty")),Z(null),await _e()}catch(e){t.error(e?.message||(0,l.__)("Failed to save.","gloty"))}finally{de(!1)}}}else je()},je=()=>{Z(null),Q("")};return p&&0===a.length?(0,u.jsx)("div",{className:"wpshelf-screen",children:(0,u.jsx)(ce,{cols:6,rows:6,headers:["",(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Lang","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Actions","gloty")]})}):(0,u.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Translations workspace","gloty"),children:[(0,u.jsx)(ee,{title:(0,l.__)("Translations workspace","gloty"),subtitle:(0,l.__)("Filter, inspect, and curate cached translations. Manual edits are protected from machine overwrite.","gloty")}),w&&(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:w}),"1"===B&&(0,u.jsxs)(y.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mb",children:[(0,l.sprintf)(/* translators: %s: number of rows */ /* translators: %s: number of rows */41 (0,l._n)('Showing the %s row the "identical to its source" warning counts.','Showing the %s rows the "identical to its source" warning counts.',r,"gloty"), se(r))," ",(0,l.__)("These are the rows behind that number, read from the same scan it was counted with — product names, codes and text already written in the target language are already left out. Deleting a row asks for that text to be translated again, which spends your allowance, so read the list before removing anything. Status, staleness and search do not narrow this view.","gloty")]}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsx)(y.CardBody,{children:(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:12,flexWrap:"wrap"},children:[(0,u.jsx)("div",{style:{minWidth:240,flex:"1 1 240px",maxWidth:360},children:(0,u.jsx)(y.SearchControl,{label:(0,l.__)("Search translations","gloty"),value:A,disabled:"1"===B,onChange:D,onKeyDown:e=>{"Enter"===e.key&&(M(A),g(1))},onClose:A?()=>{D(""),M(""),g(1)}:void 0,placeholder:(0,l.__)("Search source or translated text…","gloty"),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{minWidth:160},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Target language","gloty"),value:v,options:ue,onChange:e=>{j(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{minWidth:160},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Status","gloty"),value:b,options:[{label:(0,l.__)("All statuses","gloty"),value:""},{label:(0,l.__)("Translated (synced or edited)","gloty"),value:"translated"},{label:(0,l.__)("Synced","gloty"),value:"auto"},{label:(0,l.__)("Manually edited","gloty"),value:"manual"},{label:(0,l.__)("Pending","gloty"),value:"pending"},{label:(0,l.__)("Processing","gloty"),value:"processing"}],disabled:"1"===B,onChange:e=>{N(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{minWidth:160},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Stale","gloty"),value:S,options:[{label:(0,l.__)("All","gloty"),value:""},{label:(0,l.__)("Stale only","gloty"),value:"1"},{label:(0,l.__)("Fresh only","gloty"),value:"0"}],disabled:"1"===B,onChange:e=>{k(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{minWidth:200},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Flagged","gloty"),value:B,help:"1"===B?(0,l.__)("The rows the Overview warning counts.","gloty"):void 0,options:[{label:(0,l.__)("Not filtered","gloty"),value:""},{label:(0,l.__)("Identical to its source","gloty"),value:"1"}],onChange:e=>{E(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{display:"flex",alignItems:"flex-end",marginLeft:"auto"},children:(0,u.jsxs)("span",{className:"wpshelf-muted",children:[se(r)," ",(0,l.__)("rows","gloty")]})})]})})}),F.size>0&&(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsx)(y.CardBody,{children:(0,u.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{alignItems:"center"},children:[(0,u.jsx)("span",{children:(0,l.sprintf)(/* translators: %d: number of rows currently selected */ /* translators: %d: number of rows currently selected */42 (0,l.__)("%d selected","gloty"),F.size)}),(0, u.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{const e=Array.from(F);if(0!==e.length){q(!0);try{const s=await m()({path:"/gloty/v1/translations/dispatch-selected",method:"POST",data:{ids:e,mode:"dispatch"}}),a=s?.dispatch?.stage||null,n=!!s?.dispatch?.created;let i;i="not_connected"===a?(0,l.__)("Re-queued — but the translator service is not connected yet.","gloty"):"quota_exceeded"===a?(0,l.__)("Re-queued — but your character quota is exhausted. Upgrade your plan to dispatch.","gloty"):n?(0,l.sprintf)(/* translators: %d: number of translation rows re-queued */ /* translators: %d: number of translation rows re-queued */40 (0,l.__)("Site option: %s","gloty"),t.slice(3).join(":")),title:s}}return"gloty"===t[0]?{label:(0,l.__)("Theme / UI string","gloty"),title:s}:{label:s,title:s}}function Bs({boot:e,filters:s=null}){const t=Me(),[a,i]=(0,n.useState)([]),[r,o]=(0,n.useState)(0),[c,d]=(0,n.useState)(1),[h,g]=(0,n.useState)(1),[u,m]=(0,n.useState)(!0),[w,x]=(0,n.useState)(null),[v,j]=(0,n.useState)(()=>s?.target_language||""),[b,N]=(0,n.useState)(()=>s?.status||""),[C,k]=(0,n.useState)(()=>s?.stale||""),[T,E]=(0,n.useState)(()=>s?.echoed||""),[L,M]=(0,n.useState)(""),[A,D]=(0,n.useState)(""),[R,O]=(0,n.useState)(null),[P,$]=(0,n.useState)(null),[I,H]=(0,n.useState)(""),[G,z]=(0,n.useState)(!1),[F,V]=(0,n.useState)(()=>new Set),[U,q]=(0,n.useState)(!1),[W,X]=(0,n.useState)(null),[Y,Z]=(0,n.useState)(null),[J,K]=(0,n.useState)(""),[ee,ce]=(0,n.useState)(!1),he=(0,n.useRef)(null),ge=(0,n.useMemo)(()=>{const s=e?.language?.active||[],t=e?.language?.default||"en";return s.filter(e=>e!==t)},[e]),ue=(0,n.useMemo)(()=>[{label:(0,l.__)("All languages","gloty"),value:""},...ge.map(e=>{const s=es(e);return{label:s?.native_name?`${s.native_name} (${e})`:e,value:e}})],[ge]),_e=(0,n.useCallback)(async()=>{m(!0),x(null),V(new Set);try{const e=function({page:e,perPage:s,langFilter:t="",statusFilter:a="",staleFilter:l="",searchQuery:n="",echoedFilter:i=""}){const r=new URLSearchParams({page:String(e),per_page:String(s)});return t&&r.set("target_language",t),"1"===i?(r.set("echoed","1"),r):(a&&r.set("status",a),l&&r.set("stale",l),n&&r.set("search",n),r)}({page:h,perPage:25,langFilter:v,statusFilter:b,staleFilter:C,searchQuery:L,echoedFilter:T}),s=await y()({path:`/gloty/v1/translations?${e}`,parse:!0});i(s.items||[]),o(s.total||0),d(s.total_pages||1)}catch(e){x(e?.message||(0,l.__)("Failed to load translations.","gloty"))}finally{m(!1)}},[h,v,b,C,L,T]);(0,n.useEffect)(()=>{_e()},[_e]),(0,n.useEffect)(()=>{s&&(j(s.target_language||""),N(s.status||""),k(s.stale||""),E(s.echoed||""),D(""),M(""),g(1))},[s]),(0,n.useEffect)(()=>{!u&&0===a.length&&h>1&&h>c&&g(Math.max(1,c))},[u,a.length,h,c]),(0,n.useEffect)(()=>{if(A===L)return;const e=window.setTimeout(()=>{M(A),g(1)},400);return()=>window.clearTimeout(e)},[A,L]);const pe=(0,n.useMemo)(()=>a.map(e=>Number(e.id)),[a]),me=pe.length>0&&pe.every(e=>F.has(e)),fe=!me&&pe.some(e=>F.has(e)),we=()=>V(new Set),xe=e=>{Z(Number(e.id)),K(e.translated_text||""),window.requestAnimationFrame(()=>{he.current&&he.current.focus()})},ve=async()=>{if(!Y)return;const e=a.find(e=>Number(e.id)===Y);if(e&&J===(e.translated_text||""))Z(null);else if(""!==J){if(!ee){ce(!0);try{await y()({path:`/gloty/v1/translations/${Y}`,method:"POST",data:{translated_text:J}}),t.success((0,l.__)("Translation saved.","gloty")),Z(null),await _e()}catch(e){t.error(e?.message||(0,l.__)("Failed to save.","gloty"))}finally{ce(!1)}}}else je()},je=()=>{Z(null),K("")};return u&&0===a.length?(0,_.jsx)("div",{className:"wpshelf-screen",children:(0,_.jsx)(de,{cols:6,rows:6,headers:["",(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Lang","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Actions","gloty")]})}):(0,_.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Translations workspace","gloty"),children:[(0,_.jsx)(se,{title:(0,l.__)("Translations workspace","gloty"),subtitle:(0,l.__)("Filter, inspect, and curate cached translations. Manual edits are protected from machine overwrite.","gloty")}),w&&(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:w}),"1"===T&&(0,_.jsxs)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mb",children:[(0,l.sprintf)(/* translators: %s: number of rows */ /* translators: %s: number of rows */ 41 (0,l._n)('Showing the %s row the "identical to its source" warning counts.','Showing the %s rows the "identical to its source" warning counts.',r,"gloty"),te(r))," ",(0,l.__)("These are the rows behind that number, read from the same scan it was counted with — product names, codes and text already written in the target language are already left out. Deleting a row asks for that text to be translated again, which spends your allowance, so read the list before removing anything. Status, staleness and search do not narrow this view.","gloty")]}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsx)(f.CardBody,{children:(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:12,flexWrap:"wrap"},children:[(0,_.jsx)("div",{style:{minWidth:240,flex:"1 1 240px",maxWidth:360},children:(0,_.jsx)(f.SearchControl,{label:(0,l.__)("Search translations","gloty"),value:A,disabled:"1"===T,onChange:D,onKeyDown:e=>{"Enter"===e.key&&(M(A),g(1))},onClose:A?()=>{D(""),M(""),g(1)}:void 0,placeholder:(0,l.__)("Search source or translated text…","gloty"),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{minWidth:160},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Target language","gloty"),value:v,options:ue,onChange:e=>{j(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{minWidth:160},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Status","gloty"),value:b,options:[{label:(0,l.__)("All statuses","gloty"),value:""},{label:(0,l.__)("Translated (synced or edited)","gloty"),value:"translated"},{label:(0,l.__)("Synced","gloty"),value:"auto"},{label:(0,l.__)("Manually edited","gloty"),value:"manual"},{label:(0,l.__)("Pending","gloty"),value:"pending"},{label:(0,l.__)("Processing","gloty"),value:"processing"}],disabled:"1"===T,onChange:e=>{N(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{minWidth:160},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Stale","gloty"),value:C,options:[{label:(0,l.__)("All","gloty"),value:""},{label:(0,l.__)("Stale only","gloty"),value:"1"},{label:(0,l.__)("Fresh only","gloty"),value:"0"}],disabled:"1"===T,onChange:e=>{k(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{minWidth:200},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Flagged","gloty"),value:T,help:"1"===T?(0,l.__)("The rows the Overview warning counts.","gloty"):void 0,options:[{label:(0,l.__)("Not filtered","gloty"),value:""},{label:(0,l.__)("Identical to its source","gloty"),value:"1"}],onChange:e=>{E(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{display:"flex",alignItems:"flex-end",marginLeft:"auto"},children:(0,_.jsxs)("span",{className:"wpshelf-muted",children:[te(r)," ",(0,l.__)("rows","gloty")]})})]})})}),F.size>0&&(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsx)(f.CardBody,{children:(0,_.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{alignItems:"center"},children:[(0,_.jsx)("span",{children:(0,l.sprintf)(/* translators: %d: number of rows currently selected */ /* translators: %d: number of rows currently selected */ 42 (0,l.__)("%d selected","gloty"),F.size)}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{const e=Array.from(F);if(0!==e.length){q(!0);try{const s=await y()({path:"/gloty/v1/translations/dispatch-selected",method:"POST",data:{ids:e,mode:"dispatch"}}),a=s?.dispatch?.stage||null,n=!!s?.dispatch?.created;let i;i="not_connected"===a?(0,l.__)("Re-queued — but the translator service is not connected yet.","gloty"):"quota_exceeded"===a?(0,l.__)("Re-queued — but your character quota is exhausted. Upgrade your plan to dispatch.","gloty"):n?(0,l.sprintf)(/* translators: %d: number of translation rows re-queued */ /* translators: %d: number of translation rows re-queued */ 43 43 (0,l.__)("%d translation(s) re-queued and dispatched.","gloty"),s?.queued||e.length):(0,l.sprintf)(/* translators: %d: number of translation rows re-queued */ /* translators: %d: number of translation rows re-queued */ 44 (0,l.__)("%d translation(s) re-queued. Dispatch will pick them up on the next run.","gloty"),s?.queued||e.length),"not_connected"===a||"quota_exceeded"===a?t.info(i):t.success(i),we(),await _e()}catch(e){t.error(e?.message||(0,l.__)("Bulk translate failed.","gloty"))}finally{q(!1)}}},isBusy:U,disabled:U,children:(0,l.__)("Translate selected","gloty")}),(0, u.jsx)(y.Button,{variant:"secondary",isDestructive:!0,onClick:()=>X({type:"bulk",ids:Array.from(F)}),disabled:U,children:(0,l.__)("Delete selected","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",onClick:we,disabled:U,children:(0,l.__)("Clear","gloty")})]})]})})}),0===a.length?(0,u.jsx)(ne,{title:"1"===B?(0,l.__)("Nothing is flagged as identical to its source. The warning has cleared.","gloty"):(0,l.__)("No translations match these filters.","gloty")}):(0,u.jsxs)(u.Fragment,{children:[0===F.size&&(0,u.jsx)("p",{className:"wpshelf-table-hint wpshelf-muted",children:(0,l.__)("Tip: tick the checkboxes to translate or delete rows in bulk.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-table-wrap",children:(0,u.jsxs)(_,{className:"wp-list-table widefat striped",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("td",{className:"manage-column column-cb check-column",style:{width:32},children:(0,u.jsx)(y.CheckboxControl,{__nextHasNoMarginBottom:!0,checked:ye,indeterminate:fe,onChange:()=>{V(e=>{const s=new Set(e);return ye?pe.forEach(e=>s.delete(e)):pe.forEach(e=>s.add(e)),s})},"aria-label":(0,l.__)("Select all rows on this page","gloty")})}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Pair","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Status","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Original","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Translation","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Context","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Updated","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Actions","gloty")})]})}),(0,u.jsx)("tbody",{children:a.map(e=>{const s=Number(e.id),a=Cs(e);return(0,u.jsxs)("tr",{className:F.has(s)?"is-selected":void 0,children:[(0,u.jsx)("th",{scope:"row",className:"check-column",children:(0,u.jsx)(y.CheckboxControl,{__nextHasNoMarginBottom:!0,checked:F.has(s),onChange:()=>{return e=s,void V(s=>{const t=new Set(s);return t.has(e)?t.delete(e):t.add(e),t});var e},"aria-label":(0,l.sprintf)(/* translators: %d: translation row id */ /* translators: %d: translation row id */45 (0,l.__)("Select translation row %d","gloty"),s)})}),(0, u.jsx)("td",{children:(0,u.jsxs)("code",{children:[e.source_language,"→",e.target_language]})}),(0,u.jsxs)("td",{children:[(0,u.jsx)(K,{status:e.status}),1===Number(e.stale)&&(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--warn",style:{marginLeft:4},children:(0,l.__)("Stale","gloty")})]}),(0,u.jsx)("td",{title:ae(e.original_text)||e.original_text||void 0,children:ae(e.original_text)?Ss(ae(e.original_text),60):(0,u.jsx)("em",{className:"wpshelf-muted",title:(0,l.__)("Structured block content — its source text is captured when this row is sent for translation.","gloty"),children:(0,l.__)("Block content","gloty")})}),(0,u.jsx)("td",{className:"wpshelf-inline-edit-cell",title:Y===s?void 0:le(e.translated_text)||void 0,children:Y===s?(0,u.jsxs)(u.Fragment,{children:[oe&&(0,u.jsx)(re,{label:(0,l.__)("Saving…","gloty")}),(0,u.jsx)("textarea",{ref:he,className:"wpshelf-inline-edit",value:J,readOnly:oe,onChange:e=>Q(e.target.value),onBlur:ve,onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),ve()),"Escape"===e.key&&je()},rows:2})]}):(0,u.jsx)("span",{className:"wpshelf-inline-edit-trigger",onClick:()=>xe(e),role:"button",tabIndex:0,onKeyDown:s=>{"Enter"!==s.key&&" "!==s.key||(s.preventDefault(),xe(e))},children:le(e.translated_text)?Ss(le(e.translated_text),60):(0,u.jsx)("span",{className:"wpshelf-inline-placeholder",children:"pending"===e.status||"processing"===e.status?(0,l.__)("Not translated yet","gloty"):(0,l.__)("Add translation…","gloty")})})}),(0,u.jsx)("td",{title:ks(e.context).title,children:(0,u.jsx)("span",{className:"wpshelf-context-label",children:ks(e.context).label})}),(0,u.jsx)("td",{className:"wpshelf-muted",children:te(e.updated_at)}),(0,u.jsx)("td",{className:"wpshelf-actions-cell",children:(0,u.jsx)("div",{className:"wpshelf-row wpshelf-row-actions",children:(0,u.jsx)(y.DropdownMenu,{icon:js,label:(0,l.__)("Row actions","gloty"),popoverProps:{placement:"bottom-end"},toggleProps:{isSmall:!0,isBusy:R===s,disabled:null!==R||U,"aria-label":(0,l.sprintf)(/* translators: %s: the source text the row holds */ /* translators: %s: the source text the row holds */46 (0,l.__)("Actions for “%s”","gloty"), Ss(ae(e.original_text),40))},children:({onClose:n})=>(0,u.jsxs)(y.MenuGroup,{children:[(0,u.jsx)(y.MenuItem,{icon:bs,onClick:()=>{n(),(e=>{$(e),H(e.translated_text||"")})(e)},children:(0,l.__)("Edit","gloty")}),(0,u.jsx)(y.MenuItem,{icon:C,onClick:()=>{n(),(async e=>{O(e);try{const s=await m()({path:"/gloty/v1/translations/dispatch-selected",method:"POST",data:{ids:[e],mode:"dispatch"}}),a=s?.dispatch?.stage||null,n=!!s?.dispatch?.created;let i;i="not_connected"===a?(0,l.__)("Re-queued — but the translator service is not connected yet.","gloty"):"quota_exceeded"===a?(0,l.__)("Re-queued — but your character quota is exhausted. Upgrade your plan to dispatch.","gloty"):n?(0,l.__)("Re-queued and dispatched. Watch the jobs table for progress.","gloty"):(0,l.__)("Re-queued. It will be dispatched on the next sync run.","gloty"),"not_connected"===a||"quota_exceeded"===a?t.info(i):t.success(i),await _e()}catch(e){t.error(e?.message||(0,l.__)("Translate failed.","gloty"))}finally{O(null)}})(s)},children:(0,l.__)("Translate now","gloty")}),(0,u.jsx)(y.MenuItem,{icon:T,disabled:!a.eligible,info:a.eligible?void 0:a.reason,onClick:()=>{n(),(async e=>{const s=Cs(e);if(!s.eligible)return void t.info(s.reason);const a=Number(e.id);O(a);try{const e=await m()({path:"/gloty/v1/glossary/from-translation",method:"POST",data:{translation_id:a}}),n=e?.promoted?.term||s.term,i=String(e?.promoted?.language||"").toUpperCase();"created"===e?.outcome?t.success(s.verbatim?(0,l.sprintf)(/* translators: %s: the term added to the glossary */ /* translators: %s: the term added to the glossary */44 (0,l.__)("%d translation(s) re-queued. Dispatch will pick them up on the next run.","gloty"),s?.queued||e.length),"not_connected"===a||"quota_exceeded"===a?t.info(i):t.success(i),we(),await _e()}catch(e){t.error(e?.message||(0,l.__)("Bulk translate failed.","gloty"))}finally{q(!1)}}},isBusy:U,disabled:U,children:(0,l.__)("Translate selected","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",isDestructive:!0,onClick:()=>X({type:"bulk",ids:Array.from(F)}),disabled:U,children:(0,l.__)("Delete selected","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",onClick:we,disabled:U,children:(0,l.__)("Clear","gloty")})]})]})})}),0===a.length?(0,_.jsx)(ie,{title:"1"===T?(0,l.__)("Nothing is flagged as identical to its source. The warning has cleared.","gloty"):(0,l.__)("No translations match these filters.","gloty")}):(0,_.jsxs)(_.Fragment,{children:[0===F.size&&(0,_.jsx)("p",{className:"wpshelf-table-hint wpshelf-muted",children:(0,l.__)("Tip: tick the checkboxes to translate or delete rows in bulk.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-table-wrap",children:(0,_.jsxs)(p,{className:"wp-list-table widefat striped",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("td",{className:"manage-column column-cb check-column",style:{width:32},children:(0,_.jsx)(f.CheckboxControl,{__nextHasNoMarginBottom:!0,checked:me,indeterminate:fe,onChange:()=>{V(e=>{const s=new Set(e);return me?pe.forEach(e=>s.delete(e)):pe.forEach(e=>s.add(e)),s})},"aria-label":(0,l.__)("Select all rows on this page","gloty")})}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Pair","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Status","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Original","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Translation","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Context","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Updated","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Actions","gloty")})]})}),(0,_.jsx)("tbody",{children:a.map(e=>{const s=Number(e.id),a=Ss(e);return(0,_.jsxs)("tr",{className:F.has(s)?"is-selected":void 0,children:[(0,_.jsx)("th",{scope:"row",className:"check-column",children:(0,_.jsx)(f.CheckboxControl,{__nextHasNoMarginBottom:!0,checked:F.has(s),onChange:()=>{return e=s,void V(s=>{const t=new Set(s);return t.has(e)?t.delete(e):t.add(e),t});var e},"aria-label":(0,l.sprintf)(/* translators: %d: translation row id */ /* translators: %d: translation row id */ 45 (0,l.__)("Select translation row %d","gloty"),s)})}),(0,_.jsx)("td",{children:(0,_.jsxs)("code",{children:[e.source_language,"→",e.target_language]})}),(0,_.jsxs)("td",{children:[(0,_.jsx)(Q,{status:e.status}),1===Number(e.stale)&&(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--warn",style:{marginLeft:4},children:(0,l.__)("Stale","gloty")})]}),(0,_.jsx)("td",{title:le(e.original_text)||e.original_text||void 0,children:le(e.original_text)?ks(le(e.original_text),60):(0,_.jsx)("em",{className:"wpshelf-muted",title:(0,l.__)("Structured block content — its source text is captured when this row is sent for translation.","gloty"),children:(0,l.__)("Block content","gloty")})}),(0,_.jsx)("td",{className:"wpshelf-inline-edit-cell",title:Y===s?void 0:ne(e.translated_text)||void 0,children:Y===s?(0,_.jsxs)(_.Fragment,{children:[ee&&(0,_.jsx)(oe,{label:(0,l.__)("Saving…","gloty")}),(0,_.jsx)("textarea",{ref:he,className:"wpshelf-inline-edit",value:J,readOnly:ee,onChange:e=>K(e.target.value),onBlur:ve,onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),ve()),"Escape"===e.key&&je()},rows:2})]}):(0,_.jsx)("span",{className:"wpshelf-inline-edit-trigger",onClick:()=>xe(e),role:"button",tabIndex:0,onKeyDown:s=>{"Enter"!==s.key&&" "!==s.key||(s.preventDefault(),xe(e))},children:ne(e.translated_text)?ks(ne(e.translated_text),60):(0,_.jsx)("span",{className:"wpshelf-inline-placeholder",children:"pending"===e.status||"processing"===e.status?(0,l.__)("Not translated yet","gloty"):(0,l.__)("Add translation…","gloty")})})}),(0,_.jsx)("td",{title:Ts(e.context).title,children:(0,_.jsx)("span",{className:"wpshelf-context-label",children:Ts(e.context).label})}),(0,_.jsx)("td",{className:"wpshelf-muted",children:ae(e.updated_at)}),(0,_.jsx)("td",{className:"wpshelf-actions-cell",children:(0,_.jsx)("div",{className:"wpshelf-row wpshelf-row-actions",children:(0,_.jsx)(f.DropdownMenu,{icon:bs,label:(0,l.__)("Row actions","gloty"),popoverProps:{placement:"bottom-end"},toggleProps:{isSmall:!0,isBusy:R===s,disabled:null!==R||U,"aria-label":(0,l.sprintf)(/* translators: %s: the source text the row holds */ /* translators: %s: the source text the row holds */ 46 (0,l.__)("Actions for “%s”","gloty"),ks(le(e.original_text),40))},children:({onClose:n})=>(0,_.jsxs)(f.MenuGroup,{children:[(0,_.jsx)(f.MenuItem,{icon:Ns,onClick:()=>{n(),(e=>{$(e),H(e.translated_text||"")})(e)},children:(0,l.__)("Edit","gloty")}),(0,_.jsx)(f.MenuItem,{icon:S,onClick:()=>{n(),(async e=>{O(e);try{const s=await y()({path:"/gloty/v1/translations/dispatch-selected",method:"POST",data:{ids:[e],mode:"dispatch"}}),a=s?.dispatch?.stage||null,n=!!s?.dispatch?.created;let i;i="not_connected"===a?(0,l.__)("Re-queued — but the translator service is not connected yet.","gloty"):"quota_exceeded"===a?(0,l.__)("Re-queued — but your character quota is exhausted. Upgrade your plan to dispatch.","gloty"):n?(0,l.__)("Re-queued and dispatched. Watch the jobs table for progress.","gloty"):(0,l.__)("Re-queued. It will be dispatched on the next sync run.","gloty"),"not_connected"===a||"quota_exceeded"===a?t.info(i):t.success(i),await _e()}catch(e){t.error(e?.message||(0,l.__)("Translate failed.","gloty"))}finally{O(null)}})(s)},children:(0,l.__)("Translate now","gloty")}),(0,_.jsx)(f.MenuItem,{icon:B,disabled:!a.eligible,info:a.eligible?void 0:a.reason,onClick:()=>{n(),(async e=>{const s=Ss(e);if(!s.eligible)return void t.info(s.reason);const a=Number(e.id);O(a);try{const e=await y()({path:"/gloty/v1/glossary/from-translation",method:"POST",data:{translation_id:a}}),n=e?.promoted?.term||s.term,i=String(e?.promoted?.language||"").toUpperCase();"created"===e?.outcome?t.success(s.verbatim?(0,l.sprintf)(/* translators: %s: the term added to the glossary */ /* translators: %s: the term added to the glossary */ 47 47 (0,l.__)("“%s” added to the glossary — it will be left as written in every language.","gloty"),n):(0,l.sprintf)(/* translators: 1: the term added to the glossary, 2: uppercased language code */ /* translators: 1: the term added to the glossary, 2: uppercased language code */ 48 48 (0,l.__)("“%1$s” added to the glossary, fixed to this translation for %2$s.","gloty"),n,i)):"merged"===e?.outcome?t.success((0,l.sprintf)(/* translators: 1: uppercased language code, 2: the glossary term */ /* translators: 1: uppercased language code, 2: the glossary term */ 49 49 (0,l.__)("%1$s added to the glossary term “%2$s”.","gloty"),i,n)):"conflict"===e?.outcome?t.info((0,l.sprintf)(/* translators: 1: the glossary term, 2: uppercased language code, 3: the value the glossary already holds */ /* translators: 1: the glossary term, 2: uppercased language code, 3: the value the glossary already holds */ 50 50 (0,l.__)("“%1$s” is already in the glossary with a different %2$s value (“%3$s”). Open Glossary to change it.","gloty"),n,i,e?.promoted?.existing||"")):t.info((0,l.sprintf)(/* translators: %s: the glossary term */ /* translators: %s: the glossary term */ 51 (0,l.__)("The glossary already covers “%s” for this language.","gloty"),n))}catch(e){t.error(e?.message||(0,l.__)("Could not add this to the glossary.","gloty"))}finally{O(null)}})(e)},children:(0,l.__)("Add to glossary","gloty")}),(0, u.jsx)(y.MenuItem,{icon:Ns,isDestructive:!0,onClick:()=>{n(),X({type:"single",id:s})},children:(0,l.__)("Delete","gloty")})]})})})})]},s)})})]})}),c>1&&(0,u.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{marginTop:12},children:[(0,u.jsxs)("span",{className:"wpshelf-muted",children:[(0,l.__)("Page","gloty")," ",h," / ",c]}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:4},children:[(0,u.jsxs)(y.Button,{variant:"secondary",isSmall:!0,disabled:h<=1||p,onClick:()=>g(e=>e-1),children:["« ",(0,l.__)("Prev","gloty")]}),(0,u.jsxs)(y.Button,{variant:"secondary",isSmall:!0,disabled:h>=c||p,onClick:()=>g(e=>e+1),children:[(0,l.__)("Next","gloty")," »"]})]})]})]}),P&&(0,u.jsx)(y.Modal,{title:(0,l.__)("Edit translation","gloty"),onRequestClose:()=>$(null),className:"wpshelf-edit-modal",children:(0,u.jsxs)("div",{className:"wpshelf-edit-modal__body",children:[(0,u.jsxs)(y.Card,{className:"wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsxs)("strong",{children:[(0,l.__)("Original","gloty")," (",P.source_language,")"]})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)("pre",{className:"wpshelf-pre",children:P.original_text})})]}),(0,u.jsx)(y.TextareaControl,{label:(0,l.__)("Translation","gloty")+` (${P.target_language})`,value:I,onChange:H,rows:5,__nextHasNoMarginBottom:!0}),I!==(P.translated_text||"")&&(0,u.jsxs)("div",{className:"wpshelf-diff",children:[(0,u.jsx)("span",{className:"wpshelf-diff__label",children:(0,l.__)("Changes","gloty")}),(0,u.jsx)(me,{oldText:P.translated_text||"",newText:I})]}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16,justifyContent:"flex-end"},children:[(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>$(null),children:(0,l.__)("Cancel","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{if(P){z(!0);try{await m()({path:`/gloty/v1/translations/${P.id}`,method:"POST",data:{translated_text:I}}),t.success((0,l.__)("Translation saved.","gloty")),$(null),await _e()}catch(e){t.error(e?.message||(0,l.__)("Failed to save translation.","gloty"))}finally{z(!1)}}},isBusy:G,disabled:G||""===I,children:(0,l.__)("Save","gloty")})]})]})}),W&&(0,u.jsx)(ie,{title:(0,l.__)("Delete translations","gloty"),message:"bulk"===W.type?(0,l.sprintf)(/* translators: %d: number of rows */ /* translators: %d: number of rows */52 (0,l.__)("Delete %d cached translation(s)? They may be regenerated later.","gloty"),W.ids.length):(0,l.__)("Delete this cached translation? It may be generated again later.","gloty"),busy:"bulk"===W.type?U:null!==R,onConfirm:()=>"bulk"===W.type?(async()=>{const e=W?.ids||Array.from(F);if(0!==e.length){q(!0);try{const s=await m()({path:"/gloty/v1/translations/delete-selected",method:"POST",data:{ids:e}});t.success((0,l.sprintf)(/* translators: %d: number of translation rows deleted */ /* translators: %d: number of translation rows deleted */53 (0,l.__)("%d translation(s) deleted.","gloty"),s?.deleted||e.length)),we(),await _e()}catch(e){t.error(e?.message||(0,l.__)("Bulk delete failed.","gloty"))}finally{q(!1),X(null)}}})():(async e=>{O(e);try{await m()({path:`/gloty/v1/translations/${e}`,method:"DELETE"}),t.success((0,l.__)("Translation deleted.","gloty")),await _e()}catch(e){t.error(e?.message||(0,l.__)("Could not delete translation.","gloty"))}finally{O(null),X(null)}})(W.id),onCancel:()=>X(null)})]})}const Bs={dashboard:null,dashboardLoading:!1,dashboardError:null,jobs:null,jobsLoading:!1,languages:null,languagesLoading:!1,routing:null,activity:null,activityLoading:!1,scan:null,onboardingStep:0,pluginSettings:null,pluginSettingsLoading:!1,pluginSettingsError:null},Es=(0,f.createReduxStore)("gloty/admin",{reducer:function(e=Bs,s){switch(s.type){case"RECEIVE_DASHBOARD":return{...e,dashboard:s.payload,dashboardLoading:!1,dashboardError:null};case"DASHBOARD_ERROR":return{...e,dashboardLoading:!1,dashboardError:s.payload};case"DASHBOARD_LOADING":return{...e,dashboardLoading:!0,dashboardError:null};case"RECEIVE_JOBS":return{...e,jobs:s.payload,jobsLoading:!1};case"JOBS_LOADING":return{...e,jobsLoading:!0};case"RECEIVE_LANGUAGES":return{...e,languages:s.payload,languagesLoading:!1};case"LANGUAGES_LOADING":return{...e,languagesLoading:!0};case"RECEIVE_ROUTING":return{...e,routing:s.payload};case"RECEIVE_ACTIVITY":return{...e,activity:s.payload,activityLoading:!1};case"ACTIVITY_LOADING":return{...e,activityLoading:!0};case"RECEIVE_SCAN":return{...e,scan:s.payload};case"SET_ONBOARDING_STEP":return{...e,onboardingStep:s.payload};case"PLUGIN_SETTINGS_LOADING":return{...e,pluginSettingsLoading:!0,pluginSettingsError:null};case"RECEIVE_PLUGIN_SETTINGS":return{...e,pluginSettings:s.payload,pluginSettingsLoading:!1,pluginSettingsError:null};case"PLUGIN_SETTINGS_ERROR":return{...e,pluginSettingsLoading:!1,pluginSettingsError:s.payload};default:return e}},actions:{receiveDashboard:e=>({type:"RECEIVE_DASHBOARD",payload:e}),dashboardError:e=>({type:"DASHBOARD_ERROR",payload:e}),dashboardLoading:()=>({type:"DASHBOARD_LOADING"}),receiveJobs:e=>({type:"RECEIVE_JOBS",payload:e}),jobsLoading:()=>({type:"JOBS_LOADING"}),receiveLanguages:e=>({type:"RECEIVE_LANGUAGES",payload:e}),languagesLoading:()=>({type:"LANGUAGES_LOADING"}),receiveRouting:e=>({type:"RECEIVE_ROUTING",payload:e}),receiveActivity:e=>({type:"RECEIVE_ACTIVITY",payload:e}),activityLoading:()=>({type:"ACTIVITY_LOADING"}),receiveScan:e=>({type:"RECEIVE_SCAN",payload:e}),setOnboardingStep:e=>({type:"SET_ONBOARDING_STEP",payload:e}),pluginSettingsLoading:()=>({type:"PLUGIN_SETTINGS_LOADING"}),receivePluginSettings:e=>({type:"RECEIVE_PLUGIN_SETTINGS",payload:e}),pluginSettingsError:e=>({type:"PLUGIN_SETTINGS_ERROR",payload:e})},selectors:{getDashboard:e=>e.dashboard,isDashboardLoading:e=>e.dashboardLoading,getDashboardError:e=>e.dashboardError,getJobs:e=>e.jobs,isJobsLoading:e=>e.jobsLoading,getLanguages:e=>e.languages,isLanguagesLoading:e=>e.languagesLoading,getRouting:e=>e.routing,getActivity:e=>e.activity,isActivityLoading:e=>e.activityLoading,getScan:e=>e.scan,getOnboardingStep:e=>e.onboardingStep,getPluginSettings:e=>e.pluginSettings,isPluginSettingsLoading:e=>e.pluginSettingsLoading,getPluginSettingsError:e=>e.pluginSettingsError}});(0,f.register)(Es);const Ls="gloty/admin";function Ms(e){return{gloty:"dashboard","gloty-dashboard":"dashboard","gloty-queue":"sync","gloty-sync":"sync","gloty-translations":"translations","gloty-languages":"languages","gloty-glossary":"glossary","gloty-onboarding":"onboarding","gloty-activity":"sync","gloty-settings":"settings","gloty-billing":"billing","gloty-design-system":"design-system"}[e]||"dashboard"}function As(){if("undefined"==typeof window)return{tab:null,view:null};const e=new URL(window.location.href),s=e.searchParams.get("tab"),t=e.searchParams.get("view");return{tab:s||Ms(e.searchParams.get("page")||"gloty"),view:t||null}}const Ds=[{key:"welcome",label:(0,l.__)("Welcome","gloty")},{key:"connection",label:(0,l.__)("Connection","gloty")},{key:"languages",label:(0,l.__)("Languages","gloty")},{key:"scan",label:(0,l.__)("Content scan","gloty")},{key:"done",label:(0,l.__)("Ready","gloty")}];function Rs({boot:e}){const s=(0,f.useSelect)(e=>e(Ls).getOnboardingStep(),[]),t=e=>(0,f.dispatch)(Ls).setOnboardingStep(e),[a,i]=(0,n.useState)(null),[r,o]=(0,n.useState)(e?.license?.hasKey?"existing":"new"),[c,d]=(0,n.useState)(""),[h,g]=(0,n.useState)(null),[_,p]=(0,n.useState)(null),[w,x]=(0,n.useState)(!1),[v,j]=(0,n.useState)(null),[b,N]=(0,n.useState)(!1),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(null),[B,E]=(0,n.useState)(e?.connection?.accountEmail||""),[L,M]=(0,n.useState)(e?.connection?.accountName||""),A=!!e?.connection?.connected,D=async()=>{x(!0),g(null),p(null);try{const e=await m()({path:"/gloty/v1/onboarding/connect",method:"POST",data:{email:B,name:L,use_existing_license:"existing"===r,license_key:"existing"===r?c.trim():""}});e?.ok?(i(e),d(""),window.dispatchEvent(new Event("gloty-license-refresh"))):(p(e?.stage||"connect"),g(e?.message||(0,l.__)("Could not complete the connection.","gloty")))}catch(e){p("network"),g(e?.message||(0,l.__)("Connection failed","gloty"))}finally{x(!1)}},R=()=>{m()({path:"/gloty/v1/onboarding/complete",method:"POST"}).catch(()=>{})},O=async()=>{N(!0),T(null),S(null);try{const e=await m()({path:"/gloty/v1/onboarding/language-packs",method:"POST"});S(e),!e.can_install&&e.message&&T(e.message)}catch(e){T(e?.message||(0,l.__)("Language pack install failed.","gloty"))}finally{N(!1)}},P=async()=>{x(!0),g(null);try{const e=await m()({path:"/gloty/v1/scan/start",method:"POST",data:{batch_size:20}});j(e),R(),t(4)}catch(e){g(e?.message||(0,l.__)("Scan failed","gloty"))}finally{x(!1)}},$=e?.language?.default||"en",I=(e?.language?.active||[]).filter(e=>e!==$),H=A||!!a?.ok,G=[{key:"connection",title:(0,l.__)("Site connected to Gloty","gloty"),done:H},{key:"languages",title:(0,l.__)("Target languages enabled","gloty"),done:I.length>0},{key:"scan",title:(0,l.__)("Initial content scan started","gloty"),done:!!v||(e?.content?.sourceCount??0)>0}],z=(0,n.useMemo)(()=>{const e=C?.items;if(!C?.can_install||!Array.isArray(e))return null;const s=e.filter(e=>"failed"===e.core).length,t=e.filter(e=>"installed"===e.core).length,a=e.filter(e=>"skipped"===e.core).length,l=e.reduce((e,s)=>e+(s.plugins?.installed?.length||0),0),n=e.reduce((e,s)=>e+(s.plugins?.failed?.length||0),0);return{failed:s,installed:t,skipped:a,total:e.length,pluginsInstalled:l,pluginsFailed:n}},[C]),F=(0,n.useRef)(null);(0,n.useEffect)(()=>{F.current&&F.current.focus()},[s]);const V=Ds[s]?.label||(0,l.__)("Onboarding","gloty");return(0,u.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Onboarding","gloty"),children:[(0,u.jsx)("h2",{ref:F,tabIndex:-1,className:"screen-reader-text","aria-live":"polite",children:(0,l.sprintf)(/* translators: 1: current step, 2: total steps, 3: step label */ /* translators: 1: current step, 2: total steps, 3: step label */54 (0,l.__)("Step %1$d of %2$d: %3$s","gloty"),s+1, Ds.length,V)}),(0,u.jsx)(pe,{items:G}),s<Ds.length-1&&(0,u.jsx)(_e,{steps:Ds,current:s}),(()=>{switch(s){case 0:return(0,u.jsx)(y.Card,{className:"wpshelf-onboard-card",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("h2",{style:{marginTop:0},children:(0,l.__)("Welcome to Gloty","gloty")}),(0,u.jsx)("p",{children:(0,l.__)("Gloty is a privacy-first WordPress translation plugin. Translations are generated by the Gloty service and stored locally in your database, so serving a translated page never calls out.","gloty")}),(0,u.jsx)("p",{children:(0,l.__)("Let's get your site set up in a few quick steps.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-row",style:{marginTop:16},children:(0,u.jsx)(y.Button,{variant:"primary",onClick:()=>t(1),children:(0,l.__)("Get started","gloty")})})]})});case 1:return(0,u.jsxs)(y.Card,{className:"wpshelf-onboard-card",children:[(0,u.jsx)(y.CardHeader,{children:(0,l.__)("Connect your site","gloty")}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Connect this site to your WP Shelf account to generate translations. New customers receive a one-time trial of 50,000 characters, with no payment details required.","gloty")}),!H&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(y.RadioControl,{label:(0,l.__)("Your WP Shelf account","gloty"),selected:r,options:[{label:(0,l.__)("I’m new — start a free trial","gloty"),value:"new"},{label:(0,l.__)("I already have an account or license","gloty"),value:"existing"}],onChange:e=>{o(e),g(null)}}),"existing"===r&&(0,u.jsxs)("div",{className:"wpshelf-mb",children:[(0,u.jsxs)("p",{children:[(0,u.jsx)("a",{href:"https://wp-shelf.com/dashboard/licenses",target:"_blank",rel:"noopener noreferrer",children:(0,l.__)("Copy your license from the WP Shelf dashboard","gloty")}),"."," ",(0,l.__)("Use the email address on that account below.","gloty")]}),(0,u.jsxs)("label",{children:[(0,u.jsx)("div",{children:(0,l.__)("License key","gloty")}),(0,u.jsx)("input",{type:"password",autoComplete:"off",value:c,onChange:e=>d(e.target.value),placeholder:e?.license?.hasKey?(0,l.__)("Saved license will be used","gloty"):"GLOTY-XXXX-XXXX-XXXX-XXXX",style:{width:"100%"}})]})]})]}),H?(0,u.jsx)(y.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.__)("This site is connected to Gloty. You can continue to the next step.","gloty")}):(0,u.jsxs)("div",{className:"wpshelf-grid",style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:12,marginTop:12},children:[(0,u.jsxs)("label",{children:[(0,u.jsx)("div",{children:(0,l.__)("Your email","gloty")}),(0,u.jsx)("input",{type:"email",value:B,onChange:e=>E(e.target.value),autoComplete:"email",required:!0,style:{width:"100%"}})]}),(0,u.jsxs)("label",{children:[(0,u.jsx)("div",{children:(0,l.__)("Your name","gloty")}),(0,u.jsx)("input",{type:"text",value:L,onChange:e=>M(e.target.value),autoComplete:"name",required:!0,style:{width:"100%"}})]})]}),h&&(0,u.jsxs)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:["license"===_?(0,l.__)("Could not connect your license:","gloty")+" ":"register"===_?(0,l.__)("Your license was created, but we couldn't register this site:","gloty")+" ":"",h]}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[!H&&(0,u.jsx)(y.Button,{variant:"primary",onClick:D,isBusy:w,disabled:w||!B.trim()||!L.trim()||"existing"===r&&!e?.license?.hasKey&&!c.trim(),children:w?(0,l.__)("Connecting…","gloty"):"existing"===r?(0,l.__)("Activate license & connect","gloty"):(0,l.__)("Start free trial & connect","gloty")}),(0,u.jsx)(y.Button,{variant:H?"primary":"secondary",onClick:()=>t(2),disabled:w||!H,children:(0,l.__)("Next","gloty")})]})]})]});case 2:return(0,u.jsxs)(y.Card,{className:"wpshelf-onboard-card",children:[(0,u.jsx)(y.CardHeader,{children:(0,l.__)("Language setup","gloty")}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsxs)("p",{children:[(0,l.__)("Your source language is set to:","gloty")," ",(0,u.jsx)("strong",{children:$})]}),I.length>0?(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("p",{children:(0,l.__)("Active target languages:","gloty")}),(0,u.jsx)("div",{className:"wpshelf-row",children:I.map(e=>(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--info",children:e},e))})]}):(0,u.jsx)(y.Notice,{status:"warning",isDismissible:!1,children:(0,l.__)("No target languages enabled yet. Enable them under the Languages tab.","gloty")}),(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:12},children:(0,l.__)("You can always adjust languages later under the Languages tab.","gloty")}),(0,u.jsx)("div",{style:{marginTop:20,marginBottom:12,borderTop:"1px solid var(--wpshelf-line-soft)"}}),(0,u.jsx)("p",{children:(0,l.__)("Install WordPress language packs so core, admin, theme, and plugin strings load translated .mo files for your locales — including JavaScript-rendered blocks like the WooCommerce Cart and Checkout that Gloty cannot translate from page HTML. This uses the same downloads as Settings → General → Site Language.","gloty")}),k&&(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:k}),C?.can_install&&C?.message&&0===C?.items?.length&&(0,u.jsx)(y.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",children:C.message}),z&&z.total>0&&0===z.failed&&(0,u.jsx)(y.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: 1: total locales, 2: newly installed, 3: already on disk */ /* translators: 1: total locales, 2: newly installed, 3: already on disk */55 (0,l.__)("Language packs processed: %1$d locale(s), %2$d installed, %3$d already present.","gloty"),z.total,z.installed,z.skipped)}),z&&z.failed>0&&(0, u.jsx)(y.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: 1: succeeded or skipped count, 2: failed count */ /* translators: 1: succeeded or skipped count, 2: failed count */56 (0,l.__)("Some packs could not be installed (%1$d ok, %2$d failed). Try again or install languages under Settings → General.","gloty"),z.total-z.failed,z.failed)}),z&&z.pluginsInstalled>0&&(0, u.jsx)(y.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: %d: number of plugin language packs installed */ /* translators: %d: number of plugin language packs installed */57 (0,l._n)("Installed %d plugin language pack so block-based screens (e.g. WooCommerce Cart & Checkout) render translated.","Installed %d plugin language packs so block-based screens (e.g. WooCommerce Cart & Checkout) render translated.",z.pluginsInstalled,"gloty"),z.pluginsInstalled)}),(0, u.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,u.jsx)(y.Button,{variant:"tertiary",href:"admin.php?page=gloty-languages&tab=languages",children:(0,l.__)("Open Languages","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>t(1),children:(0,l.__)("Back","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:O,isBusy:b,disabled:b,children:(0,l.__)("Install WordPress language packs","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:()=>t(3),disabled:0===I.length,children:(0,l.__)("Next","gloty")})]})]})]});case 3:return(0,u.jsxs)(y.Card,{className:"wpshelf-onboard-card",children:[(0,u.jsx)(y.CardHeader,{children:(0,l.__)("Content scan","gloty")}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{children:(0,l.__)("A content scan registers your existing posts and pages for translation. You can run a quick scan now or do it later from the Sync tab.","gloty")}),h&&(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:h}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>t(2),children:(0,l.__)("Back","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:P,isBusy:w,disabled:w,children:(0,l.__)("Start scan now","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>{R(),t(4)},children:(0,l.__)("Skip for now","gloty")})]})]})]});case 4:return(0,u.jsx)(y.Card,{className:"wpshelf-onboard-card",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("h2",{style:{marginTop:0},children:(0,l.__)("You're all set!","gloty")}),(0,u.jsx)("p",{children:(0,l.__)("Gloty is configured and ready to translate. Visit your site with a language prefix to start capturing template strings, or use the Sync tab to scan content and generate translations.","gloty")}),v&&(0,u.jsx)(y.Notice,{status:"success",isDismissible:!1,children:(0,l.__)("Content scan started successfully.","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,u.jsx)(y.Button,{variant:"primary",href:"admin.php?page=gloty",children:(0,l.__)("Go to Dashboard","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",href:"admin.php?page=gloty-sync&tab=sync",children:(0,l.__)("View sync status","gloty")})]}),(0,u.jsxs)("div",{className:"wpshelf-role-handoff",children:[(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Next actions by role","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-role-grid",children:[(0,u.jsx)(y.Card,{children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("strong",{children:(0,l.__)("Site owner","gloty")}),(0,u.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Confirm provider limits and monitor queue and processing health.","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",href:"admin.php?page=gloty-sync&tab=sync&view=workspace",children:(0,l.__)("Open Sync workspace","gloty")})]})}),(0,u.jsx)(y.Card,{children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("strong",{children:(0,l.__)("Content manager","gloty")}),(0,u.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Review stale rows first and manually improve priority translations.","gloty")}),(0,u.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("They do not need an administrator account — under Settings you can let a role correct translations, optionally in one language only.","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",href:"admin.php?page=gloty-translations&tab=translations&view=workspace",children:(0,l.__)("Open Translations","gloty")})]})}),(0,u.jsx)(y.Card,{children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("strong",{children:(0,l.__)("Developer","gloty")}),(0,u.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Validate language packs, route prefixes, and switcher behavior on frontend pages.","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",href:"admin.php?page=gloty-languages&tab=languages&view=languages",children:(0,l.__)("Open Languages","gloty")})]})})]})]})]})});default:return null}})()]})}const Os=[{key:"capture",label:(0,l.__)("Collected","gloty"),tab:"sync",hint:(0,l.__)("Strings found on your site. Opens the content scan.","gloty")},{key:"queued",label:(0,l.__)("Queued","gloty"),tab:"sync",hint:(0,l.__)("Waiting to be sent. Opens the sync queue.","gloty")},{key:"dispatch",label:(0,l.__)("Sent","gloty"),tab:"sync",hint:(0,l.__)("In flight to the translator. Opens the job list.","gloty")},{key:"processing",label:(0,l.__)("Translating","gloty"),tab:"translations",filters:{status:"processing"},hint:(0,l.__)("Opens these rows in the translations table.","gloty")},{key:"completed",label:(0,l.__)("Done","gloty"),hint:(0,l.__)("Distinct strings finished in each language you have enabled — counted once per language, so it is smaller than the number of rows in the translations table.","gloty")},{key:"stale",label:(0,l.__)("Out of date","gloty"),tab:"translations",filters:{stale:"1"},hint:(0,l.__)("Opens the translations whose source text has changed.","gloty")}],Ps={auto:(0,l.__)("Show synced translations","gloty"),manual:(0,l.__)("Show manually edited translations","gloty"),pending:(0,l.__)("Show translations waiting to be sent","gloty"),processing:(0,l.__)("Show translations in progress","gloty")};function $s({boot:e,onNavigate:s}){const t=Le(),[a,i]=(0,n.useState)(!1),[r,o]=(0,n.useState)(!1),c=(0,f.useSelect)(e=>e(Ls).getDashboard(),[]),d=(0,f.useSelect)(e=>e(Ls).isDashboardLoading(),[]),h=(0,f.useSelect)(e=>e(Ls).getDashboardError(),[]),g=(0,n.useCallback)(async()=>{(0,f.dispatch)(Ls).dashboardLoading();try{const e=await m()({path:"/gloty/v1/dashboard",parse:!0});(0,f.dispatch)(Ls).receiveDashboard(e)}catch(e){(0,f.dispatch)(Ls).dashboardError(e?.message||(0,l.__)("Failed to load dashboard","gloty"))}},[]);(0,n.useEffect)(()=>{g()},[g]);const p=(0,n.useCallback)(async()=>{o(!0);try{const e=await m()({path:"/gloty/v1/maintenance/purge-stale-translations",method:"POST",data:{limit:5e3}}),s=Number(e?.removed||0),a=Number(e?.remaining||0);0===s?t.info((0,l.__)("Nothing was out of date.","gloty")):t.success(a>0?(0,l.sprintf)(/* translators: 1: rows removed, 2: rows still out of date */ /* translators: 1: rows removed, 2: rows still out of date */58 (0,l.__)("%1$s out-of-date translations removed and re-queued. %2$s still to go — run it again.","gloty"), se(s),se(a)):(0,l.sprintf)(/* translators: %s: number of rows removed */ /* translators: %s: number of rows removed */59 (0,l.__)("%s out-of-date translations removed and re-queued for translation.","gloty"), se(s))),await g()}catch(e){t.error(e?.message||(0,l.__)("Could not remove the out-of-date entries.","gloty"))}finally{o(!1),i(!1)}},[g,t]);if(d&&!c)return(0,u.jsxs)("div",{className:"wpshelf-screen",children:[(0,u.jsx)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[0,1,2].map(e=>(0,u.jsx)(y.Card,{className:"wpshelf-stat",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("span",{className:"wpshelf-shimmer",style:{width:"40%",height:12,marginBottom:10}}),(0,u.jsx)("span",{className:"wpshelf-shimmer",style:{width:"30%",height:28,marginBottom:8}}),(0,u.jsx)("span",{className:"wpshelf-shimmer",style:{width:"60%",height:12}})]})},e))}),(0,u.jsx)(ce,{cols:5,rows:4,headers:[(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Lang","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Updated","gloty")]})]});if(h)return(0,u.jsx)("div",{className:"wpshelf-screen",children:(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,children:h})});if(!c)return(0,u.jsx)(ne,{icon:"\\uD83D\\uDCCA",title:(0,l.__)("No data yet","gloty"),hint:(0,l.__)("Visit the front end in a target language to register template strings, or use the Sync tab to scan your content.","gloty")});const w=c.overview||{},x=c.status_breakdown||{},v=w.status_model||{},j=c.language_progress||[],b=(x.auto||0)+(x.manual||0)+(x.pending||0)+(x.processing||0),N=w.source_count??w.total_strings??0,C=w.translated_count??(x.auto||0)+(x.manual||0),S=w.pending_count??0,k=w.stale_count??0,T=w.target_languages??Math.max(0,(w.languages_active??1)-1),B=w.characters_per_language??0,E=w.characters_all_languages??B*T,L=w.expected_translations??N*Math.max(1,T),M={source:0===N?[{label:(0,l.__)("Scan content for strings","gloty"),tab:"sync"}]:[{label:(0,l.__)("Browse strings","gloty"),tab:"translations"}],translated:0===C?[{label:(0,l.__)("Start your first translation","gloty"),tab:"sync"}]:[{label:(0,l.__)("Review translations","gloty"),tab:"translations",filters:{status:"translated"}},{label:(0,l.__)("Review manual edits","gloty"),tab:"translations",filters:{status:"manual"}}],pending:S>0?[{label:(0,l.__)("Translate pending","gloty"),tab:"sync",prominent:!0},{label:(0,l.__)("View pending rows","gloty"),tab:"translations",filters:{status:"pending"}}]:null,stale:k>0?[{label:(0,l.__)("Re-sync out-of-date items","gloty"),tab:"sync"},{label:(0,l.__)("Review out-of-date rows","gloty"),tab:"translations",filters:{stale:"1"}}]:null,languages:0===T?[{label:(0,l.__)("Add a target language","gloty"),tab:"languages"}]:[{label:(0,l.__)("Manage languages","gloty"),tab:"languages"}]},A=e=>{const t=(Array.isArray(e)?e:[e]).filter(Boolean);return 0!==t.length&&s?(0,u.jsx)("div",{className:"wpshelf-stat-grid__cta"+(t.some(e=>e.prominent)?" wpshelf-stat-grid__cta--prominent":""),children:t.map(e=>(0,u.jsxs)(y.Button,{variant:e.prominent?"secondary":"link",onClick:()=>s(e.tab,e.filters||null),children:[e.label," →"]},e.label))}):null},D=e=>({template_string:(0,l.__)("theme & UI (unique gettext strings seen on localized pages)","gloty"),post_field:(0,l.__)("post / page segments (title, excerpt, each translatable block slice)","gloty"),term_field:(0,l.__)("taxonomy name & description","gloty")}[e]??e);return(0,u.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Dashboard","gloty"),children:[(0,u.jsx)(We,{boot:e,onNavigate:s}),(0,u.jsx)(Ye,{hasLanguages:T>0,hasSource:N>0,hasTranslated:C>0,pendingCount:S,onNavigate:s}),(0,u.jsx)(os,{onNavigate:s}),(0,u.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--translated",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Translated","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:se(C)}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:0===N?(0,l.__)("no content captured yet","gloty"):0===T?(0,l.__)("add a target language to begin","gloty"):(0,l.sprintf)(/* translators: 1: total expected translations (strings × languages), 2: number of target languages */ /* translators: 1: total expected translations (strings × languages), 2: number of target languages */60 (0,l._n)("of %1$s translation in %2$d language","of %1$s translations across %2$d languages",T,"gloty"),L.toLocaleString(),T)}),A(M.translated)]})}),(0, u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--pending",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Pending","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:se(S)}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:S>0?(0,l.__)("strings waiting to be translated","gloty"):(0,l.__)("queue is clear","gloty")}),A(M.pending)]})}),(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--stale",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Out of date","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:se(k)}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:k>0?(0,l.__)("source content changed","gloty"):(0,l.__)("all in sync","gloty")}),A(M.stale)]})})]}),(0,u.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--supporting",children:[(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--source",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Source strings","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value wpshelf-stat__value--medium",children:se(N)}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("every translatable text snippet found on your site","gloty")}),B>0&&(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:T>0?(0,l.sprintf)(/* translators: 1: characters in the site, 2: characters needed for every active language */ /* translators: 1: characters in the site, 2: characters needed for every active language */61 (0,l.__)("%1$s characters of source text — about %2$s to translate into every language you have enabled","gloty"), se(B),se(E)):(0,l.sprintf)(/* translators: %s: characters in the site */ /* translators: %s: characters in the site */62 (0,l.__)("%s characters of source text — this is what a language costs to add","gloty"), se(B))}),w.registry_by_source_kind&&Object.keys(w.registry_by_source_kind).length>0&&(0,u.jsx)("ul",{className:"wpshelf-stat__breakdown",children:Object.entries(w.registry_by_source_kind).map(([e,s])=>(0,u.jsxs)("li",{children:[(0,u.jsx)("strong",{children:se(s)})," ",D(e)]},e))}),A(M.source)]})}),(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--languages",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Target languages","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value wpshelf-stat__value--medium",children:T}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:T>0?(0,l.sprintf)(/* translators: %s: source language code */ /* translators: %s: source language code */63 (0,l.__)("alongside %s as source","gloty"),(e?.language?.default||"en").toUpperCase()):(0,l.__)("no target languages enabled","gloty")}),A(M.languages)]})})]}),(0, u.jsxs)("div",{className:"wpshelf-content-boxes",children:[b>0&&(0,u.jsxs)(y.Card,{className:"wpshelf-content-box",children:[(0,u.jsxs)(y.CardHeader,{children:[(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Translation status","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:[k>0&&(0,u.jsx)(y.Button,{variant:"tertiary",size:"small",isDestructive:!0,onClick:()=>i(!0),disabled:r,isBusy:r,children:r?(0,l.__)("Removing…","gloty"):(0,l.__)("Remove out-of-date","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",size:"small",onClick:g,disabled:d,isBusy:d,"aria-live":"polite",children:d?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]})]}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-row",style:{gap:24},children:Object.entries(x).map(([e,t])=>Ps[e]&&s?(0,u.jsxs)("button",{type:"button",className:"wpshelf-status-link",title:Ps[e],onClick:()=>s("translations",{status:e}),children:[(0,u.jsx)(K,{status:e}),(0,u.jsx)("span",{className:"wpshelf-status-link__value",children:se(t)})]},e):(0,u.jsxs)("div",{className:"wpshelf-status-link wpshelf-status-link--static",children:[(0,u.jsx)(K,{status:e}),(0,u.jsx)("span",{className:"wpshelf-status-link__value",children:se(t)})]},e))}),Object.keys(v).length>0&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{margin:"16px 0 8px"},children:(0,l.__)("Each string moves through these stages: Collected → Queued → Sent → Translating → Done.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-row",style:{gap:10},children:Os.map(e=>{const t=se(v[e.key]??0);return s&&e.tab?(0,u.jsxs)("button",{type:"button",className:"wpshelf-pipeline-chip wpshelf-pipeline-chip--link",title:e.hint,onClick:()=>s(e.tab,e.filters||null),children:[(0,u.jsx)("span",{className:"wpshelf-pipeline-chip__label",children:e.label}),(0,u.jsx)("strong",{className:"wpshelf-pipeline-chip__value",children:t})]},e.key):(0,u.jsxs)("div",{className:"wpshelf-pipeline-chip",title:e.hint,children:[(0,u.jsx)("span",{className:"wpshelf-pipeline-chip__label",children:e.label}),(0,u.jsx)("strong",{className:"wpshelf-pipeline-chip__value",children:t})]},e.key)})})]})]})]}),j.length>0&&(0,u.jsxs)(y.Card,{className:"wpshelf-content-box",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Language progress","gloty")})}),(0,u.jsx)(y.CardBody,{children:j.map(e=>(0,u.jsxs)("div",{style:{marginBottom:8},children:[(0,u.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{marginBottom:2},children:[(0,u.jsxs)("span",{style:{fontSize:13,fontWeight:500},children:[e.native_name||e.name," ",(0,u.jsxs)("span",{className:"wpshelf-muted",children:["(",e.code,")"]})]}),(0,u.jsxs)("span",{className:"wpshelf-muted",children:[se(e.translated),"/",se(e.total)]})]}),(0,u.jsx)(ue,{value:e.translated,max:e.total,label:`${e.percentage}%`,scale:"completion"})]},e.code))})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-content-box",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Recent translations","gloty")})}),(0,u.jsx)(y.CardBody,{children:0===(c.recent||[]).length?(0,u.jsx)(ne,{title:(0,l.__)("No translation rows yet","gloty"),hint:(0,l.__)("Visit the front end in a target language to register template strings.","gloty")}):(0,u.jsxs)(_,{className:"wp-list-table widefat striped",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{children:(0,l.__)("Original","gloty")}),(0,u.jsx)("th",{children:(0,l.__)("Translated","gloty")}),(0,u.jsx)("th",{children:(0,l.__)("Lang","gloty")}),(0,u.jsx)("th",{children:(0,l.__)("Status","gloty")}),(0,u.jsx)("th",{children:(0,l.__)("Updated","gloty")})]})}),(0,u.jsx)("tbody",{children:c.recent.map(e=>(0,u.jsxs)("tr",{children:[(0,u.jsx)("td",{title:ae(e.original)||void 0,children:ae(e.original)?ae(e.original).slice(0,80):(0,u.jsx)("em",{className:"wpshelf-muted",title:(0,l.__)("Structured block content — its text is captured when the block is sent for translation.","gloty"),children:(0,l.__)("Block content","gloty")})}),(0,u.jsx)("td",{title:le(e.translated)||void 0,children:le(e.translated)?le(e.translated).slice(0,80):(0,u.jsx)("span",{className:"wpshelf-muted",children:"pending"===e.status||"processing"===e.status?(0,l.__)("Not translated yet","gloty"):"—"})}),(0,u.jsx)("td",{children:(0,u.jsx)("code",{children:e.language_code})}),(0,u.jsx)("td",{children:(0,u.jsx)(K,{status:e.status})}),(0,u.jsx)("td",{className:"wpshelf-muted",children:te(e.updated_at)})]},e.id))})]})})]})]}),a&&(0,u.jsx)(ie,{title:(0,l.__)("Remove out-of-date entries?","gloty"),message:(0,l.sprintf)(/* translators: %s: number of out-of-date translations */ /* translators: %s: number of out-of-date translations */64 (0,l.__)("%s translations are of source text that has since changed. Removing them puts those strings back in the queue, so the next sync translates them again — which spends quota. Until it runs, visitors see the original text for those strings. Manual edits of changed content are removed too.","gloty"), se(k)),confirmLabel:(0,l.__)("Remove and re-queue","gloty"),busy:r,onConfirm:p,onCancel:()=>i(!1)})]})}function Is({boot:e}){const s=Le(),t=(0,f.useSelect)(e=>e(Ls).getLanguages(),[]),a=(0,f.useSelect)(e=>e(Ls).isLanguagesLoading(),[]),i=(0,f.useSelect)(e=>e(Ls).getRouting(),[]),[r,o]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[h,g]=(0,n.useState)(!1),[p,x]=(0,n.useState)(""),[b,N]=(0,n.useState)(!1),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(!1);(0,n.useEffect)(()=>{(async()=>{(0,f.dispatch)(Ls).languagesLoading(),d(null);try{const e=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(e)}catch(e){(0,f.dispatch)(Ls).receiveLanguages({default:"en",languages:[]}),d({status:"error",message:e?.message||(0,l.__)("Could not load languages.","gloty")})}try{const e=await m()({path:"/gloty/v1/settings/routing",parse:!0});(0,f.dispatch)(Ls).receiveRouting(e)}catch(e){(0,f.dispatch)(Ls).receiveRouting({url_structure:"subdirectory"}),d(s=>"error"===s?.status?s:{status:"error",message:e?.message||(0,l.__)("Could not load routing settings.","gloty")})}})()},[]);const B=(0,n.useMemo)(()=>t?.languages||[],[t]),E=t?.default||e?.language?.default||"en",L=(0,n.useMemo)(()=>{const e=[...B];return e.sort((e,s)=>e.code===E?-1:s.code===E?1:(Number(e.sort_order)||0)-(Number(s.sort_order)||0)),e},[B,E]),M=(0,n.useMemo)(()=>L.filter(e=>e.code!==E&&1!==Number(e.is_active)),[L,E]),A=k?L:L.filter(e=>e.code===E||1===Number(e.is_active)),D=async(e,t)=>{const a=L.filter(e=>e.code!==E),n=a.findIndex(s=>s.id===e.id),i=n+t;if(n<0||i<0||i>=a.length)return;const r=a[n],c=a[i],h=Number(r.sort_order)||0,g=Number(c.sort_order)||0;o(!0),d(null);try{await Promise.all([m()({path:`/gloty/v1/languages/${r.id}`,method:"PUT",data:{sort_order:g}}),m()({path:`/gloty/v1/languages/${c.id}`,method:"PUT",data:{sort_order:h}})]),s.success((0,l.__)("Display order updated.","gloty"));const e=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(e)}catch(e){s.error(e?.message||(0,l.__)("Could not update display order.","gloty"))}finally{o(!1)}},R=i?.url_structure||e?.routing?.url_structure||"subdirectory",O=(0,n.useMemo)(()=>function(e){const s=new Set((e||[]).map(e=>String(e.code||"").toLowerCase()));return Ke.filter(e=>!s.has(e.code.toLowerCase())).map(e=>({label:`${e.native_name} — ${e.name} (${e.code})`,value:e.code}))}(B),[B]);return a&&!t?(0,u.jsx)("div",{className:"wpshelf-screen",children:(0,u.jsx)(ce,{cols:5,rows:4,headers:[(0,l.__)("Language","gloty"),(0,l.__)("Code","gloty"),(0,l.__)("Direction","gloty"),(0,l.__)("Default","gloty"),(0,l.__)("Order","gloty")]})}):(0,u.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Languages","gloty"),children:[(0,u.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Source language is the canonical site language. Enable target languages to create URL prefixes and start capturing translations.","gloty")}),c&&(0,u.jsx)(y.Notice,{status:c.status,isDismissible:!0,onDismiss:()=>d(null),className:"wpshelf-mb",children:c.message}),(0,u.jsxs)(y.Card,{className:"wpshelf-mb",children:[(0,u.jsxs)(y.CardHeader,{children:[(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("URL strategy","gloty")}),r&&(0,u.jsx)(re,{label:(0,l.__)("Saving…","gloty")})]}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Choose how translated pages are addressed. This affects every translated URL on your site.","gloty")}),i?.deferred?.message&&(0,u.jsx)("p",{className:"wpshelf-muted",children:i.deferred.message}),(0,u.jsx)("div",{className:"wpshelf-urlstrategy",role:"radiogroup","aria-label":(0,l.__)("URL strategy","gloty"),children:[{value:"subdirectory",title:(0,l.__)("Path prefix","gloty"),example:"example.com/fr/page",desc:(0,l.__)("Recommended for SEO — each language gets its own path.","gloty")},{value:"parameter",title:(0,l.__)("Query parameter","gloty"),example:"example.com/page?lang=fr",desc:(0,l.__)("Simplest setup — no rewrite rules required.","gloty")}].map(e=>{const t=R===e.value;return(0,u.jsxs)("button",{type:"button",role:"radio","aria-checked":t,className:"wpshelf-urlstrategy__opt"+(t?" wpshelf-urlstrategy__opt--active":""),onClick:()=>!t&&(async e=>{o(!0),d(null);try{await m()({path:"/gloty/v1/settings/routing/update",method:"POST",data:{url_structure:e}});const t=await m()({path:"/gloty/v1/settings/routing",parse:!0});(0,f.dispatch)(Ls).receiveRouting(t),s.success((0,l.__)("Routing settings saved.","gloty"))}catch(e){s.error(e?.message||(0,l.__)("Could not save routing settings.","gloty"))}finally{o(!1)}})(e.value),disabled:r,children:[(0,u.jsxs)("span",{className:"wpshelf-urlstrategy__top",children:[(0,u.jsx)("span",{className:"wpshelf-urlstrategy__title",children:e.title}),t?(0,u.jsxs)("span",{className:"wpshelf-chip wpshelf-chip--success",children:["✓ ",(0,l.__)("Selected","gloty")]}):(0,u.jsx)("span",{className:"wpshelf-urlstrategy__pick wpshelf-muted",children:(0,l.__)("Use this","gloty")})]}),(0,u.jsx)("code",{className:"wpshelf-urlstrategy__example",children:e.example}),(0,u.jsx)("span",{className:"wpshelf-urlstrategy__desc wpshelf-muted",children:e.desc})]},e.value)})})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-mb",children:[(0,u.jsxs)(y.CardHeader,{children:[(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Target languages","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:12},children:[r&&(0,u.jsx)(re,{label:(0,l.__)("Saving…","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:()=>{x(""),g(!0)},disabled:r,children:(0,l.__)("Add language","gloty")})]})]}),(0,u.jsxs)(y.CardBody,{children:[0===B.length?(0,u.jsx)(ne,{title:(0,l.__)("No languages configured","gloty"),hint:(0,l.__)("Add a target language to start capturing translations.","gloty")}):(0,u.jsxs)(_,{className:"wp-list-table widefat striped",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{children:(0,l.__)("Code","gloty")}),(0,u.jsx)("th",{children:(0,l.__)("Language","gloty")}),(0,u.jsx)("th",{title:(0,l.__)("The language your content is written in. Every other language is translated from it.","gloty"),children:(0,l.__)("Source","gloty")}),(0,u.jsx)("th",{title:(0,l.__)("Controls the order languages appear in the front-end switcher.","gloty"),children:(0,l.__)("Order","gloty")}),(0,u.jsx)("th",{title:(0,l.__)("Active languages show in the switcher and are served to visitors. Inactive ones stay configured but hidden.","gloty"),children:(0,l.__)("Active","gloty")}),(0,u.jsx)("th",{children:(0,u.jsx)("span",{className:"screen-reader-text",children:(0,l.__)("Actions","gloty")})})]})}),(0,u.jsx)("tbody",{children:A.map(e=>{const t=L.filter(e=>e.code!==E),a=t[0]?.id,n=t[t.length-1]?.id,i=e.native_name||e.name||e.code;return(0,u.jsxs)("tr",{children:[(0,u.jsx)("td",{children:(0,u.jsx)("code",{children:e.code})}),(0,u.jsxs)("td",{children:[e.native_name," ",(0,u.jsxs)("span",{className:"wpshelf-muted",children:["(",e.name,")"]})]}),(0,u.jsx)("td",{children:e.code===E?(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success",title:(0,l.__)("This is your source language — content is translated from it.","gloty"),children:(0,l.__)("Source","gloty")}):(0,u.jsx)(y.Button,{variant:"link",onClick:()=>(async e=>{o(!0),d(null);try{await m()({path:"/gloty/v1/languages/default",method:"POST",data:{code:e}});const t=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(t),s.success((0,l.__)("Default language updated.","gloty"))}catch(e){s.error(e?.message||(0,l.__)("Could not set default language.","gloty"))}finally{o(!1)}})(e.code),disabled:r,children:(0,l.__)("Make source","gloty")})}),(0,u.jsx)("td",{children:e.code!==E?(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:4},children:[(0,u.jsx)(y.Button,{variant:"tertiary",isSmall:!0,disabled:r||e.id===a,onClick:()=>D(e,-1),"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */65 (0,l.__)("Move %s up","gloty"),i),children:(0, u.jsx)(w,{icon:v,size:20})}),(0,u.jsx)(y.Button,{variant:"tertiary",isSmall:!0,disabled:r||e.id===n,onClick:()=>D(e,1),"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */66 (0,l.__)("Move %s down","gloty"),i),children:(0, u.jsx)(w,{icon:j,size:20})})]}):(0,u.jsx)("span",{className:"wpshelf-muted",children:"—"})}),(0,u.jsx)("td",{children:(0,u.jsx)(y.ToggleControl,{__nextHasNoMarginBottom:!0,label:1===Number(e.is_active)?(0,l.__)("Active","gloty"):(0,l.__)("Inactive","gloty"),help:e.code===E?(0,l.__)("Source language always stays active.","gloty"):void 0,checked:1===Number(e.is_active),disabled:r||e.code===E,onChange:t=>(async(e,t)=>{o(!0),d(null);try{await m()({path:`/gloty/v1/languages/${e}`,method:"PUT",data:{is_active:t}}),s.success((0,l.__)("Language updated.","gloty"));const a=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(a)}catch(e){s.error(e?.message||(0,l.__)("Error updating","gloty"))}finally{o(!1)}})(e.id,t)})}),(0,u.jsx)("td",{children:e.code!==E&&(0,u.jsx)(y.Button,{variant:"tertiary",isDestructive:!0,isSmall:!0,onClick:()=>S(e),disabled:r,"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */67 (0,l.__)("Remove %s","gloty"),i),children:(0,l.__)("Remove","gloty")})})]},e.id)})})]}),M.length>0&&(0, u.jsx)("div",{className:"wpshelf-lang-showmore",children:(0,u.jsxs)(y.Button,{variant:"link",onClick:()=>T(e=>!e),"aria-expanded":k,children:[k?(0,l.__)("Hide inactive languages","gloty"):(0,l.sprintf)(/* translators: %d: number of inactive (configured but disabled) languages */ /* translators: %d: number of inactive (configured but disabled) languages */68 (0,l._n)("Show %d inactive language","Show %d inactive languages",M.length,"gloty"),M.length),(0, u.jsx)(w,{icon:k?v:j,size:20})]})}),B.length>0&&(0,u.jsx)("p",{className:"wpshelf-muted wpshelf-lang-legend",children:(0,l.__)("Source is the language you author in. Active languages appear in the switcher and are served to visitors; turn one off to keep it configured but hidden. Order sets where each appears in the switcher.","gloty")})]})]}),h&&(0,u.jsxs)(y.Modal,{title:(0,l.__)("Add language","gloty"),onRequestClose:()=>{b||(g(!1),x(""))},className:"wpshelf-language-modal",children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Pick a language. Base tags only — regional variants like en-GB or pt-BR are not offered.","gloty")}),(0,u.jsx)(y.ComboboxControl,{label:(0,l.__)("Language","gloty"),value:p,onChange:e=>x(e||""),options:O,allowReset:!0,__nextHasNoMarginBottom:!0}),(0,u.jsx)("div",{style:{marginTop:12},children:(0,u.jsx)(ds,{code:p})}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:8,marginTop:16,justifyContent:"flex-end"},children:[(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>{g(!1),x("")},disabled:b,children:(0,l.__)("Cancel","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{if(!p)return;const e=Qe(p);if(e){N(!0);try{await m()({path:"/gloty/v1/languages",method:"POST",data:{code:e.code,name:e.name,native_name:e.native_name,is_rtl:!!e.is_rtl}});const t=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(t),s.success((0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */69 (0,l.__)("%s added.","gloty"),e.native_name)),g(!1), x("")}catch(e){s.error(e?.message||(0,l.__)("Could not add language.","gloty"))}finally{N(!1)}}else s.error((0,l.__)("Unknown language code.","gloty"))},disabled:!p||b,isBusy:b,children:(0,l.__)("Add language","gloty")})]})]}),C&&(0,u.jsx)(ie,{title:(0,l.__)("Remove language","gloty"),message:(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */70 (0,l.__)("Remove %s? Translated content in this language will no longer be served, but the stored translations will remain in the database.","gloty"),C.native_name||C.name||C.code),confirmLabel:(0,l.__)("Remove","gloty"),busy:r,onConfirm:async()=>{const e=C;if(!e)return;const t=e.native_name||e.name||e.code;o(!0);try{await m()({path:`/gloty/v1/languages/${e.id}`,method:"DELETE"});const a=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(a),s.success((0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */71 (0,l.__)("%s removed.","gloty"),t))}catch(e){s.error(e?.message||(0,l.__)("Could not remove language.","gloty"))}finally{o(!1),S(null)}},onCancel:()=>S(null)})]})}function Hs({boot:e}){const s=!e?.onboardingComplete,t=Ms(e?.adminPage||"gloty"),a=As().tab||t,i=s&&"dashboard"===a?"onboarding":a,[r,o]=(0,n.useState)(!1),c=!!e?.devMode||"design-system"===a,d=!1!==e?.capabilities?.manageOptions,h=d?[{label:(0,l.__)("Operations","gloty"),items:[{name:"dashboard",title:(0,l.__)("Overview","gloty"),icon:N},{name:"sync",title:(0,l.__)("Sync","gloty"),icon:C},{name:"translations",title:(0,l.__)("Translations","gloty"),icon:b},{name:"analytics",title:(0,l.__)("Analytics","gloty"),icon:S}]},{label:(0,l.__)("Configure","gloty"),items:[{name:"languages",title:(0,l.__)("Languages","gloty"),icon:k},{name:"glossary",title:(0,l.__)("Glossary","gloty"),icon:T},{name:"seo",title:(0,l.__)("SEO","gloty"),icon:B},{name:"settings",title:(0,l.__)("Settings","gloty"),icon:E}]},{label:(0,l.__)("Account","gloty"),items:[{name:"billing",title:(0,l.__)("Billing","gloty"),icon:L}]},...e?.onboardingComplete?[]:[{label:(0,l.__)("Setup","gloty"),items:[{name:"onboarding",title:(0,l.__)("Setup","gloty"),icon:M}]}],...c?[{label:(0,l.__)("Developer","gloty"),items:[{name:"design-system",title:(0,l.__)("Design system","gloty"),icon:A}]}]:[]]:[{label:(0,l.__)("Operations","gloty"),items:[{name:"translations",title:(0,l.__)("Translations","gloty"),icon:b}]}],g=h.flatMap(e=>e.items),_=e=>d&&"design-system"===e||g.some(s=>s.name===e),p=d?"dashboard":"translations",m=_(i)?i:p,[f,x]=(0,n.useState)(m);(0,n.useEffect)(()=>{const e=()=>{const e=As(),s=e.tab&&_(e.tab)?e.tab:p;x(s)};return window.addEventListener("popstate",e),()=>window.removeEventListener("popstate",e)},[g]);const[v,j]=(0,n.useState)(null),D=(e,s=null)=>{x(e),j(s),function(e,s=null){if("undefined"==typeof window)return;const t=new URL(window.location.href);t.searchParams.set("page",{dashboard:"gloty",translations:"gloty-translations",sync:"gloty-sync",languages:"gloty-languages",glossary:"gloty-glossary",settings:"gloty-settings",billing:"gloty-billing",onboarding:"gloty-onboarding","design-system":"gloty-design-system"}[e]||"gloty"),t.searchParams.set("tab",e),s?t.searchParams.set("view",s):t.searchParams.delete("view"),window.history.replaceState({},"",t.toString())}(e)};return(0,u.jsx)(Ee,{children:(0,u.jsxs)("div",{className:"wpshelf-app",children:[(0,u.jsx)("a",{className:"screen-reader-text",href:"#gloty-main-content",children:(0,l.__)("Skip to main content","gloty")}),(0,u.jsxs)("header",{className:"wpshelf-app__header",children:[(0,u.jsxs)("div",{className:"wpshelf-app__brand",children:[(0,u.jsx)("div",{className:"wpshelf-app__mark","aria-hidden":"true",children:(0,u.jsx)("svg",{viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:(0,u.jsxs)("g",{transform:"matrix(1 0 0 -1 0 48)",children:[(0,u.jsx)("path",{d:"M39 24 A15 15 0 1 0 34.6 34.6",stroke:"#ffffff",strokeWidth:"2.4",strokeLinecap:"round"}),(0,u.jsx)("path",{d:"M39 24 H27.5",stroke:"#ffffff",strokeWidth:"2.4",strokeLinecap:"round"}),(0,u.jsx)("ellipse",{cx:"24",cy:"24",rx:"6.4",ry:"15",stroke:"#ffffff",strokeWidth:"1.6",strokeOpacity:"0.7"}),(0,u.jsx)("path",{d:"M13.5 16 H34.5",stroke:"#ffffff",strokeWidth:"1.5",strokeLinecap:"round",strokeOpacity:"0.55"}),(0,u.jsx)("path",{d:"M13.5 32 H32",stroke:"#ffffff",strokeWidth:"1.5",strokeLinecap:"round",strokeOpacity:"0.55"}),(0,u.jsx)("circle",{cx:"27.5",cy:"24",r:"2.4",fill:"#ffffff"})]})})}),(0,u.jsxs)("div",{className:"wpshelf-app__brand-text",children:[(0,u.jsx)("h1",{className:"wpshelf-app__title",children:(0,l.__)("Gloty","gloty")}),(0,u.jsx)("p",{className:"wpshelf-app__subtitle",children:(0,l.__)("AI-powered multilingual WordPress, done locally","gloty")})]})]}),(0,u.jsxs)("div",{className:"wpshelf-app__header-right",children:[(0,u.jsx)(ls,{onNavigate:D}),(0,u.jsxs)("span",{className:"wpshelf-app__version",children:["v",e?.plugin?.version]})]})]}),(0,u.jsxs)("div",{className:"wpshelf-layout"+(r?" wpshelf-layout--collapsed":""),children:[(0,u.jsxs)("nav",{className:"wpshelf-sidebar","aria-label":(0,l.__)("Gloty navigation","gloty"),children:[(0,u.jsx)("button",{type:"button",className:"wpshelf-sidebar__toggle",onClick:()=>o(e=>!e),"aria-label":r?(0,l.__)("Expand navigation","gloty"):(0,l.__)("Collapse navigation","gloty"),children:r?"❯":"❮"}),h.map(e=>(0,u.jsxs)("div",{className:"wpshelf-sidebar__section",children:[!r&&(0,u.jsx)("div",{className:"wpshelf-sidebar__section-label",children:e.label}),e.items.map(e=>{const s=(0,u.jsxs)("button",{type:"button",className:"wpshelf-sidebar__item"+(f===e.name?" wpshelf-sidebar__item--active":""),onClick:()=>D(e.name),"aria-selected":f===e.name,"aria-label":e.title,role:"tab",children:[(0,u.jsx)(w,{icon:e.icon,size:20,className:"wpshelf-sidebar__item-icon"}),!r&&(0,u.jsx)("span",{className:"wpshelf-sidebar__item-label",children:e.title})]},e.name);return r?(0,u.jsx)(y.Tooltip,{text:e.title,children:s},e.name):s})]},e.label))]}),(0,u.jsxs)("div",{id:"gloty-main-content",className:"wpshelf-tab-content",role:"tabpanel",tabIndex:"-1",children:[(0,u.jsx)(fs,{license:e?.license,hideOnboarding:"onboarding"===f}),"dashboard"===f?(0,u.jsx)($s,{boot:e,onNavigate:D}):"translations"===f?(0,u.jsx)(Ts,{boot:e,filters:v}):"sync"===f?(0,u.jsx)(vs,{boot:e,onNavigate:D}):"languages"===f?(0,u.jsx)(Is,{boot:e}):"glossary"===f?(0,u.jsx)(ts,{boot:e}):"seo"===f?(0,u.jsx)(xs,{boot:e}):"analytics"===f?(0,u.jsx)(X,{}):"billing"===f?(0,u.jsx)(Se,{boot:e}):"onboarding"===f?(0,u.jsx)(Rs,{boot:e}):"design-system"===f?(0,u.jsx)(qe,{}):(0,u.jsx)(ms,{boot:e})]})]})]})})}function Gs(){const e=document.getElementById("gloty-admin-root");if(!e)return;const s="undefined"!=typeof window?window.glotyBoot:void 0;s&&function(e){e?.api&&(m().use(m().createNonceMiddleware(e.api.restNonce)),m().use((e,s)=>{if("GET"!==(e.method??"GET").toUpperCase()||e.url)return s(e);const t=e.path??"",a=t.includes("?")?"&":"?";return s({...e,path:`${t}${a}_cb=${Date.now()}`,cache:"no-store"})}),m().use((s,t)=>{if(s.url)return t(s);const a=s.path??"",l=e.api.restRoot.replace(/\/$/,""),n=a.startsWith("/")?a:`/${a}`;return t({...s,url:l+n})}))}(s),(0,a.H)(e).render((0,u.jsx)(Hs,{boot:s}))}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",Gs):Gs()},930(e,s,t){var a=t(795);s.H=a.createRoot,a.hydrateRoot},795(e){e.exports=window.ReactDOM}},t={};function a(e){var l=t[e];if(void 0!==l)return l.exports;var n=t[e]={exports:{}};return s[e](n,n.exports,a),n.exports}a.m=s,e=[],a.O=(s,t,l,n)=>{if(!t){var i=1/0;for(d=0;d<e.length;d++){for(var[t,l,n]=e[d],r=!0,o=0;o<t.length;o++)(!1&n||i>=n)&&Object.keys(a.O).every(e=>a.O[e](t[o]))?t.splice(o--,1):(r=!1,n<i&&(i=n));if(r){e.splice(d--,1);var c=l();void 0!==c&&(s=c)}}return s}n=n||0;for(var d=e.length;d>0&&e[d-1][2]>n;d--)e[d]=e[d-1];e[d]=[t,l,n]},a.n=e=>{var s=e&&e.__esModule?()=>e.default:()=>e;return a.d(s,{a:s}),s},a.d=(e,s)=>{for(var t in s)a.o(s,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:s[t]})},a.o=(e,s)=>Object.prototype.hasOwnProperty.call(e,s),(()=>{var e={366:0,757:0};a.O.j=s=>0===e[s];var s=(s,t)=>{var l,n,[i,r,o]=t,c=0;if(i.some(s=>0!==e[s])){for(l in r)a.o(r,l)&&(a.m[l]=r[l]);if(o)var d=o(a)}for(s&&s(t);c<i.length;c++)n=i[c],a.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return a.O(d)},t=globalThis.webpackChunk_wp_shelf_gloty=globalThis.webpackChunk_wp_shelf_gloty||[];t.forEach(s.bind(null,0)),t.push=s.bind(null,t.push.bind(t))})();var l=a.O(void 0,[757],()=>a(843));l=a.O(l)})();51 (0,l.__)("The glossary already covers “%s” for this language.","gloty"),n))}catch(e){t.error(e?.message||(0,l.__)("Could not add this to the glossary.","gloty"))}finally{O(null)}})(e)},children:(0,l.__)("Add to glossary","gloty")}),(0,_.jsx)(f.MenuItem,{icon:Cs,isDestructive:!0,onClick:()=>{n(),X({type:"single",id:s})},children:(0,l.__)("Delete","gloty")})]})})})})]},s)})})]})}),c>1&&(0,_.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{marginTop:12},children:[(0,_.jsxs)("span",{className:"wpshelf-muted",children:[(0,l.__)("Page","gloty")," ",h," / ",c]}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:4},children:[(0,_.jsxs)(f.Button,{variant:"secondary",isSmall:!0,disabled:h<=1||u,onClick:()=>g(e=>e-1),children:["« ",(0,l.__)("Prev","gloty")]}),(0,_.jsxs)(f.Button,{variant:"secondary",isSmall:!0,disabled:h>=c||u,onClick:()=>g(e=>e+1),children:[(0,l.__)("Next","gloty")," »"]})]})]})]}),P&&(0,_.jsx)(f.Modal,{title:(0,l.__)("Edit translation","gloty"),onRequestClose:()=>$(null),className:"wpshelf-edit-modal",children:(0,_.jsxs)("div",{className:"wpshelf-edit-modal__body",children:[(0,_.jsxs)(f.Card,{className:"wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsxs)("strong",{children:[(0,l.__)("Original","gloty")," (",P.source_language,")"]})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)("pre",{className:"wpshelf-pre",children:P.original_text})})]}),(0,_.jsx)(f.TextareaControl,{label:(0,l.__)("Translation","gloty")+` (${P.target_language})`,value:I,onChange:H,rows:5,__nextHasNoMarginBottom:!0}),I!==(P.translated_text||"")&&(0,_.jsxs)("div",{className:"wpshelf-diff",children:[(0,_.jsx)("span",{className:"wpshelf-diff__label",children:(0,l.__)("Changes","gloty")}),(0,_.jsx)(ye,{oldText:P.translated_text||"",newText:I})]}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16,justifyContent:"flex-end"},children:[(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>$(null),children:(0,l.__)("Cancel","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{if(P){z(!0);try{await y()({path:`/gloty/v1/translations/${P.id}`,method:"POST",data:{translated_text:I}}),t.success((0,l.__)("Translation saved.","gloty")),$(null),await _e()}catch(e){t.error(e?.message||(0,l.__)("Failed to save translation.","gloty"))}finally{z(!1)}}},isBusy:G,disabled:G||""===I,children:(0,l.__)("Save","gloty")})]})]})}),W&&(0,_.jsx)(re,{title:(0,l.__)("Delete translations","gloty"),message:"bulk"===W.type?(0,l.sprintf)(/* translators: %d: number of rows */ /* translators: %d: number of rows */ 52 (0,l.__)("Delete %d cached translation(s)? They may be regenerated later.","gloty"),W.ids.length):(0,l.__)("Delete this cached translation? It may be generated again later.","gloty"),busy:"bulk"===W.type?U:null!==R,onConfirm:()=>"bulk"===W.type?(async()=>{const e=W?.ids||Array.from(F);if(0!==e.length){q(!0);try{const s=await y()({path:"/gloty/v1/translations/delete-selected",method:"POST",data:{ids:e}});t.success((0,l.sprintf)(/* translators: %d: number of translation rows deleted */ /* translators: %d: number of translation rows deleted */ 53 (0,l.__)("%d translation(s) deleted.","gloty"),s?.deleted||e.length)),we(),await _e()}catch(e){t.error(e?.message||(0,l.__)("Bulk delete failed.","gloty"))}finally{q(!1),X(null)}}})():(async e=>{O(e);try{await y()({path:`/gloty/v1/translations/${e}`,method:"DELETE"}),t.success((0,l.__)("Translation deleted.","gloty")),await _e()}catch(e){t.error(e?.message||(0,l.__)("Could not delete translation.","gloty"))}finally{O(null),X(null)}})(W.id),onCancel:()=>X(null)})]})}const Es={dashboard:null,dashboardLoading:!1,dashboardError:null,jobs:null,jobsLoading:!1,languages:null,languagesLoading:!1,routing:null,activity:null,activityLoading:!1,scan:null,onboardingStep:0,pluginSettings:null,pluginSettingsLoading:!1,pluginSettingsError:null},Ls=(0,w.createReduxStore)("gloty/admin",{reducer:function(e=Es,s){switch(s.type){case"RECEIVE_DASHBOARD":return{...e,dashboard:s.payload,dashboardLoading:!1,dashboardError:null};case"DASHBOARD_ERROR":return{...e,dashboardLoading:!1,dashboardError:s.payload};case"DASHBOARD_LOADING":return{...e,dashboardLoading:!0,dashboardError:null};case"RECEIVE_JOBS":return{...e,jobs:s.payload,jobsLoading:!1};case"JOBS_LOADING":return{...e,jobsLoading:!0};case"RECEIVE_LANGUAGES":return{...e,languages:s.payload,languagesLoading:!1};case"LANGUAGES_LOADING":return{...e,languagesLoading:!0};case"RECEIVE_ROUTING":return{...e,routing:s.payload};case"RECEIVE_ACTIVITY":return{...e,activity:s.payload,activityLoading:!1};case"ACTIVITY_LOADING":return{...e,activityLoading:!0};case"RECEIVE_SCAN":return{...e,scan:s.payload};case"SET_ONBOARDING_STEP":return{...e,onboardingStep:s.payload};case"PLUGIN_SETTINGS_LOADING":return{...e,pluginSettingsLoading:!0,pluginSettingsError:null};case"RECEIVE_PLUGIN_SETTINGS":return{...e,pluginSettings:s.payload,pluginSettingsLoading:!1,pluginSettingsError:null};case"PLUGIN_SETTINGS_ERROR":return{...e,pluginSettingsLoading:!1,pluginSettingsError:s.payload};default:return e}},actions:{receiveDashboard:e=>({type:"RECEIVE_DASHBOARD",payload:e}),dashboardError:e=>({type:"DASHBOARD_ERROR",payload:e}),dashboardLoading:()=>({type:"DASHBOARD_LOADING"}),receiveJobs:e=>({type:"RECEIVE_JOBS",payload:e}),jobsLoading:()=>({type:"JOBS_LOADING"}),receiveLanguages:e=>({type:"RECEIVE_LANGUAGES",payload:e}),languagesLoading:()=>({type:"LANGUAGES_LOADING"}),receiveRouting:e=>({type:"RECEIVE_ROUTING",payload:e}),receiveActivity:e=>({type:"RECEIVE_ACTIVITY",payload:e}),activityLoading:()=>({type:"ACTIVITY_LOADING"}),receiveScan:e=>({type:"RECEIVE_SCAN",payload:e}),setOnboardingStep:e=>({type:"SET_ONBOARDING_STEP",payload:e}),pluginSettingsLoading:()=>({type:"PLUGIN_SETTINGS_LOADING"}),receivePluginSettings:e=>({type:"RECEIVE_PLUGIN_SETTINGS",payload:e}),pluginSettingsError:e=>({type:"PLUGIN_SETTINGS_ERROR",payload:e})},selectors:{getDashboard:e=>e.dashboard,isDashboardLoading:e=>e.dashboardLoading,getDashboardError:e=>e.dashboardError,getJobs:e=>e.jobs,isJobsLoading:e=>e.jobsLoading,getLanguages:e=>e.languages,isLanguagesLoading:e=>e.languagesLoading,getRouting:e=>e.routing,getActivity:e=>e.activity,isActivityLoading:e=>e.activityLoading,getScan:e=>e.scan,getOnboardingStep:e=>e.onboardingStep,getPluginSettings:e=>e.pluginSettings,isPluginSettingsLoading:e=>e.pluginSettingsLoading,getPluginSettingsError:e=>e.pluginSettingsError}});(0,w.register)(Ls);const Ms="gloty/admin";function As(e){return{gloty:"dashboard","gloty-dashboard":"dashboard","gloty-queue":"sync","gloty-sync":"sync","gloty-translations":"translations","gloty-languages":"languages","gloty-glossary":"glossary","gloty-onboarding":"onboarding","gloty-activity":"sync","gloty-settings":"settings","gloty-billing":"billing","gloty-design-system":"design-system"}[e]||"dashboard"}function Ds(){if("undefined"==typeof window)return{tab:null,view:null};const e=new URL(window.location.href),s=e.searchParams.get("tab"),t=e.searchParams.get("view");return{tab:s||As(e.searchParams.get("page")||"gloty"),view:t||null}}const Rs=[{key:"welcome",label:(0,l.__)("Welcome","gloty")},{key:"connection",label:(0,l.__)("Connection","gloty")},{key:"languages",label:(0,l.__)("Languages","gloty")},{key:"scan",label:(0,l.__)("Content scan","gloty")},{key:"done",label:(0,l.__)("Ready","gloty")}];function Os({boot:e}){const s=(0,w.useSelect)(e=>e(Ms).getOnboardingStep(),[]),t=e=>(0,w.dispatch)(Ms).setOnboardingStep(e),[a,i]=(0,n.useState)(null),[r,o]=(0,n.useState)(e?.license?.hasKey?"existing":"new"),[c,d]=(0,n.useState)(""),[h,g]=(0,n.useState)(null),[u,p]=(0,n.useState)(null),[m,x]=(0,n.useState)(!1),[v,j]=(0,n.useState)(null),[b,N]=(0,n.useState)(!1),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(null),[B,E]=(0,n.useState)(e?.connection?.accountEmail||""),[L,M]=(0,n.useState)(e?.connection?.accountName||""),A=!!e?.connection?.connected,D=async()=>{x(!0),g(null),p(null);try{const e=await y()({path:"/gloty/v1/onboarding/connect",method:"POST",data:{email:B,name:L,use_existing_license:"existing"===r,license_key:"existing"===r?c.trim():""}});e?.ok?(i(e),d(""),window.dispatchEvent(new Event("gloty-license-refresh"))):(p(e?.stage||"connect"),g(e?.message||(0,l.__)("Could not complete the connection.","gloty")))}catch(e){p("network"),g(e?.message||(0,l.__)("Connection failed","gloty"))}finally{x(!1)}},R=()=>{y()({path:"/gloty/v1/onboarding/complete",method:"POST"}).catch(()=>{})},O=async()=>{N(!0),T(null),S(null);try{const e=await y()({path:"/gloty/v1/onboarding/language-packs",method:"POST"});S(e),!e.can_install&&e.message&&T(e.message)}catch(e){T(e?.message||(0,l.__)("Language pack install failed.","gloty"))}finally{N(!1)}},P=async()=>{x(!0),g(null);try{const e=await y()({path:"/gloty/v1/scan/start",method:"POST",data:{batch_size:20}});j(e),R(),t(4)}catch(e){g(e?.message||(0,l.__)("Scan failed","gloty"))}finally{x(!1)}},$=e?.language?.default||"en",I=(e?.language?.active||[]).filter(e=>e!==$),H=A||!!a?.ok,G=[{key:"connection",title:(0,l.__)("Site connected to Gloty","gloty"),done:H},{key:"languages",title:(0,l.__)("Target languages enabled","gloty"),done:I.length>0},{key:"scan",title:(0,l.__)("Initial content scan started","gloty"),done:!!v||(e?.content?.sourceCount??0)>0}],z=(0,n.useMemo)(()=>{const e=C?.items;if(!C?.can_install||!Array.isArray(e))return null;const s=e.filter(e=>"failed"===e.core).length,t=e.filter(e=>"installed"===e.core).length,a=e.filter(e=>"skipped"===e.core).length,l=e.reduce((e,s)=>e+(s.plugins?.installed?.length||0),0),n=e.reduce((e,s)=>e+(s.plugins?.failed?.length||0),0);return{failed:s,installed:t,skipped:a,total:e.length,pluginsInstalled:l,pluginsFailed:n}},[C]),F=(0,n.useRef)(null);(0,n.useEffect)(()=>{F.current&&F.current.focus()},[s]);const V=Rs[s]?.label||(0,l.__)("Onboarding","gloty");return(0,_.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Onboarding","gloty"),children:[(0,_.jsx)("h2",{ref:F,tabIndex:-1,className:"screen-reader-text","aria-live":"polite",children:(0,l.sprintf)(/* translators: 1: current step, 2: total steps, 3: step label */ /* translators: 1: current step, 2: total steps, 3: step label */ 54 (0,l.__)("Step %1$d of %2$d: %3$s","gloty"),s+1,Rs.length,V)}),(0,_.jsx)(me,{items:G}),s<Rs.length-1&&(0,_.jsx)(pe,{steps:Rs,current:s}),(()=>{switch(s){case 0:return(0,_.jsx)(f.Card,{className:"wpshelf-onboard-card",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("h2",{style:{marginTop:0},children:(0,l.__)("Welcome to Gloty","gloty")}),(0,_.jsx)("p",{children:(0,l.__)("Gloty is a privacy-first WordPress translation plugin. Translations are generated by the Gloty service and stored locally in your database, so serving a translated page never calls out.","gloty")}),(0,_.jsx)("p",{children:(0,l.__)("Let's get your site set up in a few quick steps.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-row",style:{marginTop:16},children:(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>t(1),children:(0,l.__)("Get started","gloty")})})]})});case 1:return(0,_.jsxs)(f.Card,{className:"wpshelf-onboard-card",children:[(0,_.jsx)(f.CardHeader,{children:(0,l.__)("Connect your site","gloty")}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Connect this site to your WP Shelf account to generate translations. New customers receive a one-time trial of 50,000 characters, with no payment details required.","gloty")}),!H&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(f.RadioControl,{label:(0,l.__)("Your WP Shelf account","gloty"),selected:r,options:[{label:(0,l.__)("I’m new — start a free trial","gloty"),value:"new"},{label:(0,l.__)("I already have an account or license","gloty"),value:"existing"}],onChange:e=>{o(e),g(null)}}),"existing"===r&&(0,_.jsxs)("div",{className:"wpshelf-mb",children:[(0,_.jsxs)("p",{children:[(0,_.jsx)("a",{href:"https://wp-shelf.com/dashboard/licenses",target:"_blank",rel:"noopener noreferrer",children:(0,l.__)("Copy your license from the WP Shelf dashboard","gloty")}),"."," ",(0,l.__)("Use the email address on that account below.","gloty")]}),(0,_.jsxs)("label",{children:[(0,_.jsx)("div",{children:(0,l.__)("License key","gloty")}),(0,_.jsx)("input",{type:"password",autoComplete:"off",value:c,onChange:e=>d(e.target.value),placeholder:e?.license?.hasKey?(0,l.__)("Saved license will be used","gloty"):"GLOTY-XXXX-XXXX-XXXX-XXXX",style:{width:"100%"}})]})]})]}),H?(0,_.jsx)(f.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.__)("This site is connected to Gloty. You can continue to the next step.","gloty")}):(0,_.jsxs)("div",{className:"wpshelf-grid",style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:12,marginTop:12},children:[(0,_.jsxs)("label",{children:[(0,_.jsx)("div",{children:(0,l.__)("Your email","gloty")}),(0,_.jsx)("input",{type:"email",value:B,onChange:e=>E(e.target.value),autoComplete:"email",required:!0,style:{width:"100%"}})]}),(0,_.jsxs)("label",{children:[(0,_.jsx)("div",{children:(0,l.__)("Your name","gloty")}),(0,_.jsx)("input",{type:"text",value:L,onChange:e=>M(e.target.value),autoComplete:"name",required:!0,style:{width:"100%"}})]})]}),h&&(0,_.jsxs)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:["license"===u?(0,l.__)("Could not connect your license:","gloty")+" ":"register"===u?(0,l.__)("Your license was created, but we couldn't register this site:","gloty")+" ":"",h]}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[!H&&(0,_.jsx)(f.Button,{variant:"primary",onClick:D,isBusy:m,disabled:m||!B.trim()||!L.trim()||"existing"===r&&!e?.license?.hasKey&&!c.trim(),children:m?(0,l.__)("Connecting…","gloty"):"existing"===r?(0,l.__)("Activate license & connect","gloty"):(0,l.__)("Start free trial & connect","gloty")}),(0,_.jsx)(f.Button,{variant:H?"primary":"secondary",onClick:()=>t(2),disabled:m||!H,children:(0,l.__)("Next","gloty")})]})]})]});case 2:return(0,_.jsxs)(f.Card,{className:"wpshelf-onboard-card",children:[(0,_.jsx)(f.CardHeader,{children:(0,l.__)("Language setup","gloty")}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsxs)("p",{children:[(0,l.__)("Your source language is set to:","gloty")," ",(0,_.jsx)("strong",{children:$})]}),I.length>0?(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("p",{children:(0,l.__)("Active target languages:","gloty")}),(0,_.jsx)("div",{className:"wpshelf-row",children:I.map(e=>(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--info",children:e},e))})]}):(0,_.jsx)(f.Notice,{status:"warning",isDismissible:!1,children:(0,l.__)("No target languages enabled yet. Enable them under the Languages tab.","gloty")}),(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:12},children:(0,l.__)("You can always adjust languages later under the Languages tab.","gloty")}),(0,_.jsx)("div",{style:{marginTop:20,marginBottom:12,borderTop:"1px solid var(--wpshelf-line-soft)"}}),(0,_.jsx)("p",{children:(0,l.__)("Install WordPress language packs so core, admin, theme, and plugin strings load translated .mo files for your locales — including JavaScript-rendered blocks like the WooCommerce Cart and Checkout that Gloty cannot translate from page HTML. This uses the same downloads as Settings → General → Site Language.","gloty")}),k&&(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:k}),C?.can_install&&C?.message&&0===C?.items?.length&&(0,_.jsx)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",children:C.message}),z&&z.total>0&&0===z.failed&&(0,_.jsx)(f.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: 1: total locales, 2: newly installed, 3: already on disk */ /* translators: 1: total locales, 2: newly installed, 3: already on disk */ 55 (0,l.__)("Language packs processed: %1$d locale(s), %2$d installed, %3$d already present.","gloty"),z.total,z.installed,z.skipped)}),z&&z.failed>0&&(0,_.jsx)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: 1: succeeded or skipped count, 2: failed count */ /* translators: 1: succeeded or skipped count, 2: failed count */ 56 (0,l.__)("Some packs could not be installed (%1$d ok, %2$d failed). Try again or install languages under Settings → General.","gloty"),z.total-z.failed,z.failed)}),z&&z.pluginsInstalled>0&&(0,_.jsx)(f.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: %d: number of plugin language packs installed */ /* translators: %d: number of plugin language packs installed */ 57 (0,l._n)("Installed %d plugin language pack so block-based screens (e.g. WooCommerce Cart & Checkout) render translated.","Installed %d plugin language packs so block-based screens (e.g. WooCommerce Cart & Checkout) render translated.",z.pluginsInstalled,"gloty"),z.pluginsInstalled)}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,_.jsx)(f.Button,{variant:"tertiary",href:"admin.php?page=gloty-languages&tab=languages",children:(0,l.__)("Open Languages","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>t(1),children:(0,l.__)("Back","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:O,isBusy:b,disabled:b,children:(0,l.__)("Install WordPress language packs","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>t(3),disabled:0===I.length,children:(0,l.__)("Next","gloty")})]})]})]});case 3:return(0,_.jsxs)(f.Card,{className:"wpshelf-onboard-card",children:[(0,_.jsx)(f.CardHeader,{children:(0,l.__)("Content scan","gloty")}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{children:(0,l.__)("A content scan registers your existing posts and pages for translation. You can run a quick scan now or do it later from the Sync tab.","gloty")}),h&&(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:h}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>t(2),children:(0,l.__)("Back","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:P,isBusy:m,disabled:m,children:(0,l.__)("Start scan now","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>{R(),t(4)},children:(0,l.__)("Skip for now","gloty")})]})]})]});case 4:return(0,_.jsx)(f.Card,{className:"wpshelf-onboard-card",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("h2",{style:{marginTop:0},children:(0,l.__)("You're all set!","gloty")}),(0,_.jsx)("p",{children:(0,l.__)("Gloty is configured and ready to translate. Visit your site with a language prefix to start capturing template strings, or use the Sync tab to scan content and generate translations.","gloty")}),v&&(0,_.jsx)(f.Notice,{status:"success",isDismissible:!1,children:(0,l.__)("Content scan started successfully.","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,_.jsx)(f.Button,{variant:"primary",href:"admin.php?page=gloty",children:(0,l.__)("Go to Dashboard","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",href:"admin.php?page=gloty-sync&tab=sync",children:(0,l.__)("View sync status","gloty")})]}),(0,_.jsxs)("div",{className:"wpshelf-role-handoff",children:[(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Next actions by role","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-role-grid",children:[(0,_.jsx)(f.Card,{children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("strong",{children:(0,l.__)("Site owner","gloty")}),(0,_.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Confirm provider limits and monitor queue and processing health.","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",href:"admin.php?page=gloty-sync&tab=sync&view=workspace",children:(0,l.__)("Open Sync workspace","gloty")})]})}),(0,_.jsx)(f.Card,{children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("strong",{children:(0,l.__)("Content manager","gloty")}),(0,_.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Review stale rows first and manually improve priority translations.","gloty")}),(0,_.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("They do not need an administrator account — under Settings you can let a role correct translations, optionally in one language only.","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",href:"admin.php?page=gloty-translations&tab=translations&view=workspace",children:(0,l.__)("Open Translations","gloty")})]})}),(0,_.jsx)(f.Card,{children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("strong",{children:(0,l.__)("Developer","gloty")}),(0,_.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Validate language packs, route prefixes, and switcher behavior on frontend pages.","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",href:"admin.php?page=gloty-languages&tab=languages&view=languages",children:(0,l.__)("Open Languages","gloty")})]})})]})]})]})});default:return null}})()]})}const Ps=[{key:"capture",label:(0,l.__)("Collected","gloty"),tab:"sync",hint:(0,l.__)("Strings found on your site. Opens the content scan.","gloty")},{key:"queued",label:(0,l.__)("Queued","gloty"),tab:"sync",hint:(0,l.__)("Waiting to be sent. Opens the sync queue.","gloty")},{key:"dispatch",label:(0,l.__)("Sent","gloty"),tab:"sync",hint:(0,l.__)("In flight to the translator. Opens the job list.","gloty")},{key:"processing",label:(0,l.__)("Translating","gloty"),tab:"translations",filters:{status:"processing"},hint:(0,l.__)("Opens these rows in the translations table.","gloty")},{key:"completed",label:(0,l.__)("Done","gloty"),hint:(0,l.__)("Distinct strings finished in each language you have enabled — counted once per language, so it is smaller than the number of rows in the translations table.","gloty")},{key:"stale",label:(0,l.__)("Out of date","gloty"),tab:"translations",filters:{stale:"1"},hint:(0,l.__)("Opens the translations whose source text has changed.","gloty")}],$s={auto:(0,l.__)("Show synced translations","gloty"),manual:(0,l.__)("Show manually edited translations","gloty"),pending:(0,l.__)("Show translations waiting to be sent","gloty"),processing:(0,l.__)("Show translations in progress","gloty")};function Is({boot:e,onNavigate:s}){const t=Me(),[a,i]=(0,n.useState)(!1),[r,o]=(0,n.useState)(!1),c=(0,w.useSelect)(e=>e(Ms).getDashboard(),[]),d=(0,w.useSelect)(e=>e(Ms).isDashboardLoading(),[]),h=(0,w.useSelect)(e=>e(Ms).getDashboardError(),[]),g=(0,n.useCallback)(async()=>{(0,w.dispatch)(Ms).dashboardLoading();try{const e=await y()({path:"/gloty/v1/dashboard",parse:!0});(0,w.dispatch)(Ms).receiveDashboard(e)}catch(e){(0,w.dispatch)(Ms).dashboardError(e?.message||(0,l.__)("Failed to load dashboard","gloty"))}},[]);(0,n.useEffect)(()=>{g()},[g]);const u=(0,n.useCallback)(async()=>{o(!0);try{const e=await y()({path:"/gloty/v1/maintenance/purge-stale-translations",method:"POST",data:{limit:5e3}}),s=Number(e?.removed||0),a=Number(e?.remaining||0);0===s?t.info((0,l.__)("Nothing was out of date.","gloty")):t.success(a>0?(0,l.sprintf)(/* translators: 1: rows removed, 2: rows still out of date */ /* translators: 1: rows removed, 2: rows still out of date */ 58 (0,l.__)("%1$s out-of-date translations removed and re-queued. %2$s still to go — run it again.","gloty"),te(s),te(a)):(0,l.sprintf)(/* translators: %s: number of rows removed */ /* translators: %s: number of rows removed */ 59 (0,l.__)("%s out-of-date translations removed and re-queued for translation.","gloty"),te(s))),await g()}catch(e){t.error(e?.message||(0,l.__)("Could not remove the out-of-date entries.","gloty"))}finally{o(!1),i(!1)}},[g,t]);if(d&&!c)return(0,_.jsxs)("div",{className:"wpshelf-screen",children:[(0,_.jsx)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[0,1,2].map(e=>(0,_.jsx)(f.Card,{className:"wpshelf-stat",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("span",{className:"wpshelf-shimmer",style:{width:"40%",height:12,marginBottom:10}}),(0,_.jsx)("span",{className:"wpshelf-shimmer",style:{width:"30%",height:28,marginBottom:8}}),(0,_.jsx)("span",{className:"wpshelf-shimmer",style:{width:"60%",height:12}})]})},e))}),(0,_.jsx)(de,{cols:5,rows:4,headers:[(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Lang","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Updated","gloty")]})]});if(h)return(0,_.jsx)("div",{className:"wpshelf-screen",children:(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,children:h})});if(!c)return(0,_.jsx)(ie,{icon:"\\uD83D\\uDCCA",title:(0,l.__)("No data yet","gloty"),hint:(0,l.__)("Visit the front end in a target language to register template strings, or use the Sync tab to scan your content.","gloty")});const m=c.overview||{},x=c.status_breakdown||{},v=m.status_model||{},j=c.language_progress||[],b=(x.auto||0)+(x.manual||0)+(x.pending||0)+(x.processing||0),N=m.source_count??m.total_strings??0,C=m.translated_count??(x.auto||0)+(x.manual||0),S=m.pending_count??0,k=m.stale_count??0,T=m.target_languages??Math.max(0,(m.languages_active??1)-1),B=m.characters_per_language??0,E=m.characters_all_languages??B*T,L=m.expected_translations??N*Math.max(1,T),M={source:0===N?[{label:(0,l.__)("Scan content for strings","gloty"),tab:"sync"}]:[{label:(0,l.__)("Browse strings","gloty"),tab:"translations"}],translated:0===C?[{label:(0,l.__)("Start your first translation","gloty"),tab:"sync"}]:[{label:(0,l.__)("Review translations","gloty"),tab:"translations",filters:{status:"translated"}},{label:(0,l.__)("Review manual edits","gloty"),tab:"translations",filters:{status:"manual"}}],pending:S>0?[{label:(0,l.__)("Translate pending","gloty"),tab:"sync",prominent:!0},{label:(0,l.__)("View pending rows","gloty"),tab:"translations",filters:{status:"pending"}}]:null,stale:k>0?[{label:(0,l.__)("Re-sync out-of-date items","gloty"),tab:"sync"},{label:(0,l.__)("Review out-of-date rows","gloty"),tab:"translations",filters:{stale:"1"}}]:null,languages:0===T?[{label:(0,l.__)("Add a target language","gloty"),tab:"languages"}]:[{label:(0,l.__)("Manage languages","gloty"),tab:"languages"}]},A=e=>{const t=(Array.isArray(e)?e:[e]).filter(Boolean);return 0!==t.length&&s?(0,_.jsx)("div",{className:"wpshelf-stat-grid__cta"+(t.some(e=>e.prominent)?" wpshelf-stat-grid__cta--prominent":""),children:t.map(e=>(0,_.jsxs)(f.Button,{variant:e.prominent?"secondary":"link",onClick:()=>s(e.tab,e.filters||null),children:[e.label," →"]},e.label))}):null},D=e=>({template_string:(0,l.__)("theme & UI (unique gettext strings seen on localized pages)","gloty"),post_field:(0,l.__)("post / page segments (title, excerpt, each translatable block slice)","gloty"),term_field:(0,l.__)("taxonomy name & description","gloty")}[e]??e);return(0,_.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Dashboard","gloty"),children:[(0,_.jsx)(Xe,{boot:e,onNavigate:s}),(0,_.jsx)(Ze,{hasLanguages:T>0,hasSource:N>0,hasTranslated:C>0,pendingCount:S,onNavigate:s}),(0,_.jsx)(cs,{onNavigate:s}),(0,_.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--translated",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Translated","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:te(C)}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:0===N?(0,l.__)("no content captured yet","gloty"):0===T?(0,l.__)("add a target language to begin","gloty"):(0,l.sprintf)(/* translators: 1: total expected translations (strings × languages), 2: number of target languages */ /* translators: 1: total expected translations (strings × languages), 2: number of target languages */ 60 (0,l._n)("of %1$s translation in %2$d language","of %1$s translations across %2$d languages",T,"gloty"),L.toLocaleString(),T)}),A(M.translated)]})}),(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--pending",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Pending","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:te(S)}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:S>0?(0,l.__)("strings waiting to be translated","gloty"):(0,l.__)("queue is clear","gloty")}),A(M.pending)]})}),(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--stale",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Out of date","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:te(k)}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:k>0?(0,l.__)("source content changed","gloty"):(0,l.__)("all in sync","gloty")}),A(M.stale)]})})]}),(0,_.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--supporting",children:[(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--source",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Source strings","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value wpshelf-stat__value--medium",children:te(N)}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("every translatable text snippet found on your site","gloty")}),B>0&&(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:T>0?(0,l.sprintf)(/* translators: 1: characters in the site, 2: characters needed for every active language */ /* translators: 1: characters in the site, 2: characters needed for every active language */ 61 (0,l.__)("%1$s characters of source text — about %2$s to translate into every language you have enabled","gloty"),te(B),te(E)):(0,l.sprintf)(/* translators: %s: characters in the site */ /* translators: %s: characters in the site */ 62 (0,l.__)("%s characters of source text — this is what a language costs to add","gloty"),te(B))}),m.registry_by_source_kind&&Object.keys(m.registry_by_source_kind).length>0&&(0,_.jsx)("ul",{className:"wpshelf-stat__breakdown",children:Object.entries(m.registry_by_source_kind).map(([e,s])=>(0,_.jsxs)("li",{children:[(0,_.jsx)("strong",{children:te(s)})," ",D(e)]},e))}),A(M.source)]})}),(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--languages",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Target languages","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value wpshelf-stat__value--medium",children:T}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:T>0?(0,l.sprintf)(/* translators: %s: source language code */ /* translators: %s: source language code */ 63 (0,l.__)("alongside %s as source","gloty"),(e?.language?.default||"en").toUpperCase()):(0,l.__)("no target languages enabled","gloty")}),A(M.languages)]})})]}),(0,_.jsxs)("div",{className:"wpshelf-content-boxes",children:[b>0&&(0,_.jsxs)(f.Card,{className:"wpshelf-content-box",children:[(0,_.jsxs)(f.CardHeader,{children:[(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Translation status","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:[k>0&&(0,_.jsx)(f.Button,{variant:"tertiary",size:"small",isDestructive:!0,onClick:()=>i(!0),disabled:r,isBusy:r,children:r?(0,l.__)("Removing…","gloty"):(0,l.__)("Remove out-of-date","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",size:"small",onClick:g,disabled:d,isBusy:d,"aria-live":"polite",children:d?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]})]}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-row",style:{gap:24},children:Object.entries(x).map(([e,t])=>$s[e]&&s?(0,_.jsxs)("button",{type:"button",className:"wpshelf-status-link",title:$s[e],onClick:()=>s("translations",{status:e}),children:[(0,_.jsx)(Q,{status:e}),(0,_.jsx)("span",{className:"wpshelf-status-link__value",children:te(t)})]},e):(0,_.jsxs)("div",{className:"wpshelf-status-link wpshelf-status-link--static",children:[(0,_.jsx)(Q,{status:e}),(0,_.jsx)("span",{className:"wpshelf-status-link__value",children:te(t)})]},e))}),Object.keys(v).length>0&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{margin:"16px 0 8px"},children:(0,l.__)("Each string moves through these stages: Collected → Queued → Sent → Translating → Done.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-row",style:{gap:10},children:Ps.map(e=>{const t=te(v[e.key]??0);return s&&e.tab?(0,_.jsxs)("button",{type:"button",className:"wpshelf-pipeline-chip wpshelf-pipeline-chip--link",title:e.hint,onClick:()=>s(e.tab,e.filters||null),children:[(0,_.jsx)("span",{className:"wpshelf-pipeline-chip__label",children:e.label}),(0,_.jsx)("strong",{className:"wpshelf-pipeline-chip__value",children:t})]},e.key):(0,_.jsxs)("div",{className:"wpshelf-pipeline-chip",title:e.hint,children:[(0,_.jsx)("span",{className:"wpshelf-pipeline-chip__label",children:e.label}),(0,_.jsx)("strong",{className:"wpshelf-pipeline-chip__value",children:t})]},e.key)})})]})]})]}),j.length>0&&(0,_.jsxs)(f.Card,{className:"wpshelf-content-box",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Language progress","gloty")})}),(0,_.jsx)(f.CardBody,{children:j.map(e=>(0,_.jsxs)("div",{style:{marginBottom:8},children:[(0,_.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{marginBottom:2},children:[(0,_.jsxs)("span",{style:{fontSize:13,fontWeight:500},children:[e.native_name||e.name," ",(0,_.jsxs)("span",{className:"wpshelf-muted",children:["(",e.code,")"]})]}),(0,_.jsxs)("span",{className:"wpshelf-muted",children:[te(e.translated),"/",te(e.total)]})]}),(0,_.jsx)(_e,{value:e.translated,max:e.total,label:`${e.percentage}%`,scale:"completion"})]},e.code))})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-content-box",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Recent translations","gloty")})}),(0,_.jsx)(f.CardBody,{children:0===(c.recent||[]).length?(0,_.jsx)(ie,{title:(0,l.__)("No translation rows yet","gloty"),hint:(0,l.__)("Visit the front end in a target language to register template strings.","gloty")}):(0,_.jsxs)(p,{className:"wp-list-table widefat striped",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{children:(0,l.__)("Original","gloty")}),(0,_.jsx)("th",{children:(0,l.__)("Translated","gloty")}),(0,_.jsx)("th",{children:(0,l.__)("Lang","gloty")}),(0,_.jsx)("th",{children:(0,l.__)("Status","gloty")}),(0,_.jsx)("th",{children:(0,l.__)("Updated","gloty")})]})}),(0,_.jsx)("tbody",{children:c.recent.map(e=>(0,_.jsxs)("tr",{children:[(0,_.jsx)("td",{title:le(e.original)||void 0,children:le(e.original)?le(e.original).slice(0,80):(0,_.jsx)("em",{className:"wpshelf-muted",title:(0,l.__)("Structured block content — its text is captured when the block is sent for translation.","gloty"),children:(0,l.__)("Block content","gloty")})}),(0,_.jsx)("td",{title:ne(e.translated)||void 0,children:ne(e.translated)?ne(e.translated).slice(0,80):(0,_.jsx)("span",{className:"wpshelf-muted",children:"pending"===e.status||"processing"===e.status?(0,l.__)("Not translated yet","gloty"):"—"})}),(0,_.jsx)("td",{children:(0,_.jsx)("code",{children:e.language_code})}),(0,_.jsx)("td",{children:(0,_.jsx)(Q,{status:e.status})}),(0,_.jsx)("td",{className:"wpshelf-muted",children:ae(e.updated_at)})]},e.id))})]})})]})]}),a&&(0,_.jsx)(re,{title:(0,l.__)("Remove out-of-date entries?","gloty"),message:(0,l.sprintf)(/* translators: %s: number of out-of-date translations */ /* translators: %s: number of out-of-date translations */ 64 (0,l.__)("%s translations are of source text that has since changed. Removing them puts those strings back in the queue, so the next sync translates them again — which spends quota. Until it runs, visitors see the original text for those strings. Manual edits of changed content are removed too.","gloty"),te(k)),confirmLabel:(0,l.__)("Remove and re-queue","gloty"),busy:r,onConfirm:u,onCancel:()=>i(!1)})]})}function Hs({boot:e}){const s=Me(),t=(0,w.useSelect)(e=>e(Ms).getLanguages(),[]),a=(0,w.useSelect)(e=>e(Ms).isLanguagesLoading(),[]),i=(0,w.useSelect)(e=>e(Ms).getRouting(),[]),[r,o]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[h,g]=(0,n.useState)(!1),[u,m]=(0,n.useState)(""),[v,N]=(0,n.useState)(!1),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(!1);(0,n.useEffect)(()=>{(async()=>{(0,w.dispatch)(Ms).languagesLoading(),d(null);try{const e=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(e)}catch(e){(0,w.dispatch)(Ms).receiveLanguages({default:"en",languages:[]}),d({status:"error",message:e?.message||(0,l.__)("Could not load languages.","gloty")})}try{const e=await y()({path:"/gloty/v1/settings/routing",parse:!0});(0,w.dispatch)(Ms).receiveRouting(e)}catch(e){(0,w.dispatch)(Ms).receiveRouting({url_structure:"subdirectory"}),d(s=>"error"===s?.status?s:{status:"error",message:e?.message||(0,l.__)("Could not load routing settings.","gloty")})}})()},[]);const B=(0,n.useMemo)(()=>t?.languages||[],[t]),E=t?.default||e?.language?.default||"en",L=(0,n.useMemo)(()=>{const e=[...B];return e.sort((e,s)=>e.code===E?-1:s.code===E?1:(Number(e.sort_order)||0)-(Number(s.sort_order)||0)),e},[B,E]),M=(0,n.useMemo)(()=>L.filter(e=>e.code!==E&&1!==Number(e.is_active)),[L,E]),A=k?L:L.filter(e=>e.code===E||1===Number(e.is_active)),D=async(e,t)=>{const a=L.filter(e=>e.code!==E),n=a.findIndex(s=>s.id===e.id),i=n+t;if(n<0||i<0||i>=a.length)return;const r=a[n],c=a[i],h=Number(r.sort_order)||0,g=Number(c.sort_order)||0;o(!0),d(null);try{await Promise.all([y()({path:`/gloty/v1/languages/${r.id}`,method:"PUT",data:{sort_order:g}}),y()({path:`/gloty/v1/languages/${c.id}`,method:"PUT",data:{sort_order:h}})]),s.success((0,l.__)("Display order updated.","gloty"));const e=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(e)}catch(e){s.error(e?.message||(0,l.__)("Could not update display order.","gloty"))}finally{o(!1)}},R=i?.url_structure||e?.routing?.url_structure||"subdirectory",O=(0,n.useMemo)(()=>function(e){const s=new Set((e||[]).map(e=>String(e.code||"").toLowerCase()));return Qe.filter(e=>!s.has(e.code.toLowerCase())).map(e=>({label:`${e.native_name} — ${e.name} (${e.code})`,value:e.code}))}(B),[B]);return a&&!t?(0,_.jsx)("div",{className:"wpshelf-screen",children:(0,_.jsx)(de,{cols:5,rows:4,headers:[(0,l.__)("Language","gloty"),(0,l.__)("Code","gloty"),(0,l.__)("Direction","gloty"),(0,l.__)("Default","gloty"),(0,l.__)("Order","gloty")]})}):(0,_.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Languages","gloty"),children:[(0,_.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Source language is the canonical site language. Enable target languages to create URL prefixes and start capturing translations.","gloty")}),c&&(0,_.jsx)(f.Notice,{status:c.status,isDismissible:!0,onDismiss:()=>d(null),className:"wpshelf-mb",children:c.message}),(0,_.jsxs)(f.Card,{className:"wpshelf-mb",children:[(0,_.jsxs)(f.CardHeader,{children:[(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("URL strategy","gloty")}),r&&(0,_.jsx)(oe,{label:(0,l.__)("Saving…","gloty")})]}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Choose how translated pages are addressed. This affects every translated URL on your site.","gloty")}),i?.deferred?.message&&(0,_.jsx)("p",{className:"wpshelf-muted",children:i.deferred.message}),(0,_.jsx)("div",{className:"wpshelf-urlstrategy",role:"radiogroup","aria-label":(0,l.__)("URL strategy","gloty"),children:[{value:"subdirectory",title:(0,l.__)("Path prefix","gloty"),example:"example.com/fr/page",desc:(0,l.__)("Recommended for SEO — each language gets its own path.","gloty")},{value:"parameter",title:(0,l.__)("Query parameter","gloty"),example:"example.com/page?lang=fr",desc:(0,l.__)("Simplest setup — no rewrite rules required.","gloty")}].map(e=>{const t=R===e.value;return(0,_.jsxs)("button",{type:"button",role:"radio","aria-checked":t,className:"wpshelf-urlstrategy__opt"+(t?" wpshelf-urlstrategy__opt--active":""),onClick:()=>!t&&(async e=>{o(!0),d(null);try{await y()({path:"/gloty/v1/settings/routing/update",method:"POST",data:{url_structure:e}});const t=await y()({path:"/gloty/v1/settings/routing",parse:!0});(0,w.dispatch)(Ms).receiveRouting(t),s.success((0,l.__)("Routing settings saved.","gloty"))}catch(e){s.error(e?.message||(0,l.__)("Could not save routing settings.","gloty"))}finally{o(!1)}})(e.value),disabled:r,children:[(0,_.jsxs)("span",{className:"wpshelf-urlstrategy__top",children:[(0,_.jsx)("span",{className:"wpshelf-urlstrategy__title",children:e.title}),t?(0,_.jsxs)("span",{className:"wpshelf-chip wpshelf-chip--success",children:["✓ ",(0,l.__)("Selected","gloty")]}):(0,_.jsx)("span",{className:"wpshelf-urlstrategy__pick wpshelf-muted",children:(0,l.__)("Use this","gloty")})]}),(0,_.jsx)("code",{className:"wpshelf-urlstrategy__example",children:e.example}),(0,_.jsx)("span",{className:"wpshelf-urlstrategy__desc wpshelf-muted",children:e.desc})]},e.value)})})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-mb",children:[(0,_.jsxs)(f.CardHeader,{children:[(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Target languages","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:12},children:[r&&(0,_.jsx)(oe,{label:(0,l.__)("Saving…","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>{m(""),g(!0)},disabled:r,children:(0,l.__)("Add language","gloty")})]})]}),(0,_.jsxs)(f.CardBody,{children:[0===B.length?(0,_.jsx)(ie,{title:(0,l.__)("No languages configured","gloty"),hint:(0,l.__)("Add a target language to start capturing translations.","gloty")}):(0,_.jsxs)(p,{className:"wp-list-table widefat striped",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{children:(0,l.__)("Code","gloty")}),(0,_.jsx)("th",{children:(0,l.__)("Language","gloty")}),(0,_.jsx)("th",{title:(0,l.__)("The language your content is written in. Every other language is translated from it.","gloty"),children:(0,l.__)("Source","gloty")}),(0,_.jsx)("th",{title:(0,l.__)("Controls the order languages appear in the front-end switcher.","gloty"),children:(0,l.__)("Order","gloty")}),(0,_.jsx)("th",{title:(0,l.__)("Active languages show in the switcher and are served to visitors. Inactive ones stay configured but hidden.","gloty"),children:(0,l.__)("Active","gloty")}),(0,_.jsx)("th",{children:(0,_.jsx)("span",{className:"screen-reader-text",children:(0,l.__)("Actions","gloty")})})]})}),(0,_.jsx)("tbody",{children:A.map(e=>{const t=L.filter(e=>e.code!==E),a=t[0]?.id,n=t[t.length-1]?.id,i=e.native_name||e.name||e.code;return(0,_.jsxs)("tr",{children:[(0,_.jsx)("td",{children:(0,_.jsx)("code",{children:e.code})}),(0,_.jsxs)("td",{children:[e.native_name," ",(0,_.jsxs)("span",{className:"wpshelf-muted",children:["(",e.name,")"]})]}),(0,_.jsx)("td",{children:e.code===E?(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success",title:(0,l.__)("This is your source language — content is translated from it.","gloty"),children:(0,l.__)("Source","gloty")}):(0,_.jsx)(f.Button,{variant:"link",onClick:()=>(async e=>{o(!0),d(null);try{await y()({path:"/gloty/v1/languages/default",method:"POST",data:{code:e}});const t=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(t),s.success((0,l.__)("Default language updated.","gloty"))}catch(e){s.error(e?.message||(0,l.__)("Could not set default language.","gloty"))}finally{o(!1)}})(e.code),disabled:r,children:(0,l.__)("Make source","gloty")})}),(0,_.jsx)("td",{children:e.code!==E?(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:4},children:[(0,_.jsx)(f.Button,{variant:"tertiary",isSmall:!0,disabled:r||e.id===a,onClick:()=>D(e,-1),"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 65 (0,l.__)("Move %s up","gloty"),i),children:(0,_.jsx)(x,{icon:j,size:20})}),(0,_.jsx)(f.Button,{variant:"tertiary",isSmall:!0,disabled:r||e.id===n,onClick:()=>D(e,1),"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 66 (0,l.__)("Move %s down","gloty"),i),children:(0,_.jsx)(x,{icon:b,size:20})})]}):(0,_.jsx)("span",{className:"wpshelf-muted",children:"—"})}),(0,_.jsx)("td",{children:(0,_.jsx)(f.ToggleControl,{__nextHasNoMarginBottom:!0,label:1===Number(e.is_active)?(0,l.__)("Active","gloty"):(0,l.__)("Inactive","gloty"),help:e.code===E?(0,l.__)("Source language always stays active.","gloty"):void 0,checked:1===Number(e.is_active),disabled:r||e.code===E,onChange:t=>(async(e,t)=>{o(!0),d(null);try{await y()({path:`/gloty/v1/languages/${e}`,method:"PUT",data:{is_active:t}}),s.success((0,l.__)("Language updated.","gloty"));const a=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(a)}catch(e){s.error(e?.message||(0,l.__)("Error updating","gloty"))}finally{o(!1)}})(e.id,t)})}),(0,_.jsx)("td",{children:e.code!==E&&(0,_.jsx)(f.Button,{variant:"tertiary",isDestructive:!0,isSmall:!0,onClick:()=>S(e),disabled:r,"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 67 (0,l.__)("Remove %s","gloty"),i),children:(0,l.__)("Remove","gloty")})})]},e.id)})})]}),M.length>0&&(0,_.jsx)("div",{className:"wpshelf-lang-showmore",children:(0,_.jsxs)(f.Button,{variant:"link",onClick:()=>T(e=>!e),"aria-expanded":k,children:[k?(0,l.__)("Hide inactive languages","gloty"):(0,l.sprintf)(/* translators: %d: number of inactive (configured but disabled) languages */ /* translators: %d: number of inactive (configured but disabled) languages */ 68 (0,l._n)("Show %d inactive language","Show %d inactive languages",M.length,"gloty"),M.length),(0,_.jsx)(x,{icon:k?j:b,size:20})]})}),B.length>0&&(0,_.jsx)("p",{className:"wpshelf-muted wpshelf-lang-legend",children:(0,l.__)("Source is the language you author in. Active languages appear in the switcher and are served to visitors; turn one off to keep it configured but hidden. Order sets where each appears in the switcher.","gloty")})]})]}),h&&(0,_.jsxs)(f.Modal,{title:(0,l.__)("Add language","gloty"),onRequestClose:()=>{v||(g(!1),m(""))},className:"wpshelf-language-modal",children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Pick a language. Base tags only — regional variants like en-GB or pt-BR are not offered.","gloty")}),(0,_.jsx)(f.ComboboxControl,{label:(0,l.__)("Language","gloty"),value:u,onChange:e=>m(e||""),options:O,allowReset:!0,__nextHasNoMarginBottom:!0}),(0,_.jsx)("div",{style:{marginTop:12},children:(0,_.jsx)(hs,{code:u})}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:8,marginTop:16,justifyContent:"flex-end"},children:[(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>{g(!1),m("")},disabled:v,children:(0,l.__)("Cancel","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{if(!u)return;const e=es(u);if(e){N(!0);try{await y()({path:"/gloty/v1/languages",method:"POST",data:{code:e.code,name:e.name,native_name:e.native_name,is_rtl:!!e.is_rtl}});const t=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(t),s.success((0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 69 (0,l.__)("%s added.","gloty"),e.native_name)),g(!1),m("")}catch(e){s.error(e?.message||(0,l.__)("Could not add language.","gloty"))}finally{N(!1)}}else s.error((0,l.__)("Unknown language code.","gloty"))},disabled:!u||v,isBusy:v,children:(0,l.__)("Add language","gloty")})]})]}),C&&(0,_.jsx)(re,{title:(0,l.__)("Remove language","gloty"),message:(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 70 (0,l.__)("Remove %s? Translated content in this language will no longer be served, but the stored translations will remain in the database.","gloty"),C.native_name||C.name||C.code),confirmLabel:(0,l.__)("Remove","gloty"),busy:r,onConfirm:async()=>{const e=C;if(!e)return;const t=e.native_name||e.name||e.code;o(!0);try{await y()({path:`/gloty/v1/languages/${e.id}`,method:"DELETE"});const a=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(a),s.success((0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 71 (0,l.__)("%s removed.","gloty"),t))}catch(e){s.error(e?.message||(0,l.__)("Could not remove language.","gloty"))}finally{o(!1),S(null)}},onCancel:()=>S(null)})]})}function Gs({boot:e}){const s=!e?.onboardingComplete,t=As(e?.adminPage||"gloty"),a=Ds().tab||t,i=s&&"dashboard"===a?"onboarding":a,[r,o]=(0,n.useState)(!1),c=!!e?.devMode||"design-system"===a,d=!1!==e?.capabilities?.manageOptions,h=d?[{label:(0,l.__)("Operations","gloty"),items:[{name:"dashboard",title:(0,l.__)("Overview","gloty"),icon:C},{name:"sync",title:(0,l.__)("Sync","gloty"),icon:S},{name:"translations",title:(0,l.__)("Translations","gloty"),icon:N},{name:"analytics",title:(0,l.__)("Analytics","gloty"),icon:k}]},{label:(0,l.__)("Configure","gloty"),items:[{name:"languages",title:(0,l.__)("Languages","gloty"),icon:T},{name:"glossary",title:(0,l.__)("Glossary","gloty"),icon:B},{name:"seo",title:(0,l.__)("SEO","gloty"),icon:E},{name:"settings",title:(0,l.__)("Settings","gloty"),icon:L}]},{label:(0,l.__)("Account","gloty"),items:[{name:"billing",title:(0,l.__)("Billing","gloty"),icon:M}]},...e?.onboardingComplete?[]:[{label:(0,l.__)("Setup","gloty"),items:[{name:"onboarding",title:(0,l.__)("Setup","gloty"),icon:A}]}],...c?[{label:(0,l.__)("Developer","gloty"),items:[{name:"design-system",title:(0,l.__)("Design system","gloty"),icon:D}]}]:[]]:[{label:(0,l.__)("Operations","gloty"),items:[{name:"translations",title:(0,l.__)("Translations","gloty"),icon:N}]}],g=h.flatMap(e=>e.items),u=e=>d&&"design-system"===e||g.some(s=>s.name===e),p=d?"dashboard":"translations",m=u(i)?i:p,[y,w]=(0,n.useState)(m);(0,n.useEffect)(()=>{const e=()=>{const e=Ds(),s=e.tab&&u(e.tab)?e.tab:p;w(s)};return window.addEventListener("popstate",e),()=>window.removeEventListener("popstate",e)},[g]);const[v,j]=(0,n.useState)(null),b=(e,s=null)=>{w(e),j(s),function(e,s=null){if("undefined"==typeof window)return;const t=new URL(window.location.href);t.searchParams.set("page",{dashboard:"gloty",translations:"gloty-translations",sync:"gloty-sync",languages:"gloty-languages",glossary:"gloty-glossary",settings:"gloty-settings",billing:"gloty-billing",onboarding:"gloty-onboarding","design-system":"gloty-design-system"}[e]||"gloty"),t.searchParams.set("tab",e),s?t.searchParams.set("view",s):t.searchParams.delete("view"),window.history.replaceState({},"",t.toString())}(e)};return(0,_.jsx)(Le,{children:(0,_.jsxs)("div",{className:"wpshelf-app",children:[(0,_.jsx)("a",{className:"screen-reader-text",href:"#gloty-main-content",children:(0,l.__)("Skip to main content","gloty")}),(0,_.jsxs)("header",{className:"wpshelf-app__header",children:[(0,_.jsxs)("div",{className:"wpshelf-app__brand",children:[(0,_.jsx)("div",{className:"wpshelf-app__mark","aria-hidden":"true",children:(0,_.jsx)("svg",{viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:(0,_.jsxs)("g",{transform:"matrix(1 0 0 -1 0 48)",children:[(0,_.jsx)("path",{d:"M39 24 A15 15 0 1 0 34.6 34.6",stroke:"#ffffff",strokeWidth:"2.4",strokeLinecap:"round"}),(0,_.jsx)("path",{d:"M39 24 H27.5",stroke:"#ffffff",strokeWidth:"2.4",strokeLinecap:"round"}),(0,_.jsx)("ellipse",{cx:"24",cy:"24",rx:"6.4",ry:"15",stroke:"#ffffff",strokeWidth:"1.6",strokeOpacity:"0.7"}),(0,_.jsx)("path",{d:"M13.5 16 H34.5",stroke:"#ffffff",strokeWidth:"1.5",strokeLinecap:"round",strokeOpacity:"0.55"}),(0,_.jsx)("path",{d:"M13.5 32 H32",stroke:"#ffffff",strokeWidth:"1.5",strokeLinecap:"round",strokeOpacity:"0.55"}),(0,_.jsx)("circle",{cx:"27.5",cy:"24",r:"2.4",fill:"#ffffff"})]})})}),(0,_.jsxs)("div",{className:"wpshelf-app__brand-text",children:[(0,_.jsx)("h1",{className:"wpshelf-app__title",children:(0,l.__)("Gloty","gloty")}),(0,_.jsx)("p",{className:"wpshelf-app__subtitle",children:(0,l.__)("AI-powered multilingual WordPress, done locally","gloty")})]})]}),(0,_.jsxs)("div",{className:"wpshelf-app__header-right",children:[(0,_.jsx)(ns,{onNavigate:b}),(0,_.jsxs)("span",{className:"wpshelf-app__version",children:["v",e?.plugin?.version]})]})]}),(0,_.jsxs)("div",{className:"wpshelf-layout"+(r?" wpshelf-layout--collapsed":""),children:[(0,_.jsxs)("nav",{className:"wpshelf-sidebar","aria-label":(0,l.__)("Gloty navigation","gloty"),children:[(0,_.jsx)("button",{type:"button",className:"wpshelf-sidebar__toggle",onClick:()=>o(e=>!e),"aria-label":r?(0,l.__)("Expand navigation","gloty"):(0,l.__)("Collapse navigation","gloty"),children:r?"❯":"❮"}),h.map(e=>(0,_.jsxs)("div",{className:"wpshelf-sidebar__section",children:[!r&&(0,_.jsx)("div",{className:"wpshelf-sidebar__section-label",children:e.label}),e.items.map(e=>{const s=(0,_.jsxs)("button",{type:"button",className:"wpshelf-sidebar__item"+(y===e.name?" wpshelf-sidebar__item--active":""),onClick:()=>b(e.name),"aria-selected":y===e.name,"aria-label":e.title,role:"tab",children:[(0,_.jsx)(x,{icon:e.icon,size:20,className:"wpshelf-sidebar__item-icon"}),!r&&(0,_.jsx)("span",{className:"wpshelf-sidebar__item-label",children:e.title})]},e.name);return r?(0,_.jsx)(f.Tooltip,{text:e.title,children:s},e.name):s})]},e.label))]}),(0,_.jsxs)("div",{id:"gloty-main-content",className:"wpshelf-tab-content",role:"tabpanel",tabIndex:"-1",children:[(0,_.jsx)(ws,{license:e?.license,hideOnboarding:"onboarding"===y}),"dashboard"===y?(0,_.jsx)(Is,{boot:e,onNavigate:b}):"translations"===y?(0,_.jsx)(Bs,{boot:e,filters:v}):"sync"===y?(0,_.jsx)(js,{boot:e,onNavigate:b}):"languages"===y?(0,_.jsx)(Hs,{boot:e}):"glossary"===y?(0,_.jsx)(as,{boot:e}):"seo"===y?(0,_.jsx)(vs,{boot:e}):"analytics"===y?(0,_.jsx)(Y,{}):"billing"===y?(0,_.jsx)(ke,{boot:e}):"onboarding"===y?(0,_.jsx)(Os,{boot:e}):"design-system"===y?(0,_.jsx)(We,{}):(0,_.jsx)(ys,{boot:e})]})]})]})})}function zs(){const e=document.getElementById("gloty-admin-root");if(!e)return;const s="undefined"!=typeof window?window.glotyBoot:void 0;s&&function(e){e?.api&&(y().use(y().createNonceMiddleware(e.api.restNonce)),y().use((e,s)=>{if("GET"!==(e.method??"GET").toUpperCase()||e.url)return s(e);const t=e.path??"",a=t.includes("?")?"&":"?";return s({...e,path:`${t}${a}_cb=${Date.now()}`,cache:"no-store"})}),y().use((s,t)=>{if(s.url)return t(s);const a=s.path??"",l=e.api.restRoot.replace(/\/$/,""),n=a.startsWith("/")?a:`/${a}`;return t({...s,url:l+n})}))}(s),(0,a.H)(e).render((0,_.jsx)(Gs,{boot:s}))}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",zs):zs()},930(e,s,t){var a=t(795);s.H=a.createRoot,a.hydrateRoot},795(e){e.exports=window.ReactDOM}},t={};function a(e){var l=t[e];if(void 0!==l)return l.exports;var n=t[e]={exports:{}};return s[e](n,n.exports,a),n.exports}a.m=s,e=[],a.O=(s,t,l,n)=>{if(!t){var i=1/0;for(d=0;d<e.length;d++){for(var[t,l,n]=e[d],r=!0,o=0;o<t.length;o++)(!1&n||i>=n)&&Object.keys(a.O).every(e=>a.O[e](t[o]))?t.splice(o--,1):(r=!1,n<i&&(i=n));if(r){e.splice(d--,1);var c=l();void 0!==c&&(s=c)}}return s}n=n||0;for(var d=e.length;d>0&&e[d-1][2]>n;d--)e[d]=e[d-1];e[d]=[t,l,n]},a.n=e=>{var s=e&&e.__esModule?()=>e.default:()=>e;return a.d(s,{a:s}),s},a.d=(e,s)=>{for(var t in s)a.o(s,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:s[t]})},a.o=(e,s)=>Object.prototype.hasOwnProperty.call(e,s),(()=>{var e={366:0,757:0};a.O.j=s=>0===e[s];var s=(s,t)=>{var l,n,[i,r,o]=t,c=0;if(i.some(s=>0!==e[s])){for(l in r)a.o(r,l)&&(a.m[l]=r[l]);if(o)var d=o(a)}for(s&&s(t);c<i.length;c++)n=i[c],a.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return a.O(d)},t=globalThis.webpackChunk_wp_shelf_gloty=globalThis.webpackChunk_wp_shelf_gloty||[];t.forEach(s.bind(null,0)),t.push=s.bind(null,t.push.bind(t))})();var l=a.O(void 0,[757],()=>a(843));l=a.O(l)})(); -
gloty/tags/1.64.0/build/style-gloty-editor-sidebar-rtl.css
r3688478 r3748411 1 .wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-bg:#fafafa;--wpshelf-surface:#fff;--wpshelf-surface-alt:#f5f5f5;--wpshelf-ink:#0a0a0a;--wpshelf-ink-soft:#525252;--wpshelf-muted:#6b6b6b;--wpshelf-line:#e5e5e5;--wpshelf-line-soft:#f0f0f0;--wpshelf-fill:#0a0a0a;--wpshelf-fill-hover:#333;--wpshelf-fill-ink:#fff;--wpshelf-accent:#2271b1;--wpshelf-accent-dark:#135e96;--wpshelf-accent-50:#f0f6fc;--wpshelf-accent-100:#72aee6;--wpshelf-success:#18794e;--wpshelf-success-dark:#106239;--wpshelf-success-50:#f0f9f4;--wpshelf-warn:#d97706;--wpshelf-warn-dark:#8a5300;--wpshelf-warn-50:#fdf8ec;--wpshelf-danger:#b42318;--wpshelf-danger-50:#fdf3f3;--wpshelf-brand-fill:var(--wpshelf-accent);--wpshelf-hue:247;--wpshelf-chroma:0.10;--wpshelf-control-h:32px;--wpshelf-control-h-sm:26px;--wpshelf-cell-pad-y:10px;--wpshelf-cell-pad-x:14px;--wpshelf-font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;--wpshelf-font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;--wpshelf-text-2xs:10px;--wpshelf-text-xs:11px;--wpshelf-text-sm:12px;--wpshelf-text-base:13px;--wpshelf-text-md:14px;--wpshelf-text-lg:15px;--wpshelf-text-xl:18px;--wpshelf-text-2xl:22px;--wpshelf-text-stat-md:24px;--wpshelf-text-stat-lg:30px;--wpshelf-leading-tight:1.15;--wpshelf-leading-snug:1.4;--wpshelf-leading-normal:1.55;--wpshelf-leading-relaxed:1.65;--wpshelf-weight-normal:400;--wpshelf-weight-medium:500;--wpshelf-weight-semi:600;--wpshelf-weight-bold:700;--wpshelf-tracking-tight:-0.02em;--wpshelf-tracking-normal:0;--wpshelf-tracking-caps:0.04em;--wpshelf-tracking-wide:0.06em;--wpshelf-space-1:4px;--wpshelf-space-2:8px;--wpshelf-space-3:12px;--wpshelf-space-4:16px;--wpshelf-space-5:20px;--wpshelf-space-6:24px;--wpshelf-space-7:28px;--wpshelf-space-8:32px;--wpshelf-space-10:40px;--wpshelf-space-14:56px;--wpshelf-space-16:64px;--wpshelf-sidebar-width:200px;--wpshelf-sidebar-collapsed:48px;--wpshelf-content-max:1280px;--wpshelf-measure:52em;--wpshelf-duration-fast:0.12s;--wpshelf-duration-base:0.15s;--wpshelf-duration-slow:0.20s;--wpshelf-duration-xslow:0.30s;--wpshelf-ease:cubic-bezier(0.4,0,0.2,1);--wpshelf-ease-out:cubic-bezier(0,0,0.2,1);--wpshelf-ease-in:cubic-bezier(0.4,0,1,1);--wpshelf-ease-spring:cubic-bezier(0.32,0.72,0,1);--wpshelf-ease-out-quart:cubic-bezier(0.25,1,0.5,1);--wpshelf-transition-color:color var(--wpshelf-duration-fast) var(--wpshelf-ease),background var(--wpshelf-duration-fast) var(--wpshelf-ease),border-color var(--wpshelf-duration-fast) var(--wpshelf-ease);--wpshelf-transition-lift:transform var(--wpshelf-duration-base) var(--wpshelf-ease),box-shadow var(--wpshelf-duration-base) var(--wpshelf-ease);--wpshelf-transition-progress:width var(--wpshelf-duration-xslow) var(--wpshelf-ease);--wpshelf-radius-xs:6px;--wpshelf-radius-sm:8px;--wpshelf-radius:10px;--wpshelf-radius-lg:12px;--wpshelf-radius-pill:999px;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.04);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.08);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.12);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.06);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.06);--wpshelf-focus-ring:2px solid var(--wpshelf-accent);--wpshelf-focus-ring-offset:2px;--wpshelf-z-base:1;--wpshelf-z-above:10;--wpshelf-z-sticky:100;--wpshelf-z-modal:100000;--wpshelf-z-toast:100100;--wpshelf-z-tooltip:100200}@supports (color:oklch(50% 0.1 200)){.wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-accent:oklch(0.53 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.46 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-100:oklch(0.73 calc(var(--wpshelf-chroma)*0.9) var(--wpshelf-hue));--wpshelf-accent-50:oklch(0.97 0.012 var(--wpshelf-hue))}}[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{color-scheme:dark;--wpshelf-bg:#0a0a0a;--wpshelf-surface:#111;--wpshelf-surface-alt:#171717;--wpshelf-ink:#ededed;--wpshelf-ink-soft:#a1a1a1;--wpshelf-muted:#8f8f8f;--wpshelf-line:#262626;--wpshelf-line-soft:#1f1f1f;--wpshelf-fill:#ededed;--wpshelf-fill-hover:#c9c9c9;--wpshelf-fill-ink:#0a0a0a;--wpshelf-accent:#4f94d4;--wpshelf-accent-dark:#72aee6;--wpshelf-accent-50:#24313e;--wpshelf-success:#3fb950;--wpshelf-success-dark:#56d364;--wpshelf-success-50:#16241a;--wpshelf-warn:#d29922;--wpshelf-warn-dark:#e3b341;--wpshelf-warn-50:#26200f;--wpshelf-danger:#f85149;--wpshelf-danger-50:#2a1615;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.5);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.6);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.4)}@supports (color:color-mix(in oklab,red,blue)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent-50:color-mix(in oklab,var(--wpshelf-accent) 14%,var(--wpshelf-surface));--wpshelf-success-50:color-mix(in oklab,var(--wpshelf-success) 16%,var(--wpshelf-surface));--wpshelf-warn-50:color-mix(in oklab,var(--wpshelf-warn) 16%,var(--wpshelf-surface));--wpshelf-danger-50:color-mix(in oklab,var(--wpshelf-danger) 16%,var(--wpshelf-surface))}}@supports (color:oklch(50% 0.1 200)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent:oklch(0.68 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.76 var(--wpshelf-chroma) var(--wpshelf-hue))}}[data-g-density=compact],[data-g-density=compact] .wpshelf-app,[data-g-density=compact] .wpshelf-app-wrap,[data-wpshelf-density=compact],[data-wpshelf-density=compact] .wpshelf-app,[data-wpshelf-density=compact] .wpshelf-app-wrap{--wpshelf-control-h:28px;--wpshelf-control-h-sm:22px;--wpshelf-cell-pad-y:5px;--wpshelf-cell-pad-x:12px}.wpshelf-chip{align-items:center;background:var(--wpshelf-line-soft);border:1px solid transparent;border-radius:var(--wpshelf-radius-pill);color:var(--wpshelf-ink-soft);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-medium);gap:6px;padding:2px 9px;text-transform:capitalize;white-space:nowrap}.wpshelf-chip:before{background:currentcolor;border-radius:50%;content:"";flex-shrink:0;height:6px;opacity:.9;width:6px}.wpshelf-chip--success{background:var(--wpshelf-success-50);color:var(--wpshelf-success-dark)}.wpshelf-chip--warn{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn-dark)}.wpshelf-chip--danger,.wpshelf-chip--error{background:var(--wpshelf-danger-50);color:var(--wpshelf-danger)}.wpshelf-chip--info{background:var(--wpshelf-accent-50);color:var(--wpshelf-accent-dark)}.wpshelf-chip--muted{background:var(--wpshelf-line-soft);color:var(--wpshelf-ink-soft)}@supports (color:color-mix(in oklab,red,blue)){.wpshelf-chip{border-color:var(--wpshelf-line)}.wpshelf-chip--success{border-color:color-mix(in oklab,var(--wpshelf-success) 22%,transparent)}.wpshelf-chip--warn{border-color:color-mix(in oklab,var(--wpshelf-warn) 26%,transparent)}.wpshelf-chip--danger,.wpshelf-chip--error{border-color:color-mix(in oklab,var(--wpshelf-danger) 22%,transparent)}.wpshelf-chip--info{border-color:color-mix(in oklab,var(--wpshelf-accent) 22%,transparent)}.wpshelf-chip--muted{border-color:var(--wpshelf-line)}}.wpshelf-status-glossary{display:grid;gap:10px 18px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.wpshelf-status-glossary__item{align-items:center;display:flex;gap:10px}.wpshelf-status-glossary__text{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0} 1 .wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-bg:#fafafa;--wpshelf-surface:#fff;--wpshelf-surface-alt:#f5f5f5;--wpshelf-ink:#0a0a0a;--wpshelf-ink-soft:#525252;--wpshelf-muted:#6b6b6b;--wpshelf-line:#e5e5e5;--wpshelf-line-soft:#f0f0f0;--wpshelf-fill:#0a0a0a;--wpshelf-fill-hover:#333;--wpshelf-fill-ink:#fff;--wpshelf-accent:#2271b1;--wpshelf-accent-dark:#135e96;--wpshelf-accent-50:#f0f6fc;--wpshelf-accent-100:#72aee6;--wpshelf-success:#18794e;--wpshelf-success-dark:#106239;--wpshelf-success-50:#f0f9f4;--wpshelf-warn:#d97706;--wpshelf-warn-dark:#8a5300;--wpshelf-warn-50:#fdf8ec;--wpshelf-danger:#b42318;--wpshelf-danger-50:#fdf3f3;--wpshelf-brand-fill:var(--wpshelf-accent);--wpshelf-hue:247;--wpshelf-chroma:0.10;--wpshelf-control-h:32px;--wpshelf-control-h-sm:26px;--wpshelf-cell-pad-y:10px;--wpshelf-cell-pad-x:14px;--wpshelf-font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;--wpshelf-font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;--wpshelf-text-2xs:10px;--wpshelf-text-xs:11px;--wpshelf-text-sm:12px;--wpshelf-text-base:13px;--wpshelf-text-md:14px;--wpshelf-text-lg:15px;--wpshelf-text-xl:18px;--wpshelf-text-2xl:22px;--wpshelf-text-stat-md:24px;--wpshelf-text-stat-lg:30px;--wpshelf-leading-tight:1.15;--wpshelf-leading-snug:1.4;--wpshelf-leading-normal:1.55;--wpshelf-leading-relaxed:1.65;--wpshelf-weight-normal:400;--wpshelf-weight-medium:500;--wpshelf-weight-semi:600;--wpshelf-weight-bold:700;--wpshelf-tracking-tight:-0.02em;--wpshelf-tracking-normal:0;--wpshelf-tracking-caps:0.04em;--wpshelf-tracking-wide:0.06em;--wpshelf-space-1:4px;--wpshelf-space-2:8px;--wpshelf-space-3:12px;--wpshelf-space-4:16px;--wpshelf-space-5:20px;--wpshelf-space-6:24px;--wpshelf-space-7:28px;--wpshelf-space-8:32px;--wpshelf-space-10:40px;--wpshelf-space-14:56px;--wpshelf-space-16:64px;--wpshelf-sidebar-width:200px;--wpshelf-sidebar-collapsed:48px;--wpshelf-content-max:1280px;--wpshelf-measure:52em;--wpshelf-duration-fast:0.12s;--wpshelf-duration-base:0.15s;--wpshelf-duration-slow:0.20s;--wpshelf-duration-xslow:0.30s;--wpshelf-ease:cubic-bezier(0.4,0,0.2,1);--wpshelf-ease-out:cubic-bezier(0,0,0.2,1);--wpshelf-ease-in:cubic-bezier(0.4,0,1,1);--wpshelf-ease-spring:cubic-bezier(0.32,0.72,0,1);--wpshelf-ease-out-quart:cubic-bezier(0.25,1,0.5,1);--wpshelf-transition-color:color var(--wpshelf-duration-fast) var(--wpshelf-ease),background var(--wpshelf-duration-fast) var(--wpshelf-ease),border-color var(--wpshelf-duration-fast) var(--wpshelf-ease);--wpshelf-transition-lift:transform var(--wpshelf-duration-base) var(--wpshelf-ease),box-shadow var(--wpshelf-duration-base) var(--wpshelf-ease);--wpshelf-transition-progress:width var(--wpshelf-duration-xslow) var(--wpshelf-ease);--wpshelf-radius-xs:6px;--wpshelf-radius-sm:8px;--wpshelf-radius:10px;--wpshelf-radius-lg:12px;--wpshelf-radius-pill:999px;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.04);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.08);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.12);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.06);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.06);--wpshelf-focus-ring:2px solid var(--wpshelf-accent);--wpshelf-focus-ring-offset:2px;--wpshelf-z-base:1;--wpshelf-z-above:10;--wpshelf-z-sticky:100;--wpshelf-z-modal:100000;--wpshelf-z-toast:100100;--wpshelf-z-tooltip:100200}@supports (color:oklch(50% 0.1 200)){.wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-accent:oklch(0.53 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.46 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-100:oklch(0.73 calc(var(--wpshelf-chroma)*0.9) var(--wpshelf-hue));--wpshelf-accent-50:oklch(0.97 0.012 var(--wpshelf-hue))}}[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{color-scheme:dark;--wpshelf-bg:#0a0a0a;--wpshelf-surface:#111;--wpshelf-surface-alt:#171717;--wpshelf-ink:#ededed;--wpshelf-ink-soft:#a1a1a1;--wpshelf-muted:#8f8f8f;--wpshelf-line:#262626;--wpshelf-line-soft:#1f1f1f;--wpshelf-fill:#ededed;--wpshelf-fill-hover:#c9c9c9;--wpshelf-fill-ink:#0a0a0a;--wpshelf-accent:#4f94d4;--wpshelf-accent-dark:#72aee6;--wpshelf-accent-50:#24313e;--wpshelf-success:#3fb950;--wpshelf-success-dark:#56d364;--wpshelf-success-50:#16241a;--wpshelf-warn:#d29922;--wpshelf-warn-dark:#e3b341;--wpshelf-warn-50:#26200f;--wpshelf-danger:#f85149;--wpshelf-danger-50:#2a1615;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.5);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.6);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.4)}@supports (color:color-mix(in oklab,red,blue)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent-50:color-mix(in oklab,var(--wpshelf-accent) 14%,var(--wpshelf-surface));--wpshelf-success-50:color-mix(in oklab,var(--wpshelf-success) 16%,var(--wpshelf-surface));--wpshelf-warn-50:color-mix(in oklab,var(--wpshelf-warn) 16%,var(--wpshelf-surface));--wpshelf-danger-50:color-mix(in oklab,var(--wpshelf-danger) 16%,var(--wpshelf-surface))}}@supports (color:oklch(50% 0.1 200)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent:oklch(0.68 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.76 var(--wpshelf-chroma) var(--wpshelf-hue))}}[data-g-density=compact],[data-g-density=compact] .wpshelf-app,[data-g-density=compact] .wpshelf-app-wrap,[data-wpshelf-density=compact],[data-wpshelf-density=compact] .wpshelf-app,[data-wpshelf-density=compact] .wpshelf-app-wrap{--wpshelf-control-h:28px;--wpshelf-control-h-sm:22px;--wpshelf-cell-pad-y:5px;--wpshelf-cell-pad-x:12px}.wpshelf-chip{align-items:center;background:var(--wpshelf-line-soft);border:1px solid transparent;border-radius:var(--wpshelf-radius-pill);color:var(--wpshelf-ink-soft);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-medium);gap:6px;padding:2px 9px;text-transform:capitalize;white-space:nowrap}.wpshelf-chip:before{background:currentcolor;border-radius:50%;content:"";flex-shrink:0;height:6px;opacity:.9;width:6px}.wpshelf-chip--success{background:var(--wpshelf-success-50);color:var(--wpshelf-success-dark)}.wpshelf-chip--warn{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn-dark)}.wpshelf-chip--danger,.wpshelf-chip--error{background:var(--wpshelf-danger-50);color:var(--wpshelf-danger)}.wpshelf-chip--info{background:var(--wpshelf-accent-50);color:var(--wpshelf-accent-dark)}.wpshelf-chip--muted{background:var(--wpshelf-line-soft);color:var(--wpshelf-ink-soft)}@supports (color:color-mix(in oklab,red,blue)){.wpshelf-chip{border-color:var(--wpshelf-line)}.wpshelf-chip--success{border-color:color-mix(in oklab,var(--wpshelf-success) 22%,transparent)}.wpshelf-chip--warn{border-color:color-mix(in oklab,var(--wpshelf-warn) 26%,transparent)}.wpshelf-chip--danger,.wpshelf-chip--error{border-color:color-mix(in oklab,var(--wpshelf-danger) 22%,transparent)}.wpshelf-chip--info{border-color:color-mix(in oklab,var(--wpshelf-accent) 22%,transparent)}.wpshelf-chip--muted{border-color:var(--wpshelf-line)}}.wpshelf-status-glossary{display:grid;gap:10px 18px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.wpshelf-status-glossary__item{align-items:center;display:flex;gap:10px}.wpshelf-status-glossary__text{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0}.wpshelf-cell--money{color:var(--wpshelf-ink);font-variant-numeric:tabular-nums;text-align:left}.wpshelf-cell--money.is-negative{color:var(--wpshelf-danger)}.wpshelf-cell--money.is-muted{color:var(--wpshelf-muted)}.wpshelf-ledger{display:flex;flex-direction:column;gap:var(--wpshelf-space-2);margin:0}.wpshelf-ledger__row{align-items:baseline;display:flex;gap:var(--wpshelf-space-4);justify-content:space-between;margin:0}.wpshelf-ledger__row dt{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-base);margin:0}.wpshelf-ledger__row dd{margin:0}.wpshelf-ledger__row--sub{padding-right:var(--wpshelf-space-4)}.wpshelf-ledger__row--sub dt{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm)}.wpshelf-ledger__total{border-top:1px solid var(--wpshelf-line);margin-top:var(--wpshelf-space-1);padding-top:var(--wpshelf-space-2)}.wpshelf-ledger__total dd,.wpshelf-ledger__total dt{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-semi)}.wpshelf-ledger__note{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0} 2 2 .wpshelf-editor-sidebar{color:var(--wpshelf-ink);display:flex;flex-direction:column;font-size:var(--wpshelf-text-base);gap:var(--wpshelf-space-4);padding:var(--wpshelf-space-4)}.wpshelf-editor-sidebar__loading{display:flex;justify-content:center;padding:var(--wpshelf-space-5) 0}.wpshelf-editor-sidebar__empty{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-base);line-height:var(--wpshelf-leading-normal);margin:0}.wpshelf-provider-status{background:var(--wpshelf-surface);border:1px solid var(--wpshelf-line);border-radius:var(--wpshelf-radius-sm);display:flex;flex-direction:column;gap:var(--wpshelf-space-2);padding:var(--wpshelf-space-3)}.wpshelf-provider-status__header{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between}.wpshelf-provider-status__name{color:var(--wpshelf-ink);font-size:var(--wpshelf-text-md)}.wpshelf-provider-status__badge{align-items:center;border-radius:var(--wpshelf-radius-pill);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-semi);padding:2px 8px}.wpshelf-provider-status__badge--connected{background:var(--wpshelf-success-50);color:var(--wpshelf-success)}.wpshelf-provider-status__badge--disconnected{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn)}.wpshelf-provider-status__actions{align-items:center;display:flex;gap:var(--wpshelf-space-2)}.wpshelf-language-switcher{display:flex;flex-wrap:wrap;gap:var(--wpshelf-space-1)}.wpshelf-language-switcher__btn{flex:0 0 auto}.wpshelf-language-switcher__btn--active{font-weight:var(--wpshelf-weight-semi)}.wpshelf-language-switcher__code{opacity:.7}.wpshelf-language-switcher__default{color:var(--wpshelf-muted)}.wpshelf-language-switcher__native{color:var(--wpshelf-ink-soft)}.wpshelf-language-switcher__empty{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);margin:0}.wpshelf-translation-row{border-bottom:1px solid var(--wpshelf-line-soft);display:flex;flex-direction:column;gap:2px;padding:var(--wpshelf-space-2) 0;width:100%}.wpshelf-translation-row__original{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-semi);word-break:break-word}.wpshelf-translation-row__translated{color:var(--wpshelf-ink-soft);word-break:break-word}.wpshelf-translation-row__meta{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between;margin-top:var(--wpshelf-space-1)}.wpshelf-inline-editor{background:var(--wpshelf-surface);border:1px solid var(--wpshelf-accent-100);border-radius:var(--wpshelf-radius-sm);display:flex;flex-direction:column;gap:var(--wpshelf-space-2);padding:var(--wpshelf-space-3);width:100%}.wpshelf-inline-editor__original{display:flex;flex-direction:column;gap:2px}.wpshelf-inline-editor__label{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-bold);letter-spacing:var(--wpshelf-tracking-caps);text-transform:uppercase}.wpshelf-inline-editor__text{color:var(--wpshelf-ink-soft);line-height:var(--wpshelf-leading-normal);max-height:7.5em;overflow-y:auto;word-break:break-word}.wpshelf-inline-editor__status{align-items:center;display:flex}.wpshelf-inline-editor__textarea textarea{font-size:var(--wpshelf-text-base);line-height:var(--wpshelf-leading-normal);width:100%}.wpshelf-inline-editor__actions,.wpshelf-pagination{align-items:center;display:flex;gap:var(--wpshelf-space-2)}.wpshelf-pagination{justify-content:space-between;margin-top:var(--wpshelf-space-3)}.wpshelf-pagination__info{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);font-variant-numeric:tabular-nums}.wpshelf-provider-status__result{margin:0}.wpshelf-string-list{width:100%}.wpshelf-string-list--empty{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);padding:var(--wpshelf-space-3) 0}.wpshelf-string-list--empty p{margin:0}.wpshelf-string-list__table{border-collapse:collapse;font-size:var(--wpshelf-text-sm);width:100%}.wpshelf-string-list__table th{border-bottom:1px solid var(--wpshelf-line);color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-semi);letter-spacing:var(--wpshelf-tracking-caps);padding:var(--wpshelf-space-1) var(--wpshelf-space-2);text-align:right;text-transform:uppercase;white-space:nowrap}.wpshelf-string-list__table td{border-bottom:1px solid var(--wpshelf-line-soft);padding:var(--wpshelf-space-2);vertical-align:top;word-break:break-word}.wpshelf-string-list__row:last-child td{border-bottom:none}.wpshelf-string-list__cell-status,.wpshelf-string-list__th-status{white-space:nowrap;width:1%}.wpshelf-string-list__cell-original{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-medium)}.wpshelf-string-list__cell-provider,.wpshelf-string-list__cell-translation{color:var(--wpshelf-ink-soft)}.wpshelf-string-list__th-original,.wpshelf-string-list__th-translation{width:40%}.wpshelf-string-list__cell-provider,.wpshelf-string-list__th-provider{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);white-space:nowrap;width:1%}.wpshelf-string-list__preview{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap}.wpshelf-string-list__pagination{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between;margin-top:var(--wpshelf-space-3)}.wpshelf-string-list__page-info{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);font-variant-numeric:tabular-nums} -
gloty/tags/1.64.0/build/style-gloty-editor-sidebar.css
r3688478 r3748411 1 .wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-bg:#fafafa;--wpshelf-surface:#fff;--wpshelf-surface-alt:#f5f5f5;--wpshelf-ink:#0a0a0a;--wpshelf-ink-soft:#525252;--wpshelf-muted:#6b6b6b;--wpshelf-line:#e5e5e5;--wpshelf-line-soft:#f0f0f0;--wpshelf-fill:#0a0a0a;--wpshelf-fill-hover:#333;--wpshelf-fill-ink:#fff;--wpshelf-accent:#2271b1;--wpshelf-accent-dark:#135e96;--wpshelf-accent-50:#f0f6fc;--wpshelf-accent-100:#72aee6;--wpshelf-success:#18794e;--wpshelf-success-dark:#106239;--wpshelf-success-50:#f0f9f4;--wpshelf-warn:#d97706;--wpshelf-warn-dark:#8a5300;--wpshelf-warn-50:#fdf8ec;--wpshelf-danger:#b42318;--wpshelf-danger-50:#fdf3f3;--wpshelf-brand-fill:var(--wpshelf-accent);--wpshelf-hue:247;--wpshelf-chroma:0.10;--wpshelf-control-h:32px;--wpshelf-control-h-sm:26px;--wpshelf-cell-pad-y:10px;--wpshelf-cell-pad-x:14px;--wpshelf-font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;--wpshelf-font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;--wpshelf-text-2xs:10px;--wpshelf-text-xs:11px;--wpshelf-text-sm:12px;--wpshelf-text-base:13px;--wpshelf-text-md:14px;--wpshelf-text-lg:15px;--wpshelf-text-xl:18px;--wpshelf-text-2xl:22px;--wpshelf-text-stat-md:24px;--wpshelf-text-stat-lg:30px;--wpshelf-leading-tight:1.15;--wpshelf-leading-snug:1.4;--wpshelf-leading-normal:1.55;--wpshelf-leading-relaxed:1.65;--wpshelf-weight-normal:400;--wpshelf-weight-medium:500;--wpshelf-weight-semi:600;--wpshelf-weight-bold:700;--wpshelf-tracking-tight:-0.02em;--wpshelf-tracking-normal:0;--wpshelf-tracking-caps:0.04em;--wpshelf-tracking-wide:0.06em;--wpshelf-space-1:4px;--wpshelf-space-2:8px;--wpshelf-space-3:12px;--wpshelf-space-4:16px;--wpshelf-space-5:20px;--wpshelf-space-6:24px;--wpshelf-space-7:28px;--wpshelf-space-8:32px;--wpshelf-space-10:40px;--wpshelf-space-14:56px;--wpshelf-space-16:64px;--wpshelf-sidebar-width:200px;--wpshelf-sidebar-collapsed:48px;--wpshelf-content-max:1280px;--wpshelf-measure:52em;--wpshelf-duration-fast:0.12s;--wpshelf-duration-base:0.15s;--wpshelf-duration-slow:0.20s;--wpshelf-duration-xslow:0.30s;--wpshelf-ease:cubic-bezier(0.4,0,0.2,1);--wpshelf-ease-out:cubic-bezier(0,0,0.2,1);--wpshelf-ease-in:cubic-bezier(0.4,0,1,1);--wpshelf-ease-spring:cubic-bezier(0.32,0.72,0,1);--wpshelf-ease-out-quart:cubic-bezier(0.25,1,0.5,1);--wpshelf-transition-color:color var(--wpshelf-duration-fast) var(--wpshelf-ease),background var(--wpshelf-duration-fast) var(--wpshelf-ease),border-color var(--wpshelf-duration-fast) var(--wpshelf-ease);--wpshelf-transition-lift:transform var(--wpshelf-duration-base) var(--wpshelf-ease),box-shadow var(--wpshelf-duration-base) var(--wpshelf-ease);--wpshelf-transition-progress:width var(--wpshelf-duration-xslow) var(--wpshelf-ease);--wpshelf-radius-xs:6px;--wpshelf-radius-sm:8px;--wpshelf-radius:10px;--wpshelf-radius-lg:12px;--wpshelf-radius-pill:999px;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.04);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.08);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.12);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.06);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.06);--wpshelf-focus-ring:2px solid var(--wpshelf-accent);--wpshelf-focus-ring-offset:2px;--wpshelf-z-base:1;--wpshelf-z-above:10;--wpshelf-z-sticky:100;--wpshelf-z-modal:100000;--wpshelf-z-toast:100100;--wpshelf-z-tooltip:100200}@supports (color:oklch(50% 0.1 200)){.wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-accent:oklch(0.53 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.46 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-100:oklch(0.73 calc(var(--wpshelf-chroma)*0.9) var(--wpshelf-hue));--wpshelf-accent-50:oklch(0.97 0.012 var(--wpshelf-hue))}}[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{color-scheme:dark;--wpshelf-bg:#0a0a0a;--wpshelf-surface:#111;--wpshelf-surface-alt:#171717;--wpshelf-ink:#ededed;--wpshelf-ink-soft:#a1a1a1;--wpshelf-muted:#8f8f8f;--wpshelf-line:#262626;--wpshelf-line-soft:#1f1f1f;--wpshelf-fill:#ededed;--wpshelf-fill-hover:#c9c9c9;--wpshelf-fill-ink:#0a0a0a;--wpshelf-accent:#4f94d4;--wpshelf-accent-dark:#72aee6;--wpshelf-accent-50:#24313e;--wpshelf-success:#3fb950;--wpshelf-success-dark:#56d364;--wpshelf-success-50:#16241a;--wpshelf-warn:#d29922;--wpshelf-warn-dark:#e3b341;--wpshelf-warn-50:#26200f;--wpshelf-danger:#f85149;--wpshelf-danger-50:#2a1615;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.5);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.6);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.4)}@supports (color:color-mix(in oklab,red,blue)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent-50:color-mix(in oklab,var(--wpshelf-accent) 14%,var(--wpshelf-surface));--wpshelf-success-50:color-mix(in oklab,var(--wpshelf-success) 16%,var(--wpshelf-surface));--wpshelf-warn-50:color-mix(in oklab,var(--wpshelf-warn) 16%,var(--wpshelf-surface));--wpshelf-danger-50:color-mix(in oklab,var(--wpshelf-danger) 16%,var(--wpshelf-surface))}}@supports (color:oklch(50% 0.1 200)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent:oklch(0.68 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.76 var(--wpshelf-chroma) var(--wpshelf-hue))}}[data-g-density=compact],[data-g-density=compact] .wpshelf-app,[data-g-density=compact] .wpshelf-app-wrap,[data-wpshelf-density=compact],[data-wpshelf-density=compact] .wpshelf-app,[data-wpshelf-density=compact] .wpshelf-app-wrap{--wpshelf-control-h:28px;--wpshelf-control-h-sm:22px;--wpshelf-cell-pad-y:5px;--wpshelf-cell-pad-x:12px}.wpshelf-chip{align-items:center;background:var(--wpshelf-line-soft);border:1px solid transparent;border-radius:var(--wpshelf-radius-pill);color:var(--wpshelf-ink-soft);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-medium);gap:6px;padding:2px 9px;text-transform:capitalize;white-space:nowrap}.wpshelf-chip:before{background:currentcolor;border-radius:50%;content:"";flex-shrink:0;height:6px;opacity:.9;width:6px}.wpshelf-chip--success{background:var(--wpshelf-success-50);color:var(--wpshelf-success-dark)}.wpshelf-chip--warn{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn-dark)}.wpshelf-chip--danger,.wpshelf-chip--error{background:var(--wpshelf-danger-50);color:var(--wpshelf-danger)}.wpshelf-chip--info{background:var(--wpshelf-accent-50);color:var(--wpshelf-accent-dark)}.wpshelf-chip--muted{background:var(--wpshelf-line-soft);color:var(--wpshelf-ink-soft)}@supports (color:color-mix(in oklab,red,blue)){.wpshelf-chip{border-color:var(--wpshelf-line)}.wpshelf-chip--success{border-color:color-mix(in oklab,var(--wpshelf-success) 22%,transparent)}.wpshelf-chip--warn{border-color:color-mix(in oklab,var(--wpshelf-warn) 26%,transparent)}.wpshelf-chip--danger,.wpshelf-chip--error{border-color:color-mix(in oklab,var(--wpshelf-danger) 22%,transparent)}.wpshelf-chip--info{border-color:color-mix(in oklab,var(--wpshelf-accent) 22%,transparent)}.wpshelf-chip--muted{border-color:var(--wpshelf-line)}}.wpshelf-status-glossary{display:grid;gap:10px 18px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.wpshelf-status-glossary__item{align-items:center;display:flex;gap:10px}.wpshelf-status-glossary__text{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0} 1 .wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-bg:#fafafa;--wpshelf-surface:#fff;--wpshelf-surface-alt:#f5f5f5;--wpshelf-ink:#0a0a0a;--wpshelf-ink-soft:#525252;--wpshelf-muted:#6b6b6b;--wpshelf-line:#e5e5e5;--wpshelf-line-soft:#f0f0f0;--wpshelf-fill:#0a0a0a;--wpshelf-fill-hover:#333;--wpshelf-fill-ink:#fff;--wpshelf-accent:#2271b1;--wpshelf-accent-dark:#135e96;--wpshelf-accent-50:#f0f6fc;--wpshelf-accent-100:#72aee6;--wpshelf-success:#18794e;--wpshelf-success-dark:#106239;--wpshelf-success-50:#f0f9f4;--wpshelf-warn:#d97706;--wpshelf-warn-dark:#8a5300;--wpshelf-warn-50:#fdf8ec;--wpshelf-danger:#b42318;--wpshelf-danger-50:#fdf3f3;--wpshelf-brand-fill:var(--wpshelf-accent);--wpshelf-hue:247;--wpshelf-chroma:0.10;--wpshelf-control-h:32px;--wpshelf-control-h-sm:26px;--wpshelf-cell-pad-y:10px;--wpshelf-cell-pad-x:14px;--wpshelf-font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;--wpshelf-font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;--wpshelf-text-2xs:10px;--wpshelf-text-xs:11px;--wpshelf-text-sm:12px;--wpshelf-text-base:13px;--wpshelf-text-md:14px;--wpshelf-text-lg:15px;--wpshelf-text-xl:18px;--wpshelf-text-2xl:22px;--wpshelf-text-stat-md:24px;--wpshelf-text-stat-lg:30px;--wpshelf-leading-tight:1.15;--wpshelf-leading-snug:1.4;--wpshelf-leading-normal:1.55;--wpshelf-leading-relaxed:1.65;--wpshelf-weight-normal:400;--wpshelf-weight-medium:500;--wpshelf-weight-semi:600;--wpshelf-weight-bold:700;--wpshelf-tracking-tight:-0.02em;--wpshelf-tracking-normal:0;--wpshelf-tracking-caps:0.04em;--wpshelf-tracking-wide:0.06em;--wpshelf-space-1:4px;--wpshelf-space-2:8px;--wpshelf-space-3:12px;--wpshelf-space-4:16px;--wpshelf-space-5:20px;--wpshelf-space-6:24px;--wpshelf-space-7:28px;--wpshelf-space-8:32px;--wpshelf-space-10:40px;--wpshelf-space-14:56px;--wpshelf-space-16:64px;--wpshelf-sidebar-width:200px;--wpshelf-sidebar-collapsed:48px;--wpshelf-content-max:1280px;--wpshelf-measure:52em;--wpshelf-duration-fast:0.12s;--wpshelf-duration-base:0.15s;--wpshelf-duration-slow:0.20s;--wpshelf-duration-xslow:0.30s;--wpshelf-ease:cubic-bezier(0.4,0,0.2,1);--wpshelf-ease-out:cubic-bezier(0,0,0.2,1);--wpshelf-ease-in:cubic-bezier(0.4,0,1,1);--wpshelf-ease-spring:cubic-bezier(0.32,0.72,0,1);--wpshelf-ease-out-quart:cubic-bezier(0.25,1,0.5,1);--wpshelf-transition-color:color var(--wpshelf-duration-fast) var(--wpshelf-ease),background var(--wpshelf-duration-fast) var(--wpshelf-ease),border-color var(--wpshelf-duration-fast) var(--wpshelf-ease);--wpshelf-transition-lift:transform var(--wpshelf-duration-base) var(--wpshelf-ease),box-shadow var(--wpshelf-duration-base) var(--wpshelf-ease);--wpshelf-transition-progress:width var(--wpshelf-duration-xslow) var(--wpshelf-ease);--wpshelf-radius-xs:6px;--wpshelf-radius-sm:8px;--wpshelf-radius:10px;--wpshelf-radius-lg:12px;--wpshelf-radius-pill:999px;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.04);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.08);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.12);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.06);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.06);--wpshelf-focus-ring:2px solid var(--wpshelf-accent);--wpshelf-focus-ring-offset:2px;--wpshelf-z-base:1;--wpshelf-z-above:10;--wpshelf-z-sticky:100;--wpshelf-z-modal:100000;--wpshelf-z-toast:100100;--wpshelf-z-tooltip:100200}@supports (color:oklch(50% 0.1 200)){.wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-accent:oklch(0.53 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.46 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-100:oklch(0.73 calc(var(--wpshelf-chroma)*0.9) var(--wpshelf-hue));--wpshelf-accent-50:oklch(0.97 0.012 var(--wpshelf-hue))}}[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{color-scheme:dark;--wpshelf-bg:#0a0a0a;--wpshelf-surface:#111;--wpshelf-surface-alt:#171717;--wpshelf-ink:#ededed;--wpshelf-ink-soft:#a1a1a1;--wpshelf-muted:#8f8f8f;--wpshelf-line:#262626;--wpshelf-line-soft:#1f1f1f;--wpshelf-fill:#ededed;--wpshelf-fill-hover:#c9c9c9;--wpshelf-fill-ink:#0a0a0a;--wpshelf-accent:#4f94d4;--wpshelf-accent-dark:#72aee6;--wpshelf-accent-50:#24313e;--wpshelf-success:#3fb950;--wpshelf-success-dark:#56d364;--wpshelf-success-50:#16241a;--wpshelf-warn:#d29922;--wpshelf-warn-dark:#e3b341;--wpshelf-warn-50:#26200f;--wpshelf-danger:#f85149;--wpshelf-danger-50:#2a1615;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.5);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.6);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.4)}@supports (color:color-mix(in oklab,red,blue)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent-50:color-mix(in oklab,var(--wpshelf-accent) 14%,var(--wpshelf-surface));--wpshelf-success-50:color-mix(in oklab,var(--wpshelf-success) 16%,var(--wpshelf-surface));--wpshelf-warn-50:color-mix(in oklab,var(--wpshelf-warn) 16%,var(--wpshelf-surface));--wpshelf-danger-50:color-mix(in oklab,var(--wpshelf-danger) 16%,var(--wpshelf-surface))}}@supports (color:oklch(50% 0.1 200)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent:oklch(0.68 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.76 var(--wpshelf-chroma) var(--wpshelf-hue))}}[data-g-density=compact],[data-g-density=compact] .wpshelf-app,[data-g-density=compact] .wpshelf-app-wrap,[data-wpshelf-density=compact],[data-wpshelf-density=compact] .wpshelf-app,[data-wpshelf-density=compact] .wpshelf-app-wrap{--wpshelf-control-h:28px;--wpshelf-control-h-sm:22px;--wpshelf-cell-pad-y:5px;--wpshelf-cell-pad-x:12px}.wpshelf-chip{align-items:center;background:var(--wpshelf-line-soft);border:1px solid transparent;border-radius:var(--wpshelf-radius-pill);color:var(--wpshelf-ink-soft);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-medium);gap:6px;padding:2px 9px;text-transform:capitalize;white-space:nowrap}.wpshelf-chip:before{background:currentcolor;border-radius:50%;content:"";flex-shrink:0;height:6px;opacity:.9;width:6px}.wpshelf-chip--success{background:var(--wpshelf-success-50);color:var(--wpshelf-success-dark)}.wpshelf-chip--warn{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn-dark)}.wpshelf-chip--danger,.wpshelf-chip--error{background:var(--wpshelf-danger-50);color:var(--wpshelf-danger)}.wpshelf-chip--info{background:var(--wpshelf-accent-50);color:var(--wpshelf-accent-dark)}.wpshelf-chip--muted{background:var(--wpshelf-line-soft);color:var(--wpshelf-ink-soft)}@supports (color:color-mix(in oklab,red,blue)){.wpshelf-chip{border-color:var(--wpshelf-line)}.wpshelf-chip--success{border-color:color-mix(in oklab,var(--wpshelf-success) 22%,transparent)}.wpshelf-chip--warn{border-color:color-mix(in oklab,var(--wpshelf-warn) 26%,transparent)}.wpshelf-chip--danger,.wpshelf-chip--error{border-color:color-mix(in oklab,var(--wpshelf-danger) 22%,transparent)}.wpshelf-chip--info{border-color:color-mix(in oklab,var(--wpshelf-accent) 22%,transparent)}.wpshelf-chip--muted{border-color:var(--wpshelf-line)}}.wpshelf-status-glossary{display:grid;gap:10px 18px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.wpshelf-status-glossary__item{align-items:center;display:flex;gap:10px}.wpshelf-status-glossary__text{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0}.wpshelf-cell--money{color:var(--wpshelf-ink);font-variant-numeric:tabular-nums;text-align:right}.wpshelf-cell--money.is-negative{color:var(--wpshelf-danger)}.wpshelf-cell--money.is-muted{color:var(--wpshelf-muted)}.wpshelf-ledger{display:flex;flex-direction:column;gap:var(--wpshelf-space-2);margin:0}.wpshelf-ledger__row{align-items:baseline;display:flex;gap:var(--wpshelf-space-4);justify-content:space-between;margin:0}.wpshelf-ledger__row dt{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-base);margin:0}.wpshelf-ledger__row dd{margin:0}.wpshelf-ledger__row--sub{padding-left:var(--wpshelf-space-4)}.wpshelf-ledger__row--sub dt{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm)}.wpshelf-ledger__total{border-top:1px solid var(--wpshelf-line);margin-top:var(--wpshelf-space-1);padding-top:var(--wpshelf-space-2)}.wpshelf-ledger__total dd,.wpshelf-ledger__total dt{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-semi)}.wpshelf-ledger__note{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0} 2 2 .wpshelf-editor-sidebar{color:var(--wpshelf-ink);display:flex;flex-direction:column;font-size:var(--wpshelf-text-base);gap:var(--wpshelf-space-4);padding:var(--wpshelf-space-4)}.wpshelf-editor-sidebar__loading{display:flex;justify-content:center;padding:var(--wpshelf-space-5) 0}.wpshelf-editor-sidebar__empty{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-base);line-height:var(--wpshelf-leading-normal);margin:0}.wpshelf-provider-status{background:var(--wpshelf-surface);border:1px solid var(--wpshelf-line);border-radius:var(--wpshelf-radius-sm);display:flex;flex-direction:column;gap:var(--wpshelf-space-2);padding:var(--wpshelf-space-3)}.wpshelf-provider-status__header{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between}.wpshelf-provider-status__name{color:var(--wpshelf-ink);font-size:var(--wpshelf-text-md)}.wpshelf-provider-status__badge{align-items:center;border-radius:var(--wpshelf-radius-pill);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-semi);padding:2px 8px}.wpshelf-provider-status__badge--connected{background:var(--wpshelf-success-50);color:var(--wpshelf-success)}.wpshelf-provider-status__badge--disconnected{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn)}.wpshelf-provider-status__actions{align-items:center;display:flex;gap:var(--wpshelf-space-2)}.wpshelf-language-switcher{display:flex;flex-wrap:wrap;gap:var(--wpshelf-space-1)}.wpshelf-language-switcher__btn{flex:0 0 auto}.wpshelf-language-switcher__btn--active{font-weight:var(--wpshelf-weight-semi)}.wpshelf-language-switcher__code{opacity:.7}.wpshelf-language-switcher__default{color:var(--wpshelf-muted)}.wpshelf-language-switcher__native{color:var(--wpshelf-ink-soft)}.wpshelf-language-switcher__empty{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);margin:0}.wpshelf-translation-row{border-bottom:1px solid var(--wpshelf-line-soft);display:flex;flex-direction:column;gap:2px;padding:var(--wpshelf-space-2) 0;width:100%}.wpshelf-translation-row__original{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-semi);word-break:break-word}.wpshelf-translation-row__translated{color:var(--wpshelf-ink-soft);word-break:break-word}.wpshelf-translation-row__meta{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between;margin-top:var(--wpshelf-space-1)}.wpshelf-inline-editor{background:var(--wpshelf-surface);border:1px solid var(--wpshelf-accent-100);border-radius:var(--wpshelf-radius-sm);display:flex;flex-direction:column;gap:var(--wpshelf-space-2);padding:var(--wpshelf-space-3);width:100%}.wpshelf-inline-editor__original{display:flex;flex-direction:column;gap:2px}.wpshelf-inline-editor__label{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-bold);letter-spacing:var(--wpshelf-tracking-caps);text-transform:uppercase}.wpshelf-inline-editor__text{color:var(--wpshelf-ink-soft);line-height:var(--wpshelf-leading-normal);max-height:7.5em;overflow-y:auto;word-break:break-word}.wpshelf-inline-editor__status{align-items:center;display:flex}.wpshelf-inline-editor__textarea textarea{font-size:var(--wpshelf-text-base);line-height:var(--wpshelf-leading-normal);width:100%}.wpshelf-inline-editor__actions,.wpshelf-pagination{align-items:center;display:flex;gap:var(--wpshelf-space-2)}.wpshelf-pagination{justify-content:space-between;margin-top:var(--wpshelf-space-3)}.wpshelf-pagination__info{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);font-variant-numeric:tabular-nums}.wpshelf-provider-status__result{margin:0}.wpshelf-string-list{width:100%}.wpshelf-string-list--empty{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);padding:var(--wpshelf-space-3) 0}.wpshelf-string-list--empty p{margin:0}.wpshelf-string-list__table{border-collapse:collapse;font-size:var(--wpshelf-text-sm);width:100%}.wpshelf-string-list__table th{border-bottom:1px solid var(--wpshelf-line);color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-semi);letter-spacing:var(--wpshelf-tracking-caps);padding:var(--wpshelf-space-1) var(--wpshelf-space-2);text-align:left;text-transform:uppercase;white-space:nowrap}.wpshelf-string-list__table td{border-bottom:1px solid var(--wpshelf-line-soft);padding:var(--wpshelf-space-2);vertical-align:top;word-break:break-word}.wpshelf-string-list__row:last-child td{border-bottom:none}.wpshelf-string-list__cell-status,.wpshelf-string-list__th-status{white-space:nowrap;width:1%}.wpshelf-string-list__cell-original{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-medium)}.wpshelf-string-list__cell-provider,.wpshelf-string-list__cell-translation{color:var(--wpshelf-ink-soft)}.wpshelf-string-list__th-original,.wpshelf-string-list__th-translation{width:40%}.wpshelf-string-list__cell-provider,.wpshelf-string-list__th-provider{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);white-space:nowrap;width:1%}.wpshelf-string-list__preview{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap}.wpshelf-string-list__pagination{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between;margin-top:var(--wpshelf-space-3)}.wpshelf-string-list__page-info{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);font-variant-numeric:tabular-nums} -
gloty/tags/1.64.0/composer.lock
r3723660 r3748411 9 9 { 10 10 "name": "wp-shelf/html-parser", 11 "version": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",11 "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 12 12 "dist": { 13 13 "type": "path", … … 46 46 { 47 47 "name": "wp-shelf/platform", 48 "version": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",48 "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 49 49 "dist": { 50 50 "type": "path", -
gloty/tags/1.64.0/gloty.php
r3723660 r3748411 4 4 * Plugin URI: https://wp-shelf.com/gloty 5 5 * Description: AI translation for WordPress in 38 languages. Every translation is stored in your own database and served locally — no API call at render time. 6 * Version: 1.6 3.36 * Version: 1.64.0 7 7 * Author: WP Shelf 8 8 * Author URI: https://wp-shelf.com … … 61 61 * Plugin constants. 62 62 */ 63 define( 'GLOTY_VERSION', '1.6 3.3' );63 define( 'GLOTY_VERSION', '1.64.0' ); 64 64 define( 'GLOTY_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 65 65 define( 'GLOTY_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); -
gloty/tags/1.64.0/includes/API/class-admin-rest-routes.php
r3723648 r3748411 1949 1949 if ( null === $status ) { 1950 1950 return new WP_REST_Response( [ 1951 'ok' => true, 1952 'has_key' => LicenseClient::has_key(), 1953 'key_masked' => LicenseClient::get_masked_license_key(), 1954 'status' => null, 1951 'ok' => true, 1952 'has_key' => LicenseClient::has_key(), 1953 'key_masked' => LicenseClient::get_masked_license_key(), 1954 'status' => null, 1955 // Null is either an outage or a key the service no 1956 // longer accepts (rotated, or the licence is gone); 1957 // the panel words the two differently. 1958 'key_refused' => LicenseClient::has_key() && LicenseClient::is_key_refused(), 1955 1959 ] ); 1956 1960 } 1957 1961 return new WP_REST_Response( [ 1958 'ok' => true, 1959 'has_key' => true, 1960 'key_masked' => LicenseClient::get_masked_license_key(), 1961 'status' => $status->to_array(), 1962 'ok' => true, 1963 'has_key' => true, 1964 'key_masked' => LicenseClient::get_masked_license_key(), 1965 'status' => $status->to_array(), 1966 'key_refused' => false, 1962 1967 ] ); 1963 1968 }, -
gloty/tags/1.64.0/includes/Admin/class-admin-boot-data.php
r3692917 r3748411 249 249 'serverUrl' => $server_url, 250 250 'status' => $status?->to_array(), 251 // Only meaningful when status is null: the service answered and no 252 // longer accepts the key, as opposed to not answering at all. 253 'keyRefused' => null === $status && LicenseClient::is_key_refused(), 251 254 ]; 252 255 } -
gloty/tags/1.64.0/includes/Admin/class-issues-service.php
r3723648 r3748411 179 179 180 180 $status = LicenseClient::check(); 181 182 /* 183 * Answered, and refused — not unreachable. An operator rotated the key, 184 * or the licence it belonged to is gone; the service answers both as it 185 * answers a mistyped key, deliberately, so this cannot say which and 186 * does not suggest the key was misused. Read after check(), which is 187 * what records a refusal it has just heard. Before this, the same state 188 * reported "will resolve automatically", which it never would. 189 */ 190 if ( null === $status && LicenseClient::is_key_refused() ) { 191 return [ 192 [ 193 'id' => 'license-refused', 194 'severity' => 'error', 195 'title' => __( 'License key no longer accepted', 'gloty' ), 196 'detail' => __( 197 'The licensing service no longer accepts the license key saved on this site. Translations keep running, but usage is not recorded against your plan. If you were sent a replacement key, or can see one in your WP Shelf account, enter it under Billing.', 198 'gloty' 199 ), 200 'action' => [ 201 'label' => __( 'Enter the new key', 'gloty' ), 202 'view' => 'billing', 203 ], 204 ], 205 ]; 206 } 207 181 208 if ( null === $status ) { 182 209 return [ -
gloty/tags/1.64.0/includes/Licensing/class-license-client.php
r3635518 r3748411 21 21 22 22 use WpShelf\Platform\LicenseClient as PlatformLicenseClient; 23 use WpShelf\Platform\LicenseRefusal; 23 24 use WpShelf\Platform\ProductConfig; 24 25 … … 39 40 */ 40 41 private const DEFAULT_SERVER_URL = 'https://gloty-api.wp-shelf.com'; 42 43 /** 44 * Where a customer signed in to wp-shelf.com sees every licence key they 45 * hold — including a replacement an operator rotated in, which is how the 46 * licence-key rotation runbook delivers one. 47 */ 48 public const ACCOUNT_LICENSES_URL = 'https://wp-shelf.com/dashboard/licenses'; 41 49 42 50 private static ?PlatformLicenseClient $client = null; … … 109 117 */ 110 118 public static function activate( string $key, string $server_url = '' ): array { 111 return self::client()->activate( $key, $server_url ); 119 $response = self::client()->activate( $key, $server_url ); 120 121 // Also cleared inside the shared client, but only by a copy new enough 122 // to know about refusals — and the copy that runs is whichever sibling's 123 // autoloader won. Clearing here holds whichever one that is. 124 if ( ! empty( $response['ok'] ) ) { 125 LicenseRefusal::clear( self::client()->config() ); 126 } 127 128 return $response; 112 129 } 113 130 … … 118 135 */ 119 136 public static function deactivate(): array { 120 return self::client()->deactivate(); 137 $response = self::client()->deactivate(); 138 LicenseRefusal::clear( self::client()->config() ); 139 140 return $response; 141 } 142 143 /** 144 * Whether the licensing service has stopped accepting the key this site holds. 145 * 146 * True after an operator rotated a disclosed key, or the licence the key 147 * belonged to no longer exists. The service answers both exactly as it 148 * answers a mistyped key — on purpose, so a leaked key cannot be confirmed 149 * — which is why this cannot say which. It is not an outage: an 150 * unreachable service never sets it. 151 * 152 * Translation keeps running meanwhile (it authenticates with the site 153 * token), but usage stops being recorded against the plan, so this is 154 * worth an issue rather than a footnote. 155 * 156 * Reads one option; never calls the service. The refusal is recorded by 157 * the shared status check — the daily forced one included. 158 */ 159 public static function is_key_refused(): bool { 160 return LicenseRefusal::is_refused( self::client()->config(), self::get_license_key() ); 121 161 } 122 162 -
gloty/tags/1.64.0/languages/gloty.pot
r3723648 r3748411 196 196 msgstr "" 197 197 198 #: includes/API/class-admin-rest-routes.php:211 3199 #: includes/API/class-admin-rest-routes.php:215 0198 #: includes/API/class-admin-rest-routes.php:2118 199 #: includes/API/class-admin-rest-routes.php:2155 200 200 msgid "Email and name are required." 201 201 msgstr "" 202 202 203 #: includes/API/class-admin-rest-routes.php:220 0203 #: includes/API/class-admin-rest-routes.php:2205 204 204 msgid "Could not create your license." 205 205 msgstr "" 206 206 207 #: includes/API/class-admin-rest-routes.php:22 17207 #: includes/API/class-admin-rest-routes.php:2222 208 208 msgid "Could not register this site with the translator service." 209 209 msgstr "" … … 358 358 msgstr "" 359 359 360 #: includes/Admin/class-issues-service.php:186 360 #: includes/Admin/class-issues-service.php:195 361 msgid "License key no longer accepted" 362 msgstr "" 363 364 #: includes/Admin/class-issues-service.php:196 365 msgid "The licensing service no longer accepts the license key saved on this site. Translations keep running, but usage is not recorded against your plan. If you were sent a replacement key, or can see one in your WP Shelf account, enter it under Billing." 366 msgstr "" 367 368 #: includes/Admin/class-issues-service.php:201 369 msgid "Enter the new key" 370 msgstr "" 371 372 #: includes/Admin/class-issues-service.php:213 361 373 msgid "License server is unreachable" 362 374 msgstr "" 363 375 364 #: includes/Admin/class-issues-service.php: 187376 #: includes/Admin/class-issues-service.php:214 365 377 msgid "We could not check your plan status. Translations still work; this will resolve automatically when the server is reachable." 366 378 msgstr "" 367 379 368 #: includes/Admin/class-issues-service.php:2 02380 #: includes/Admin/class-issues-service.php:229 369 381 msgid "Character quota exceeded" 370 382 msgstr "" 371 383 372 384 #. translators: 1: characters used, 2: character limit 373 #: includes/Admin/class-issues-service.php:2 05385 #: includes/Admin/class-issues-service.php:232 374 386 msgid "Used %1$s of %2$s characters. Dispatching is blocked until you upgrade or the period resets." 375 387 msgstr "" 376 388 377 #: includes/Admin/class-issues-service.php:2 10378 #: includes/Admin/class-issues-service.php:2 35389 #: includes/Admin/class-issues-service.php:237 390 #: includes/Admin/class-issues-service.php:262 379 391 msgid "Upgrade plan" 380 392 msgstr "" 381 393 382 394 #. translators: %d: percentage used 383 #: includes/Admin/class-issues-service.php:2 25395 #: includes/Admin/class-issues-service.php:252 384 396 msgid "Character quota at %d%%" 385 397 msgstr "" 386 398 387 399 #. translators: 1: characters used, 2: character limit 388 #: includes/Admin/class-issues-service.php:2 30400 #: includes/Admin/class-issues-service.php:257 389 401 msgid "Used %1$s of %2$s characters this billing period." 390 402 msgstr "" 391 403 392 #: includes/Admin/class-issues-service.php:2 45404 #: includes/Admin/class-issues-service.php:272 393 405 msgid "License expired" 394 406 msgstr "" 395 407 396 #: includes/Admin/class-issues-service.php:2 46408 #: includes/Admin/class-issues-service.php:273 397 409 msgid "Your subscription has expired. Renew to resume translation dispatch." 398 410 msgstr "" 399 411 400 #: includes/Admin/class-issues-service.php:2 51412 #: includes/Admin/class-issues-service.php:278 401 413 msgid "Manage billing" 402 414 msgstr "" 403 415 404 416 #. translators: %d: days remaining in the billing period 405 #: includes/Admin/class-issues-service.php:2 65417 #: includes/Admin/class-issues-service.php:292 406 418 msgid "Billing period resets in %d day" 407 419 msgid_plural "Billing period resets in %d days" … … 409 421 msgstr[1] "" 410 422 411 #: includes/Admin/class-issues-service.php: 273423 #: includes/Admin/class-issues-service.php:300 412 424 msgid "Usage will roll over automatically. No action required." 413 425 msgstr "" 414 426 415 #: includes/Admin/class-issues-service.php:3 21427 #: includes/Admin/class-issues-service.php:348 416 428 msgid "These translations are identical to the original text, and are not product names, codes, or text already written in that language. That usually means the translation service returned the source instead of a translation. They are stored as complete, so they will keep serving untranslated until they are translated again. Open the list to see exactly which rows this is counting before you remove any of them." 417 429 msgstr "" 418 430 419 431 #. translators: %s: comma-separated list of language codes with counts, e.g. "de (1,204), sl (980)" 420 #: includes/Admin/class-issues-service.php:3 29432 #: includes/Admin/class-issues-service.php:356 421 433 msgid "Most affected: %s." 422 434 msgstr "" 423 435 424 436 #. translators: %s: number of translations identical to their source 425 #: includes/Admin/class-issues-service.php:3 40437 #: includes/Admin/class-issues-service.php:367 426 438 msgid "%s translation is identical to its source" 427 439 msgid_plural "%s translations are identical to their source" … … 429 441 msgstr[1] "" 430 442 431 #: includes/Admin/class-issues-service.php:3 60443 #: includes/Admin/class-issues-service.php:387 432 444 msgid "Show these rows" 433 445 msgstr "" 434 446 435 #: includes/Admin/class-issues-service.php: 399447 #: includes/Admin/class-issues-service.php:426 436 448 msgid "Translated pages are not using the fast path" 437 449 msgstr "" 438 450 439 #: includes/Admin/class-issues-service.php:4 13451 #: includes/Admin/class-issues-service.php:440 440 452 msgid "Your translations are still served correctly, from the database, exactly as they were before this feature existed — pages are just not as fast as they could be." 441 453 msgstr "" 442 454 443 #: includes/Admin/class-issues-service.php:4 17455 #: includes/Admin/class-issues-service.php:444 444 456 msgid "Gloty speeds up translated pages by compiling your translations into a file your server keeps in memory, and your server's PHP OPcache has no free memory left to hold it. Writing the file anyway would make pages slower rather than faster, so Gloty did not. Ask your host to raise the PHP setting `opcache.memory_consumption` — on cPanel it is under MultiPHP INI Editor." 445 457 msgstr "" 446 458 447 #: includes/Admin/class-issues-service.php:4 20459 #: includes/Admin/class-issues-service.php:447 448 460 msgid "Your translation set compiles to a file larger than your server's `opcache.max_file_size` limit, so your server would refuse to keep it in memory. Ask your host to raise that setting." 449 461 msgstr "" 450 462 451 #: includes/Admin/class-issues-service.php:4 23463 #: includes/Admin/class-issues-service.php:450 452 464 msgid "Your translation set compiles to a file larger than the configured limit. Raise it with the `gloty_compiled_map_max_bytes` filter if your server has memory to spare." 453 465 msgstr "" 454 466 455 #: includes/Admin/class-issues-service.php:4 27467 #: includes/Admin/class-issues-service.php:454 456 468 msgid "Gloty could not write its translation cache file. This usually means the uploads directory is not writable by WordPress." 457 469 msgstr "" 458 470 459 #: includes/Admin/class-issues-service.php:4 30471 #: includes/Admin/class-issues-service.php:457 460 472 msgid "Writing the translation cache failed recently, so Gloty has paused trying for an hour. This usually means the uploads directory is not writable by WordPress." 461 473 msgstr "" 462 474 463 #: includes/Admin/class-issues-service.php:4 33475 #: includes/Admin/class-issues-service.php:460 464 476 msgid "Your server does not have PHP OPcache enabled, so Gloty cannot use its fastest path for serving translations. Ask your host whether OPcache can be turned on." 465 477 msgstr "" 466 478 467 479 #. translators: %d: number of stuck jobs 468 #: includes/Admin/class-issues-service.php:4 69480 #: includes/Admin/class-issues-service.php:496 469 481 msgid "%d job stuck processing" 470 482 msgid_plural "%d jobs stuck processing" … … 472 484 msgstr[1] "" 473 485 474 #: includes/Admin/class-issues-service.php: 477486 #: includes/Admin/class-issues-service.php:504 475 487 msgid "These jobs have been in the processing state for more than 10 minutes. They may be waiting on a webhook that never arrived." 476 488 msgstr "" 477 489 478 #: includes/Admin/class-issues-service.php: 482490 #: includes/Admin/class-issues-service.php:509 479 491 msgid "View jobs" 480 492 msgstr "" 481 493 482 494 #. translators: %d: number of failed jobs 483 #: includes/Admin/class-issues-service.php: 494495 #: includes/Admin/class-issues-service.php:521 484 496 msgid "%d job failed in the last 24 hours" 485 497 msgid_plural "%d jobs failed in the last 24 hours" … … 487 499 msgstr[1] "" 488 500 489 #: includes/Admin/class-issues-service.php:5 02501 #: includes/Admin/class-issues-service.php:529 490 502 msgid "Check the sync events log to see why these jobs failed, and retry them when the root cause is fixed." 491 503 msgstr "" 492 504 493 #: includes/Admin/class-issues-service.php:5 07494 #: includes/Admin/class-issues-service.php:5 29505 #: includes/Admin/class-issues-service.php:534 506 #: includes/Admin/class-issues-service.php:556 495 507 msgid "Open sync screen" 496 508 msgstr "" 497 509 498 #: includes/Admin/class-issues-service.php:5 23510 #: includes/Admin/class-issues-service.php:550 499 511 msgid "Automatic translation is delayed" 500 512 msgstr "" 501 513 502 #: includes/Admin/class-issues-service.php:5 24514 #: includes/Admin/class-issues-service.php:551 503 515 msgid "WordPress cron has not run recently, so scans and translations only progress when you trigger them. On low-traffic sites this is expected — set up a real server cron for wp-cron.php for hands-off processing, or use “Scan” / “Translate now”." 504 516 msgstr "" … … 868 880 869 881 #: src/admin/App.js:422 870 #: src/admin/LicensePanel.js:4 53882 #: src/admin/LicensePanel.js:464 871 883 msgid "License key" 872 884 msgstr "" … … 1172 1184 #: src/admin/App.js:1761 1173 1185 #: src/admin/DesignSystemScreen.js:518 1174 #: src/admin/LicensePanel.js:4 681186 #: src/admin/LicensePanel.js:479 1175 1187 #: src/admin/SyncScreen.js:480 1176 1188 #: src/admin/SyncScreen.js:938 … … 1734 1746 #: src/admin/DesignSystemScreen.js:146 1735 1747 #: src/admin/HealthPill.js:24 1736 #: src/admin/LicensePanel.js: 5911748 #: src/admin/LicensePanel.js:602 1737 1749 msgid "Checking…" 1738 1750 msgstr "" … … 2315 2327 msgstr "" 2316 2328 2317 #: src/admin/LicensePanel.js:1 792329 #: src/admin/LicensePanel.js:188 2318 2330 msgid "License provisioned and activated." 2319 2331 msgstr "" 2320 2332 2321 #: src/admin/LicensePanel.js:1 862322 #: src/admin/LicensePanel.js: 1922333 #: src/admin/LicensePanel.js:195 2334 #: src/admin/LicensePanel.js:201 2323 2335 msgid "Provisioning failed." 2324 2336 msgstr "" 2325 2337 2326 #: src/admin/LicensePanel.js:2 182338 #: src/admin/LicensePanel.js:228 2327 2339 msgid "License activated." 2328 2340 msgstr "" 2329 2341 2330 #: src/admin/LicensePanel.js:2 242331 #: src/admin/LicensePanel.js:2 302342 #: src/admin/LicensePanel.js:234 2343 #: src/admin/LicensePanel.js:240 2332 2344 msgid "Activation failed." 2333 2345 msgstr "" 2334 2346 2335 #: src/admin/LicensePanel.js:2 492347 #: src/admin/LicensePanel.js:260 2336 2348 msgid "License deactivated." 2337 2349 msgstr "" 2338 2350 2339 #: src/admin/LicensePanel.js:2 542351 #: src/admin/LicensePanel.js:265 2340 2352 msgid "Deactivation failed." 2341 2353 msgstr "" 2342 2354 2343 #: src/admin/LicensePanel.js: 2962355 #: src/admin/LicensePanel.js:307 2344 2356 msgid "No billing portal is available for this license — there’s no Stripe subscription to manage. This is normal for free or manually-granted plans." 2345 2357 msgstr "" 2346 2358 2347 #: src/admin/LicensePanel.js:3 052359 #: src/admin/LicensePanel.js:316 2348 2360 msgid "Could not open the billing portal." 2349 2361 msgstr "" 2350 2362 2351 #: src/admin/LicensePanel.js:3 332363 #: src/admin/LicensePanel.js:344 2352 2364 msgid "License" 2353 2365 msgstr "" 2354 2366 2355 #: src/admin/LicensePanel.js:3 522367 #: src/admin/LicensePanel.js:363 2356 2368 msgid "Get started with Gloty translation credits, or enter an existing license key." 2357 2369 msgstr "" 2358 2370 2359 #: src/admin/LicensePanel.js:3 752371 #: src/admin/LicensePanel.js:386 2360 2372 msgid "Get Started" 2361 2373 msgstr "" 2362 2374 2363 #: src/admin/LicensePanel.js:3 862375 #: src/admin/LicensePanel.js:397 2364 2376 msgid "I have a license key" 2365 2377 msgstr "" 2366 2378 2367 #: src/admin/LicensePanel.js: 3942379 #: src/admin/LicensePanel.js:405 2368 2380 msgid "Email" 2369 2381 msgstr "" 2370 2382 2371 #: src/admin/LicensePanel.js:4 032383 #: src/admin/LicensePanel.js:414 2372 2384 msgid "Name" 2373 2385 msgstr "" 2374 2386 2375 #: src/admin/LicensePanel.js:4 192387 #: src/admin/LicensePanel.js:430 2376 2388 msgid "Get Free License" 2377 2389 msgstr "" 2378 2390 2379 #: src/admin/LicensePanel.js:4 282391 #: src/admin/LicensePanel.js:439 2380 2392 msgid "License Key" 2381 2393 msgstr "" 2382 2394 2383 #: src/admin/LicensePanel.js:441 2395 #: src/admin/LicensePanel.js:452 2396 #: src/admin/LicensePanel.js:691 2384 2397 msgid "Activate" 2385 2398 msgstr "" 2386 2399 2387 #: src/admin/LicensePanel.js:4 622400 #: src/admin/LicensePanel.js:473 2388 2401 msgid "Plan" 2389 2402 msgstr "" 2390 2403 2391 #: src/admin/LicensePanel.js:4 742404 #: src/admin/LicensePanel.js:485 2392 2405 msgid "Sites" 2393 2406 msgstr "" 2394 2407 2395 #: src/admin/LicensePanel.js:4 822408 #: src/admin/LicensePanel.js:493 2396 2409 msgid "Usage" 2397 2410 msgstr "" 2398 2411 2399 #: src/admin/LicensePanel.js: 4942412 #: src/admin/LicensePanel.js:505 2400 2413 msgid "You’re approaching your monthly limit. Translation pauses at 100% until the limit resets or you upgrade — existing translations keep serving." 2401 2414 msgstr "" 2402 2415 2403 #: src/admin/LicensePanel.js: 4982416 #: src/admin/LicensePanel.js:509 2404 2417 msgid "Translation pauses when you reach your monthly limit, then resumes after it resets or you upgrade. Already-stored translations always keep serving." 2405 2418 msgstr "" 2406 2419 2407 #: src/admin/LicensePanel.js:5 072420 #: src/admin/LicensePanel.js:518 2408 2421 msgid "Resets" 2409 2422 msgstr "" 2410 2423 2411 #: src/admin/LicensePanel.js:5 202412 #: src/admin/LicensePanel.js:5 572424 #: src/admin/LicensePanel.js:531 2425 #: src/admin/LicensePanel.js:568 2413 2426 msgid "Upgrade" 2414 2427 msgstr "" 2415 2428 2416 #: src/admin/LicensePanel.js:5 372429 #: src/admin/LicensePanel.js:548 2417 2430 msgid "1 site" 2418 2431 msgstr "" 2419 2432 2420 2433 #. translators: %d: number of sites 2421 #: src/admin/LicensePanel.js:5 402434 #: src/admin/LicensePanel.js:551 2422 2435 msgid "Up to %d sites" 2423 2436 msgstr "" 2424 2437 2425 #: src/admin/LicensePanel.js:5 582438 #: src/admin/LicensePanel.js:569 2426 2439 msgid "Buy" 2427 2440 msgstr "" 2428 2441 2429 #: src/admin/LicensePanel.js:5 802442 #: src/admin/LicensePanel.js:591 2430 2443 msgid "Manage Subscription" 2431 2444 msgstr "" 2432 2445 2433 #: src/admin/LicensePanel.js: 5922446 #: src/admin/LicensePanel.js:603 2434 2447 msgid "Refresh status" 2435 2448 msgstr "" 2436 2449 2437 #: src/admin/LicensePanel.js:6 002438 #: src/admin/LicensePanel.js:6 192450 #: src/admin/LicensePanel.js:611 2451 #: src/admin/LicensePanel.js:630 2439 2452 msgid "Deactivate" 2440 2453 msgstr "" 2441 2454 2442 #: src/admin/LicensePanel.js:6 042455 #: src/admin/LicensePanel.js:615 2443 2456 msgid "Deactivating frees this license for another site. Your translations stay in place — nothing is deleted." 2444 2457 msgstr "" 2445 2458 2446 #: src/admin/LicensePanel.js:6 142459 #: src/admin/LicensePanel.js:625 2447 2460 msgid "Deactivate license on this site?" 2448 2461 msgstr "" 2449 2462 2450 #: src/admin/LicensePanel.js:6 152463 #: src/admin/LicensePanel.js:626 2451 2464 msgid "This frees the license seat for use on another site. Your stored translations stay in place and keep serving, but new translations stop until you reactivate. Nothing is deleted." 2452 2465 msgstr "" 2453 2466 2454 #: src/admin/LicensePanel.js:639 2467 #: src/admin/LicensePanel.js:656 2468 msgid "This license key is no longer accepted." 2469 msgstr "" 2470 2471 #: src/admin/LicensePanel.js:663 2472 msgid "Translations keep running, but usage is not recorded against your plan. If you were sent a replacement key, or can see one in your WP Shelf account, paste it here and activate it." 2473 msgstr "" 2474 2475 #: src/admin/LicensePanel.js:672 2476 msgid "Open your WP Shelf licenses" 2477 msgstr "" 2478 2479 #: src/admin/LicensePanel.js:678 2480 msgid "Replacement license key" 2481 msgstr "" 2482 2483 #: src/admin/LicensePanel.js:706 2455 2484 msgid "License key is configured but the license server could not be reached." 2456 2485 msgstr "" 2457 2486 2458 #: src/admin/LicensePanel.js: 6522487 #: src/admin/LicensePanel.js:719 2459 2488 msgid "Retrying…" 2460 2489 msgstr "" 2461 2490 2462 #: src/admin/LicensePanel.js: 6532491 #: src/admin/LicensePanel.js:720 2463 2492 #: src/admin/SyncScreen.js:991 2464 2493 msgid "Retry" … … 3483 3512 #. translators: %s: a number of views. 3484 3513 #: src/admin/TrendChart.js:340 3514 msgctxt "tooltip readout" 3485 3515 msgid "%s views" 3486 3516 msgstr "" -
gloty/tags/1.64.0/package.json
r3723660 r3748411 1 1 { 2 2 "name": "@wp-shelf/gloty", 3 "version": "1.6 3.3",3 "version": "1.64.0", 4 4 "description": "Gloty - AI-powered translation plugin for WordPress.", 5 5 "private": true, -
gloty/tags/1.64.0/readme.txt
r3723660 r3748411 5 5 Tested up to: 7.1 6 6 Requires PHP: 8.1 7 Stable tag: 1.6 3.37 Stable tag: 1.64.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 196 196 == Changelog == 197 197 198 = 1.64.0 = 199 * New: if your license key stops being accepted — for example because we replaced it at your request — Gloty says so in Needs attention and on the license card, with a field for the replacement key that reconnects this site without using another site slot. Before, it reported that the licensing service could not be reached and offered only Retry. Translations keep being served while you replace the key. 200 * Changed: on a site running several WP Shelf plugins, the newest version of the shared admin styles is used, whichever plugin was installed or updated last. Before, updating an older WP Shelf plugin could make every WP Shelf screen fall back to its older styles. 201 198 202 = 1.63.3 = 199 203 * Fixed: a translation that came back with part of Gloty's own request stuck to its end — text such as `','kind':'heading` or `','kind':'seo_title','doc':'post:1807` after the translated words — is no longer stored or shown. It is a stray piece of the translation service's instructions, not part of the translation, and it appeared in headings, menu labels, SEO titles and image captions. Gloty now refuses it and asks for that piece of text again, and no longer copies an affected entry onto other pages with the same text. Ordinary text that merely contains the word "kind" or apostrophes is unaffected. A refusal is written to the audit log with the value that was rejected. This fix first shipped as 1.61.1 to a single site and had not reached the 1.62 and 1.63 releases. -
gloty/tags/1.64.0/shared-js/design-system/src/components.css
r3723648 r3748411 313 313 } 314 314 315 /* Sentence case. A column header is a label, not an abbreviation. */ 316 .wpshelf-table th { 315 /* Sentence case. A column header is a label, not an abbreviation. 316 One header whether or not the table also carries WordPress's 317 `wp-list-table widefat` classes (TASK-112): every property core sets on a 318 `.widefat` header is set here, at (0,1,4) — above core's 319 `.widefat th:not(tbody th)` at (0,1,3). Mirrored in 320 shared/php/platform/assets/admin.css, which also names the 321 `.wpshelf-app .wp-list-table th` it shares this rule with. */ 322 table.wpshelf-table > thead > tr > th { 323 padding: var(--wpshelf-cell-pad-y) var(--wpshelf-cell-pad-x); 324 border-bottom: 1px solid var(--wpshelf-line); 325 background: var(--wpshelf-surface-alt); 326 color: var(--wpshelf-muted); 317 327 font-size: var(--wpshelf-text-sm); 318 328 font-weight: var(--wpshelf-weight-medium); 319 color: var(--wpshelf-muted); 329 line-height: var(--wpshelf-leading-snug); 330 overflow-wrap: break-word; 331 text-align: start; 320 332 } 321 333 … … 384 396 } 385 397 398 /* A column's alignment reaches its header, above the header default. */ 399 .wpshelf-table th.wpshelf-cell--left { 400 text-align: left; 401 } 402 403 .wpshelf-table th.wpshelf-cell--right { 404 text-align: right; 405 } 406 407 .wpshelf-table th.wpshelf-cell--center { 408 text-align: center; 409 } 410 386 411 /* Declared even though it is the default: a column may state `align: 'left'` 387 412 explicitly, and a class that renders with no rule behind it is the failure -
gloty/tags/1.64.0/shared-js/design-system/src/interactive-table.js
r3688478 r3748411 14 14 } from '@wordpress/element'; 15 15 import { FilterBar, TablePager } from './data-table'; 16 17 // Built once: `localeCompare` with options builds a collator per comparison, 18 // and a sort over a few thousand rows makes tens of thousands of them. 19 const collator = new Intl.Collator(undefined, { 20 numeric: true, 21 sensitivity: 'base', 22 }); 16 23 17 24 export function tableText(node) { … … 109 116 matching.sort( 110 117 (a, b) => 111 tableText( 112 Children.toArray(a.props.children)[sort.column] 113 ).localeCompare( 114 tableText(Children.toArray(b.props.children)[sort.column]), 115 undefined, 116 { numeric: true, sensitivity: 'base' } 118 collator.compare( 119 tableText(Children.toArray(a.props.children)[sort.column]), 120 tableText(Children.toArray(b.props.children)[sort.column]) 117 121 ) * sort.direction 118 122 ); -
gloty/tags/1.64.0/shared-js/design-system/src/style.css
r3688478 r3748411 97 97 color: var(--wpshelf-ink-soft); 98 98 } 99 100 /* ================================================================ 101 Money cell and ledger — amounts in tables, and a label/value breakdown 102 with a ruled total. Promoted upstream so a PHP screen and a React screen 103 render the same money the same way. Mirrored in 104 shared/php/platform/assets/admin.css (AdminStyleTokenParityTest). 105 ================================================================ */ 106 107 .wpshelf-cell--money { 108 text-align: right; 109 font-variant-numeric: tabular-nums; 110 color: var(--wpshelf-ink); 111 } 112 113 .wpshelf-cell--money.is-negative { 114 color: var(--wpshelf-danger); 115 } 116 117 .wpshelf-cell--money.is-muted { 118 color: var(--wpshelf-muted); 119 } 120 121 .wpshelf-ledger { 122 margin: 0; 123 display: flex; 124 flex-direction: column; 125 gap: var(--wpshelf-space-2); 126 } 127 128 .wpshelf-ledger__row { 129 display: flex; 130 align-items: baseline; 131 justify-content: space-between; 132 gap: var(--wpshelf-space-4); 133 margin: 0; 134 } 135 136 .wpshelf-ledger__row dt { 137 margin: 0; 138 color: var(--wpshelf-ink-soft); 139 font-size: var(--wpshelf-text-base); 140 } 141 142 .wpshelf-ledger__row dd { 143 margin: 0; 144 } 145 146 .wpshelf-ledger__row--sub { 147 padding-left: var(--wpshelf-space-4); 148 } 149 150 .wpshelf-ledger__row--sub dt { 151 color: var(--wpshelf-muted); 152 font-size: var(--wpshelf-text-sm); 153 } 154 155 .wpshelf-ledger__total { 156 margin-top: var(--wpshelf-space-1); 157 padding-top: var(--wpshelf-space-2); 158 border-top: 1px solid var(--wpshelf-line); 159 } 160 161 .wpshelf-ledger__total dt, 162 .wpshelf-ledger__total dd { 163 font-weight: var(--wpshelf-weight-semi); 164 color: var(--wpshelf-ink); 165 } 166 167 .wpshelf-ledger__note { 168 margin: 0; 169 color: var(--wpshelf-ink-soft); 170 font-size: var(--wpshelf-text-sm); 171 } -
gloty/tags/1.64.0/shared-js/design-system/src/table-state.js
r3723648 r3748411 148 148 * @return {number} Comparator result. 149 149 */ 150 /** 151 * One collator for every comparison. 152 * 153 * `localeCompare` with an options object builds a fresh `Intl.Collator` on 154 * each call, and a sort makes n·log n of them: 5,000 rows — the most these 155 * screens load — took about 100ms per sort that way, and the sort reruns on 156 * every keystroke in the search box. One collator built once sorts the same 157 * rows in about 6ms with exactly the same ordering. 158 */ 159 const collator = new Intl.Collator(undefined, { 160 numeric: true, 161 sensitivity: 'base', 162 }); 163 150 164 export function compareRows(a, b, column, direction) { 151 165 const pick = column.sortValue ? column.sortValue : (row) => row[column.key]; … … 161 175 } 162 176 163 return ( 164 String(left ?? '').localeCompare(String(right ?? ''), undefined, { 165 numeric: true, 166 sensitivity: 'base', 167 }) * sign 168 ); 177 return collator.compare(String(left ?? ''), String(right ?? '')) * sign; 169 178 } 170 179 -
gloty/tags/1.64.0/src/admin/LicensePanel.js
r3723648 r3748411 88 88 const [hasKey, setHasKey] = useState(boot?.license?.hasKey || false); 89 89 const [keyMasked, setKeyMasked] = useState(boot?.license?.keyMasked || ''); 90 /* 91 * The service answered and no longer accepts the stored key — an operator 92 * rotated it, or the licence is gone. Distinct from "could not be reached": 93 * waiting fixes that one, only a replacement key fixes this. 94 */ 95 const [keyRefused, setKeyRefused] = useState( 96 boot?.license?.keyRefused || false 97 ); 90 98 const [busy, setBusy] = useState(false); 91 99 const [refreshing, setRefreshing] = useState(false); … … 123 131 setHasKey(res?.has_key || false); 124 132 setStatus(res?.status || null); 133 setKeyRefused(res?.key_refused || false); 125 134 if (res?.key_masked) { 126 135 setKeyMasked(res.key_masked); … … 213 222 if (res?.ok) { 214 223 setHasKey(true); 224 setKeyRefused(false); 215 225 setKeyInput(''); 216 226 setNotice({ … … 245 255 setHasKey(false); 246 256 setStatus(null); 257 setKeyRefused(false); 247 258 setNotice({ 248 259 status: 'info', … … 627 638 )} 628 639 629 {hasKey && !status && ( 640 {/* 641 Worded for both causes, because the service deliberately does 642 not say which, and with no suggestion the key was misused. The 643 field is here rather than behind Deactivate: activating the 644 replacement re-binds this site's existing activation, so it 645 takes no extra seat. 646 */} 647 {hasKey && !status && keyRefused && ( 648 <> 649 <Notice 650 status="warning" 651 isDismissible={false} 652 className="wpshelf-mb" 653 > 654 <p> 655 <strong> 656 {__( 657 'This license key is no longer accepted.', 658 'gloty' 659 )} 660 </strong> 661 </p> 662 <p> 663 {__( 664 'Translations keep running, but usage is not recorded against your plan. If you were sent a replacement key, or can see one in your WP Shelf account, paste it here and activate it.', 665 'gloty' 666 )}{' '} 667 <a 668 href="https://wp-shelf.com/dashboard/licenses" 669 target="_blank" 670 rel="noopener noreferrer" 671 > 672 {__('Open your WP Shelf licenses', 'gloty')} 673 </a> 674 </p> 675 </Notice> 676 <div className="wpshelf-settings-field"> 677 <TextControl 678 label={__('Replacement license key', 'gloty')} 679 value={keyInput} 680 onChange={setKeyInput} 681 placeholder="GLOTY-XXXX-XXXX-XXXX-XXXX" 682 __nextHasNoMarginBottom 683 /> 684 </div> 685 <Button 686 variant="primary" 687 onClick={activate} 688 isBusy={busy} 689 disabled={busy || !keyInput.trim()} 690 > 691 {__('Activate', 'gloty')} 692 </Button> 693 </> 694 )} 695 696 {hasKey && !status && !keyRefused && ( 630 697 <p className="wpshelf-muted"> 631 698 {keyMasked && ( -
gloty/tags/1.64.0/src/admin/style.css
r3723648 r3748411 340 340 * Below the wp-admin breakpoint the sidebar stacks above the content. 341 341 * 342 * It used to be hidden outright, and the reason given was that "the plugin's own343 * submenu is still in the wp-admin menu, so a second copy of the same links342 * It used to be hidden outright, and the reason given was that "the plugin's 343 * own submenu is still in the wp-admin menu, so a second copy of the same links 344 344 * above the content is noise". That stopped being true the moment every plugin 345 345 * became a single entry under WP Shelf: this sidebar is now the only way to … … 525 525 526 526 /* This shell changes screens without a page load, so the fade is the motion a 527 motion-sensitive user meets most. Suppressed exactly as the shelf sheet does. */ 527 motion-sensitive user meets most. Suppressed exactly as the shelf sheet 528 does. */ 528 529 @media (prefers-reduced-motion: reduce) { 529 530 … … 1746 1747 } 1747 1748 1748 /* Hairline, solid, one step off the surface. Dashed grids read as thresholds. */ 1749 /* Hairline, solid, one step off the surface. Dashed grids read as 1750 thresholds. */ 1749 1751 .wpshelf-chart__grid { 1750 1752 stroke: var(--wpshelf-line); … … 1758 1760 } 1759 1761 1760 /* A wash, never a block: the line carries the shape, the fill only its weight. */ 1762 /* A wash, never a block: the line carries the shape, the fill only its 1763 weight. */ 1761 1764 .wpshelf-chart__area { 1762 1765 fill: var(--wpshelf-accent); … … 1772 1775 } 1773 1776 1774 /* The chart's one direct label — the busiest day. Ink, never the series colour. */ 1777 /* The chart's one direct label — the busiest day. Ink, never the series 1778 colour. */ 1775 1779 .wpshelf-chart__peak { 1776 1780 fill: var(--wpshelf-ink); -
gloty/tags/1.64.0/vendor/composer/autoload_classmap.php
r3723648 r3748411 142 142 'WpShelf\\Platform\\FormMarkup' => $vendorDir . '/wp-shelf/platform/src/FormMarkup.php', 143 143 'WpShelf\\Platform\\LicenseClient' => $vendorDir . '/wp-shelf/platform/src/LicenseClient.php', 144 'WpShelf\\Platform\\LicenseRefusal' => $vendorDir . '/wp-shelf/platform/src/LicenseRefusal.php', 144 145 'WpShelf\\Platform\\LicenseTransport' => $vendorDir . '/wp-shelf/platform/src/LicenseTransport.php', 145 146 'WpShelf\\Platform\\Pager' => $vendorDir . '/wp-shelf/platform/src/Pager.php', -
gloty/tags/1.64.0/vendor/composer/autoload_static.php
r3723648 r3748411 170 170 'WpShelf\\Platform\\FormMarkup' => __DIR__ . '/..' . '/wp-shelf/platform/src/FormMarkup.php', 171 171 'WpShelf\\Platform\\LicenseClient' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseClient.php', 172 'WpShelf\\Platform\\LicenseRefusal' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseRefusal.php', 172 173 'WpShelf\\Platform\\LicenseTransport' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseTransport.php', 173 174 'WpShelf\\Platform\\Pager' => __DIR__ . '/..' . '/wp-shelf/platform/src/Pager.php', -
gloty/tags/1.64.0/vendor/composer/installed.json
r3723660 r3748411 3 3 { 4 4 "name": "wp-shelf/html-parser", 5 "version": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",6 "version_normalized": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",5 "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 6 "version_normalized": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 7 7 "dist": { 8 8 "type": "path", … … 43 43 { 44 44 "name": "wp-shelf/platform", 45 "version": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",46 "version_normalized": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",45 "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 46 "version_normalized": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 47 47 "dist": { 48 48 "type": "path", -
gloty/tags/1.64.0/vendor/composer/installed.php
r3723660 r3748411 2 2 'root' => array( 3 3 'name' => 'wp-shelf/gloty', 4 'pretty_version' => 'dev- main',5 'version' => 'dev- main',6 'reference' => '6 35a6dd92d2f2eb2936e79cfea23c4635ea223eb',4 'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 5 'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 6 'reference' => '6e5e1992bdcd2740c8e706d59d229784889aec50', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 12 12 'versions' => array( 13 13 'wp-shelf/gloty' => array( 14 'pretty_version' => 'dev- main',15 'version' => 'dev- main',16 'reference' => '6 35a6dd92d2f2eb2936e79cfea23c4635ea223eb',14 'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 15 'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 16 'reference' => '6e5e1992bdcd2740c8e706d59d229784889aec50', 17 17 'type' => 'wordpress-plugin', 18 18 'install_path' => __DIR__ . '/../../', … … 21 21 ), 22 22 'wp-shelf/html-parser' => array( 23 'pretty_version' => 'dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd',24 'version' => 'dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd',23 'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 24 'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 25 25 'reference' => '1c4b68cd06da61ac60b52a4a2bf25ec4cf160ca4', 26 26 'type' => 'library', … … 30 30 ), 31 31 'wp-shelf/platform' => array( 32 'pretty_version' => 'dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd',33 'version' => 'dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd',32 'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 33 'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 34 34 'reference' => '1a5dd36e91615be4855bc9481ba9bacf32bb18c8', 35 35 'type' => 'library', -
gloty/tags/1.64.0/vendor/wp-shelf/platform/assets/admin.css
r3723648 r3748411 492 492 } 493 493 494 /* 495 * Stacked, but compact: the links flow as a wrapped row with the group 496 * labels dropped. As a column of full-width rows it was a whole phone 497 * screen of navigation above the content, every visit. 498 */ 494 499 .wpshelf-sidebar { 495 500 position: static; 501 display: flex; 502 flex-wrap: wrap; 503 gap: 2px; 504 } 505 506 .wpshelf-sidebar__section { 507 display: contents; 508 } 509 510 .wpshelf-sidebar__section-label { 511 display: none; 512 } 513 514 /* Scoped under the sidebar so it outranks the base item rule below. */ 515 .wpshelf-sidebar .wpshelf-sidebar__item { 516 width: auto; 517 padding: 6px 10px; 496 518 } 497 519 } … … 627 649 /* ---- Content region ---- */ 628 650 .wpshelf-tab-content { 651 position: relative; 629 652 background: transparent; 630 653 border: 0; … … 632 655 margin-top: 0; 633 656 min-width: 0; 657 } 658 659 /* 660 * While an async save or navigation is in flight the content region carries 661 * aria-busy, and before this nothing drew it: the Save button stayed lit and 662 * the screen sat still until the swap. A 2px hairline across the top of the 663 * region is the shelf's whole busy signal — an edge, not a spinner, in keeping 664 * with the rest of the language. Under reduced motion the line simply shows. 665 * (`position: relative` is on the region's rule above.) 666 */ 667 .wpshelf-tab-content[aria-busy="true"]::before { 668 content: ""; 669 position: absolute; 670 top: 0; 671 left: 0; 672 width: 100%; 673 height: 2px; 674 background: var(--wpshelf-accent); 675 transform-origin: left; 676 animation: wpshelf-busy-bar 1.2s ease-in-out infinite; 677 pointer-events: none; 678 } 679 680 @keyframes wpshelf-busy-bar { 681 682 0% { 683 transform: scaleX(0); 684 } 685 686 50% { 687 transform: scaleX(0.7); 688 } 689 690 100% { 691 transform: scaleX(1); 692 opacity: 0; 693 } 694 } 695 696 /* The button that was pressed, until the server answers. */ 697 .wpshelf-is-saving { 698 opacity: 0.6; 699 cursor: progress; 700 } 701 702 /* 703 * A failure notice the script inserts gets focus so it is read out; the 704 * ring the browser draws for programmatic focus on a paragraph is noise. 705 */ 706 .wpshelf-tab-content .notice:focus, 707 .wpshelf-tab-content .wpshelf-notice:focus { 708 outline: none; 709 } 710 711 .wpshelf-tab-content .notice:focus-visible, 712 .wpshelf-tab-content .wpshelf-notice:focus-visible { 713 outline: var(--wpshelf-focus-ring); 714 } 715 716 @media (prefers-reduced-motion: reduce) { 717 718 .wpshelf-tab-content[aria-busy="true"]::before { 719 animation: none; 720 } 634 721 } 635 722 … … 821 908 } 822 909 823 /* Sentence case: a column header is a label, not an abbreviation. */ 824 .wpshelf-app .wp-list-table th { 910 /* 911 * Sentence case: a column header is a label, not an abbreviation. 912 * 913 * One header for every shelf table, whatever WordPress classes it carries. 914 * Crawlune and SnippetGrove print `wp-list-table widefat striped wpshelf-table` 915 * and Labely prints `wpshelf-table` alone, and while this rule named only the 916 * first the two computed different components from the same class: a filled, 917 * hairlined header against a bold, centred, unruled one that was the browser's 918 * default (TASK-112). So the shelf's own header is named here too, and every 919 * property WordPress sets on a `.widefat` header is set here as well — line 920 * height and wrapping included — so neither variant borrows anything from core. 921 * 922 * `table.wpshelf-table > thead > tr > th` is (0,1,4) on purpose: core's 923 * `.widefat th:not(tbody th)` is (0,1,3), and a tie would hand the header to 924 * whichever stylesheet happened to load last. It is also why this one rule is 925 * not scoped under `.wpshelf-app`: a shelf table in an order metabox is still 926 * a shelf table. Proved by computed style, not by selector, in 927 * products/labely/plugin/e2e/computed-styles.spec.js. 928 */ 929 .wpshelf-app .wp-list-table th, 930 table.wpshelf-table > thead > tr > th { 825 931 padding: var(--wpshelf-cell-pad-y) var(--wpshelf-cell-pad-x); 826 932 border-bottom: 1px solid var(--wpshelf-line); … … 829 935 font-size: var(--wpshelf-text-sm); 830 936 font-weight: var(--wpshelf-weight-medium); 937 line-height: var(--wpshelf-leading-snug); 938 overflow-wrap: break-word; 831 939 } 832 940 … … 978 1086 ───────────────────────────────────────────────────────────────────────── */ 979 1087 1088 /* No gaps between cells. `.widefat` sets this for WordPress's tables; a 1089 shelf table without it kept the browser's 2px, which showed as white seams 1090 through the header's fill. */ 980 1091 .wpshelf-table { 981 1092 max-width: var(--wpshelf-measure); 1093 border-spacing: 0; 982 1094 } 983 1095 … … 1128 1240 align-items: center; 1129 1241 gap: var(--wpshelf-space-1); 1242 /* A header and its glyph are one unit; "Statement ↕" wrapped the glyph 1243 onto a line of its own in a narrow column. */ 1244 white-space: nowrap; 1130 1245 padding: 0; 1131 1246 border: none; … … 1177 1292 } 1178 1293 1294 /* A header reads from its start edge, whatever the browser (centre) or 1295 WordPress (`.widefat th`, left — wrong in RTL) would have said. Above core 1296 for the same reason as the header rule; below the modifiers that follow. */ 1297 table.wpshelf-table > thead > tr > th { 1298 text-align: start; 1299 } 1300 1301 /* A column's alignment reaches its header, so a right-aligned figure sits 1302 under a right-aligned label. (0,2,1): above the header default and above 1303 `.widefat th`, which used to pin every DataTable header left. */ 1304 .wpshelf-table th.wpshelf-cell--left { 1305 text-align: left; 1306 } 1307 1308 .wpshelf-table th.wpshelf-cell--right { 1309 text-align: right; 1310 } 1311 1312 .wpshelf-table th.wpshelf-cell--center { 1313 text-align: center; 1314 } 1315 1179 1316 /* Declared even though it is the default: a column may state `align: 'left'` 1180 1317 explicitly, and a class that renders with no rule behind it is the failure … … 1191 1328 .wpshelf-cell--center { 1192 1329 text-align: center; 1330 } 1331 1332 /* ---- Money cell ---- 1333 Right-aligned and tabular so a column of amounts lines up on the decimal; 1334 `is-negative`/`is-muted` are plain state classes, not `.wpshelf-*` modifiers, 1335 because they say something about the value rather than name a variant of 1336 the component. */ 1337 .wpshelf-cell--money { 1338 text-align: right; 1339 font-variant-numeric: tabular-nums; 1340 /* An amount is one token: "€14,9 / 9" broken over two lines reads as two 1341 numbers. A narrow table scrolls in its wrapper instead. */ 1342 white-space: nowrap; 1343 color: var(--wpshelf-ink); 1344 } 1345 1346 .wpshelf-cell--money.is-negative { 1347 color: var(--wpshelf-danger); 1348 } 1349 1350 .wpshelf-cell--money.is-muted { 1351 color: var(--wpshelf-muted); 1193 1352 } 1194 1353 … … 1894 2053 font-size: var(--wpshelf-text-sm); 1895 2054 color: var(--wpshelf-muted); 2055 } 2056 2057 /* The table controls and the bulk bar hide with the `hidden` attribute, 2058 which a `display` rule would otherwise override — Previous/Next showed 2059 under a one-page table and "0 rows selected" sat above every list. */ 2060 .wpshelf-pager[hidden], 2061 .wpshelf-filters[hidden], 2062 .wpshelf-bulkbar[hidden] { 2063 display: none; 1896 2064 } 1897 2065 … … 2399 2567 } 2400 2568 2569 /* 2570 * A checkbox or radio inside a field label is a tick box beside its text, not 2571 * a full-width text box: the rule above drew one as an empty bar with its 2572 * label underneath. 2573 */ 2574 .wpshelf-field > input[type="checkbox"], 2575 .wpshelf-field > input[type="radio"] { 2576 display: inline-block; 2577 width: auto; 2578 margin: 0 var(--wpshelf-space-2) 0 0; 2579 padding: 0; 2580 vertical-align: middle; 2581 } 2582 2401 2583 .wpshelf-field > input:focus, 2402 2584 .wpshelf-field > textarea:focus, … … 2527 2709 font-size: var(--wpshelf-text-sm); 2528 2710 line-height: var(--wpshelf-leading-normal); 2711 } 2712 2713 /* ---- Ledger ---- 2714 A calculation read top to bottom, one line per input. A `<dl>` rather than a table — each row is a label/value 2715 pair, not a record with equal-weight columns — mirroring the definition-row 2716 shape `.wpshelf-license-*` already uses above. */ 2717 .wpshelf-ledger { 2718 margin: 0; 2719 display: flex; 2720 flex-direction: column; 2721 gap: var(--wpshelf-space-2); 2722 } 2723 2724 .wpshelf-ledger__row { 2725 display: flex; 2726 align-items: baseline; 2727 justify-content: space-between; 2728 gap: var(--wpshelf-space-4); 2729 margin: 0; 2730 } 2731 2732 .wpshelf-ledger__row dt { 2733 margin: 0; 2734 color: var(--wpshelf-ink-soft); 2735 font-size: var(--wpshelf-text-base); 2736 } 2737 2738 .wpshelf-ledger__row dd { 2739 margin: 0; 2740 } 2741 2742 /* A cost line's own detail — the shipping/packaging/fee rows under a line 2743 item, or a guard's cap under the amount. Indented so the hierarchy reads 2744 without a second column. */ 2745 .wpshelf-ledger__row--sub { 2746 padding-left: var(--wpshelf-space-4); 2747 } 2748 2749 .wpshelf-ledger__row--sub dt { 2750 color: var(--wpshelf-muted); 2751 font-size: var(--wpshelf-text-sm); 2752 } 2753 2754 .wpshelf-ledger__total { 2755 margin-top: var(--wpshelf-space-1); 2756 padding-top: var(--wpshelf-space-2); 2757 border-top: 1px solid var(--wpshelf-line); 2758 } 2759 2760 .wpshelf-ledger__total dt, 2761 .wpshelf-ledger__total dd { 2762 font-weight: var(--wpshelf-weight-semi); 2763 color: var(--wpshelf-ink); 2764 } 2765 2766 /* The measured/assumed footnote under a cost input. */ 2767 .wpshelf-ledger__note { 2768 margin: 0; 2769 color: var(--wpshelf-ink-soft); 2770 font-size: var(--wpshelf-text-sm); 2529 2771 } 2530 2772 … … 2754 2996 } 2755 2997 } 2998 2999 /* ---- Pagers: "Next" at the size of the page count beside it ------------- 3000 WordPress sets `.tablenav-pages .button` to 16 px for its « ‹ › » glyphs; 3001 `Pager` prints words there, so "Next" drew a size larger than 3002 "Page 1 of 2" and every other button on the screen. */ 3003 .wpshelf-app .tablenav-pages { 3004 display: flex; 3005 align-items: center; 3006 justify-content: flex-end; 3007 gap: var(--wpshelf-space-2); 3008 } 3009 3010 .wpshelf-app .tablenav-pages .displaying-num { 3011 margin: 0; 3012 } 3013 3014 .wpshelf-app .tablenav-pages .button { 3015 min-width: 0; 3016 min-height: 0; 3017 padding: 0 10px; 3018 font-size: var(--wpshelf-text-base); 3019 line-height: calc(var(--wpshelf-control-h) - 2px); 3020 vertical-align: middle; 3021 } -
gloty/tags/1.64.0/vendor/wp-shelf/platform/assets/screens.js
r3688478 r3748411 15 15 let request; 16 16 let currentUrl = window.location.href; 17 // The content region the server printed, captured while this footer script 18 // runs. A client router that takes the shell over (Crawlune's and 19 // SnippetGrove's bundles) replaces it, and the ServerScreen it renders 20 // mounts its own content through render() — so a detached capture is the 21 // signal that first-load boot has nothing left to do. 22 const served = document.querySelector('.wpshelf-tab-content'); 17 23 const text = (tag, value, className) => { 18 24 const node = document.createElement(tag); … … 107 113 } 108 114 115 /** Rows above which a table gets a search box. */ 116 const SEARCH_THRESHOLD = 10; 117 // Built once: localeCompare with options builds a collator per comparison, 118 // and a sort over a few thousand rows makes tens of thousands of them. 119 const collator = new Intl.Collator(undefined, { 120 numeric: true, 121 sensitivity: 'base', 122 }); 123 109 124 function tableControls(root) { 110 125 for (const table of root.querySelectorAll( … … 124 139 let sort = -1; 125 140 let direction = 1; 141 // A search box, a "15 / 15 · 1 / 1" counter and Previous/Next on a 142 // one-row table are noise; they appear once there is something to 143 // search or page through. 144 const searchable = rows.length > SEARCH_THRESHOLD; 126 145 const toolbar = document.createElement('div'); 127 146 toolbar.className = 'wpshelf-filters'; 147 toolbar.hidden = !searchable; 128 148 const search = document.createElement('input'); 129 149 search.type = 'search'; … … 133 153 const summary = text('span', '', 'wpshelf-footnote'); 134 154 summary.setAttribute('aria-live', 'polite'); 135 toolbar.append(search, summary); 136 table.before(toolbar); 155 // In the search wrapper, so it takes the filter bar's search width 156 // rather than stretching across the whole card. 157 const searchWrap = document.createElement('div'); 158 searchWrap.className = 'wpshelf-filters__search'; 159 searchWrap.append(search); 160 toolbar.append(searchWrap, summary); 161 // Outside the scrolling wrapper, so the controls stay put while a 162 // wide table scrolls sideways beneath them. 163 const anchor = table.closest('.wpshelf-table-wrap') || table; 164 anchor.before(toolbar); 137 165 const pager = document.createElement('div'); 138 166 pager.className = 'wpshelf-pager'; … … 141 169 previous.type = next.type = 'button'; 142 170 pager.append(previous, next); 143 table.after(pager);171 anchor.after(pager); 144 172 const headers = [...table.tHead.rows[0].cells]; 173 const glyphs = []; 145 174 function draw() { 146 175 const terms = search.value … … 157 186 matching.sort( 158 187 (a, b) => 159 (a.cells[sort]?.textContent || '').localeCompare( 160 b.cells[sort]?.textContent || '', 161 undefined, 162 { numeric: true, sensitivity: 'base' } 188 collator.compare( 189 a.cells[sort]?.textContent || '', 190 b.cells[sort]?.textContent || '' 163 191 ) * direction 164 192 ); … … 172 200 table.tBodies[0].append(row); 173 201 }); 174 summary.textContent = `${matching.length} / ${rows.length} · ${page} / ${pages}`; 202 summary.textContent = 203 pages > 1 || matching.length !== rows.length 204 ? `${matching.length} / ${rows.length} · ${page} / ${pages}` 205 : ''; 175 206 previous.disabled = page <= 1; 176 207 next.disabled = page >= pages; … … 186 217 ) 187 218 ); 219 glyphs.forEach(([index, glyph]) => { 220 const active = index === sort; 221 glyph.textContent = active ? (direction === 1 ? '↑' : '↓') : '↕'; 222 glyph.parentNode.classList.toggle( 223 'wpshelf-table__sort--active', 224 active 225 ); 226 }); 188 227 } 189 228 headers.forEach((header, index) => { … … 193 232 ) 194 233 return; 234 // The label and a dimmed glyph that holds its width, so a 235 // header never wraps onto a line of its own for the arrow. 195 236 const button = text( 196 237 'button', 197 `${header.textContent} ↕`,238 header.textContent.trim(), 198 239 'wpshelf-table__sort' 199 240 ); 241 const glyph = text('span', '↕', 'wpshelf-table__sort-glyph'); 242 glyph.setAttribute('aria-hidden', 'true'); 243 button.append(glyph); 244 glyphs.push([index, glyph]); 200 245 button.type = 'button'; 201 246 header.replaceChildren(button); … … 225 270 } 226 271 227 function mount(root) { 228 mounted.get(root)?.(); 272 /** 273 * Where attention goes once a save has redrawn the screen. 274 * 275 * A full page load would put the reader at the top, beside the notice 276 * WordPress printed. The async swap removed the button that had focus, so 277 * without this focus fell to <body> and a screen reader said nothing. The 278 * notice is the outcome, so it is focused first; failing that, the 279 * heading; failing that, the content region itself. 280 */ 281 function settle(root) { 282 const target = 283 root.querySelector( 284 '.notice, .wpshelf-notice, [role="alert"], [role="status"]' 285 ) || 286 root.querySelector('h1') || 287 root; 288 if (!target.hasAttribute('tabindex')) target.tabIndex = -1; 289 target.focus(); 290 window.scrollTo({ top: 0 }); 291 } 292 293 /** 294 * A failure the reader cannot miss: announced, focused, dismissible. 295 * 296 * The dismiss control is the one WordPress adds to `is-dismissible` 297 * notices on page load, and only then — a notice inserted later gets none 298 * from core, so it is built here. 299 */ 300 function alert(message) { 301 const notice = text('p', message, 'notice notice-error is-dismissible'); 302 notice.setAttribute('role', 'alert'); 303 notice.tabIndex = -1; 304 const dismiss = document.createElement('button'); 305 dismiss.type = 'button'; 306 dismiss.className = 'notice-dismiss'; 307 dismiss.append(text('span', labels.dismiss || 'Dismiss', 'screen-reader-text')); 308 dismiss.addEventListener('click', () => notice.remove()); 309 notice.append(dismiss); 310 return notice; 311 } 312 313 /** Run every registered module on a root; return their cleanups. */ 314 function mountModules(root) { 229 315 const cleanups = []; 230 let submission;231 316 for (const init of modules.values()) { 232 317 const cleanup = init(root); 233 318 if (typeof cleanup === 'function') cleanups.push(cleanup); 234 319 } 320 return cleanups; 321 } 322 323 /** Record how to dispose a root's instance, so the next mount runs it first. */ 324 function remember(root, cleanups) { 325 let disposed = false; 326 const dispose = () => { 327 if (!disposed) { 328 disposed = true; 329 cleanups.reverse().forEach((cleanup) => cleanup()); 330 } 331 }; 332 mounted.set(root, dispose); 333 return () => mounted.get(root)?.(); 334 } 335 336 function mount(root) { 337 mounted.get(root)?.(); 338 const cleanups = mountModules(root); 339 let submission; 235 340 tableControls(root); 236 341 const submit = async (event) => { … … 270 375 submission = new AbortController(); 271 376 root.setAttribute('aria-busy', 'true'); 377 // aria-disabled rather than disabled: a disabled button drops out 378 // of the tab order and throws keyboard focus to the top of the 379 // page. The dataset flag above already stops a second submit. 380 const pressed = event.submitter; 381 pressed?.setAttribute('aria-disabled', 'true'); 382 pressed?.classList.add('wpshelf-is-saving'); 272 383 try { 273 384 await render(url.href, root, { … … 277 388 history: true, 278 389 }); 390 settle(root); 279 391 } catch (error) { 280 392 if (error.name === 'AbortError') return; 281 393 // Never retry a write automatically: the server may have saved it. 282 root.prepend( 283 text( 284 'p', 285 method === 'GET' ? labels.failed : labels.saveFailed, 286 'notice notice-error' 287 ) 394 const notice = alert( 395 method === 'GET' ? labels.failed : labels.saveFailed 288 396 ); 397 root.prepend(notice); 398 notice.focus(); 289 399 } finally { 290 400 delete form.dataset.shelfSubmitting; 291 401 root.removeAttribute('aria-busy'); 402 pressed?.removeAttribute('aria-disabled'); 403 pressed?.classList.remove('wpshelf-is-saving'); 292 404 } 293 405 }; … … 312 424 root.addEventListener('change', change); 313 425 cleanups.push(() => root.removeEventListener('change', change)); 314 let disposed = false; 315 const dispose = () => { 316 if (!disposed) { 317 disposed = true; 318 cleanups.reverse().forEach((cleanup) => cleanup()); 319 } 320 }; 321 mounted.set(root, dispose); 322 return () => mounted.get(root)?.(); 426 return remember(root, cleanups); 323 427 } 324 428 … … 417 521 tableControls, 418 522 refresh: (root) => render(location.href, root, screens.get(root)), 523 // A property, not a method, so a screen script can ask whether the copy 524 // that loaded mounts its module on a plain load — an older sibling's 525 // screens.js may be the one served, and it did not (TASK-106). 526 mountsOnLoad: true, 419 527 }; 528 529 /** 530 * First (non-async) load: mount the registered modules on the screen the 531 * server printed. Before this, a module only mounted from render(), so on 532 * a product that is not standalone every enhancement a screen registered 533 * was inert until something re-rendered it. 534 * 535 * A standalone product gets the whole mount — modules, table controls and 536 * form interception — because its links and saves are async. One that is 537 * not gets its modules only: its forms post and reload, and intercepting 538 * them is what once told a ShareCrew merchant "The save could not be 539 * confirmed" for a save that had succeeded. The product is recorded either 540 * way, so a module that calls refresh() redraws the right screen. Either 541 * way the disposer lands in `mounted`, so a later render() on the same 542 * root cleans this instance before mounting the next: never two live. 543 */ 544 function boot() { 545 const root = served || document.querySelector('.wpshelf-tab-content'); 546 if (!root || !root.isConnected || mounted.has(root)) return; 547 root.dataset.wpshelfPage = new URL(location.href).searchParams.get('page'); 548 screens.set(root, { product: labels.product }); 549 if (labels.standalone) mount(root); 550 else remember(root, mountModules(root)); 551 } 552 420 553 if (labels.standalone) { 421 554 document.addEventListener('click', (event) => { … … 448 581 if (currentUrl !== location.href) navigate(location.href, true); 449 582 }); 450 const boot = () => {451 const root = document.querySelector('.wpshelf-tab-content');452 if (root) {453 root.dataset.wpshelfPage = new URL(location.href).searchParams.get(454 'page'455 );456 screens.set(root, { product: labels.product });457 mount(root);458 }459 };460 583 if (document.readyState !== 'complete') 461 584 window.addEventListener('load', boot, { once: true }); 462 585 else boot(); 586 } else { 587 // DOMContentLoaded rather than load: these screens' forms post for 588 // real, and a guard (a confirm before a money-moving action) has to be 589 // on them before anyone can press one — the moment a page-load-time 590 // script would have attached it. Then one task later, so a client 591 // router that replaces the shell on DOMContentLoaded has done so. 592 const later = () => setTimeout(boot, 0); 593 if (document.readyState === 'loading') 594 document.addEventListener('DOMContentLoaded', later, { once: true }); 595 else later(); 463 596 } 464 597 })(); -
gloty/tags/1.64.0/vendor/wp-shelf/platform/src/AdminAssets.php
r3723648 r3748411 45 45 * cards computed `border: none`. 46 46 * 47 * So the file is chosen by **mtime across every installed copy**, not by which 48 * class won. A stylesheet has no API to call and no version to negotiate; the 49 * newest one on disk is a superset of the older ones, because this package only 50 * ever adds — *if* newest on disk meant newest built, and it does not. WordPress 51 * writes each file as it unzips, so the mtime is when that plugin was last 52 * installed or updated on this site: updating the plugin with the stalest 53 * vendored copy makes that copy win (measured 2026-09-23, see 54 * docs/operations/shelf-coinstall-final-2026-09-23.md). A shared-asset change is 55 * durable only once every shelf plugin has shipped it, and 56 * infra/wordpress/shelf-together-check.sh fails when installed copies disagree. 47 * So the file is chosen **across every installed copy**, not by which class 48 * won. A stylesheet has no API to call and no version to negotiate; the newest 49 * copy is a superset of the older ones, because this package only ever adds. 50 * "Newest" was first taken from mtime, and that was wrong in a way that took a 51 * measurement to see: WordPress writes each file as it unzips, so the mtime is 52 * when that plugin was last installed or updated on this site, and updating the 53 * plugin with the stalest vendored copy made that copy win (2026-09-23, 54 * docs/operations/shelf-coinstall-final-2026-09-23.md). 55 * 56 * Newest now means the highest **revision stamp** — `assets/revision.txt`, 57 * written by `scripts/stamp-shared-assets.php`, committed beside the assets and 58 * copied wherever they are copied. It describes the bytes, not the install, so 59 * which plugin the customer updated last stops mattering. Mtime remains the 60 * tie-breaker, and the whole answer for copies vendored before the stamp 61 * existed. Two limits still hold: the *class* that does the choosing is still 62 * whichever copy won, so an old sibling's `AdminAssets` keeps choosing by mtime 63 * until that sibling is updated; and a shared-asset change is durable only once 64 * every shelf plugin has shipped it. infra/wordpress/shelf-together-check.sh 65 * fails when installed copies disagree. 57 66 * 58 67 * The class API is a different matter and cannot be fixed this way — the winning … … 149 158 * stylesheet for a day with a one-year max-age. 150 159 * 151 * The file's own mtime keys the URL to the bytes instead. It changes on any 152 * deploy that rewrites the file and on no deploy that does not. 160 * The copy's revision stamp keys the URL to the bytes instead: identical 161 * bytes get an identical URL whichever plugin they are served from, and a 162 * new revision is a new URL. A copy with no stamp — one vendored before the 163 * stamp existed — falls back to its mtime, which changes on any deploy that 164 * rewrites the file and on no deploy that does not. 153 165 * 154 166 * @param string $fallback Used when the file cannot be stat'd. … … 156 168 */ 157 169 private static function cache_key( string $fallback, string $file = 'admin.css' ): string { 158 $path = self::newest_path_for( $file ); 159 $mtime = '' !== $path && \is_readable( $path ) ? \filemtime( $path ) : false; 170 $path = self::newest_path_for( $file ); 171 172 if ( '' === $path || ! \is_readable( $path ) ) { 173 return $fallback; 174 } 175 176 $revision = self::revision_of( $path ); 177 178 if ( $revision > 0 ) { 179 return (string) $revision; 180 } 181 182 $mtime = \filemtime( $path ); 160 183 161 184 return false !== $mtime ? (string) $mtime : $fallback; … … 201 224 202 225 /** 203 * The most recently modified of a list of paths.226 * The newest of a list of copies: highest revision stamp, then latest mtime. 204 227 * 205 228 * Split out from the glob so it can be tested: the decision is the part with … … 208 231 * mid-update whose file is briefly gone cannot win by being unstat-able. 209 232 * 233 * The revision comes from `revision.txt` beside the copy, written by 234 * `scripts/stamp-shared-assets.php` and committed with the assets it 235 * describes — so it is a fact about the bytes, where the mtime is a fact 236 * about when this site unpacked them. A copy with no stamp predates the 237 * stamp and so is older than any copy that has one; among unstamped copies 238 * the mtime still decides, which is exactly the previous behaviour. 239 * 210 240 * @param list<string> $paths Absolute paths, any of which may not exist. 211 241 * … … 213 243 */ 214 244 private static function newest( array $paths ): string { 215 $best = ''; 216 $mtime = -1; 245 $best = ''; 246 $revision = -1; 247 $mtime = -1; 217 248 218 249 foreach ( $paths as $path ) { … … 221 252 } 222 253 223 $candidate = (int) \filemtime( $path ); 224 225 if ( $candidate > $mtime ) { 226 $best = $path; 227 $mtime = $candidate; 254 $candidate_revision = self::revision_of( $path ); 255 $candidate_mtime = (int) \filemtime( $path ); 256 257 if ( 258 $candidate_revision > $revision 259 || ( $candidate_revision === $revision && $candidate_mtime > $mtime ) 260 ) { 261 $best = $path; 262 $revision = $candidate_revision; 263 $mtime = $candidate_mtime; 228 264 } 229 265 } 230 266 231 267 return $best; 268 } 269 270 /** 271 * The revision stamped beside a copy of an asset, or 0 when it has none. 272 * 273 * The first line of `revision.txt` in the asset's directory, as an integer. 274 * Anything else in the file — the comment, the per-file hashes the stamp 275 * script checks — is for people and for `--check`, not for this method. 276 * Read once per directory per request: a site with five of our plugins 277 * asks about three files in each of five directories. 278 * 279 * @param string $asset_path Absolute path of a copy of an asset. 280 */ 281 private static function revision_of( string $asset_path ): int { 282 /** @var array<string, int> $revisions */ 283 static $revisions = []; 284 285 $dir = \dirname( $asset_path ); 286 287 if ( isset( $revisions[ $dir ] ) ) { 288 return $revisions[ $dir ]; 289 } 290 291 $manifest = $dir . '/revision.txt'; 292 $first = ''; 293 294 if ( \is_readable( $manifest ) ) { 295 $handle = \fopen( $manifest, 'r' ); 296 297 if ( false !== $handle ) { 298 $first = \trim( (string) \fgets( $handle ) ); 299 \fclose( $handle ); 300 } 301 } 302 303 $revisions[ $dir ] = '' !== $first && \ctype_digit( $first ) ? (int) $first : 0; 304 305 return $revisions[ $dir ]; 232 306 } 233 307 -
gloty/tags/1.64.0/vendor/wp-shelf/platform/src/AsyncScreens.php
r3688478 r3748411 42 42 'next' => \__('Next', 'default'), 43 43 'loaded' => \__('Search and sort apply to the loaded rows.', 'default'), 44 'dismiss' => \__('Dismiss this notice.', 'default'), 44 45 ], $labels)); 45 46 } -
gloty/tags/1.64.0/vendor/wp-shelf/platform/src/LicenseClient.php
r3723648 r3748411 133 133 $this->store_license_key( $key ); 134 134 $this->cache_status( $response ); 135 LicenseRefusal::clear( $this->config ); 135 136 } 136 137 … … 183 184 * response: a licensing outage must not stop a paying customer working. 184 185 * 186 * **A refusal is not an outage, and is not answered like one.** When the 187 * service answers and the answer is the uniform refusal (see 188 * {@see LicenseRefusal::is_refusal()}) — the key was rotated, or the 189 * licence it belonged to is gone — the cached status is dropped, the 190 * refusal is recorded for the product's screens to explain, and this 191 * returns null at once. It used to keep serving the cached plan for up to 192 * the status TTL and then return null anyway, which every caller read as 193 * "could not reach the service": the site stopped validating and blamed 194 * the network. Null is still what callers get, so `is_dispatch_allowed()` 195 * fails open exactly as before; what changed is that the plugin can now 196 * tell its owner why. An unreachable server, a 429 or a 5xx still fall 197 * back to the cache. 198 * 185 199 * The key is tested before the server URL is resolved, and the order is the 186 200 * point. Resolving reads the server-URL option, which SnippetGrove and … … 217 231 $response = ( $post['ok'] && isset( $post['data'] ) ) ? $post['data'] : null; 218 232 233 if ( LicenseRefusal::is_refusal( $response ) ) { 234 LicenseRefusal::record( $this->config, $key ); 235 \delete_transient( $this->config->status_transient ); 236 return null; 237 } 238 219 239 if ( ! is_array( $response ) || empty( $response['ok'] ) ) { 220 240 return $this->cached_status(); … … 222 242 223 243 $this->cache_status( $response ); 244 LicenseRefusal::clear( $this->config ); 224 245 225 246 return $response; … … 368 389 $this->store_license_key( '' ); 369 390 \delete_transient( $this->config->status_transient ); 391 LicenseRefusal::clear( $this->config ); 370 392 } 371 393 -
gloty/trunk/build/gloty-admin.asset.php
r3723648 r3748411 1 <?php return array('dependencies' => array('react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => ' e3d859e836b549af3807');1 <?php return array('dependencies' => array('react-dom', 'react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '3f1856f97a09438ce020'); -
gloty/trunk/build/gloty-admin.js
r3723648 r3748411 1 (()=>{"use strict";var e,s={843(e,s,t){var a=t(930);const l=window.wp.i18n,n=window.wp.element;function i({search:e=null,filters:s=[],count:t=null,countLabel:a=null,onClear:l=null,clearLabel:i=null,children:r=null}){const o=e&&e.value||s.some(e=>""!==e.value&&null!=e.value);return(0,n.createElement)("div",{className:"wpshelf-filters"},e?(0,n.createElement)("div",{className:"wpshelf-filters__search"},(0,n.createElement)("input",{type:"search",className:"wpshelf-filters__search-input",value:e.value,placeholder:e.placeholder,"aria-label":e.label||e.placeholder,onChange:s=>e.onChange(s.target.value)})):null,s.map(e=>(0,n.createElement)("select",{key:e.label,className:"wpshelf-filters__select",value:e.value,"aria-label":e.label,onChange:s=>e.onChange(s.target.value)},e.options.map(e=>(0,n.createElement)("option",{key:e.value,value:e.value},e.label)))),r,null!==t&&a?(0,n.createElement)("span",{className:"wpshelf-filters__count",role:"status"},a):null,l&&o&&i?(0,n.createElement)("button",{type:"button",className:"wpshelf-linkbtn",onClick:l},i):null)}function r({label:e,onPrev:s,onNext:t,prevDisabled:a=!1,nextDisabled:l=!1,prevLabel:i,nextLabel:r}){return(0,n.createElement)("div",{className:"wpshelf-pager"},(0,n.createElement)("span",{className:"wpshelf-pager__label"},e),(0,n.createElement)("span",{className:"wpshelf-pager__controls"},(0,n.createElement)("button",{type:"button",className:"button",onClick:s,disabled:a},i),(0,n.createElement)("button",{type:"button",className:"button",onClick:t,disabled:l},r)))} function o(e){return n.Children.toArray(e).map(e=>(0,n.isValidElement)(e)?e.props["data-search"]??o(e.props.children??e.props.label??e.props.value??""):String(e)).join(" ")}function c(e){return n.Children.toArray(e).some(e=>(0,n.isValidElement)(e)&&("string"!=typeof e.type||["input","button","select","a"].includes(e.type)||c(e.props.children)))}function d(e){return n.Children.toArray(e).some(e=>(0,n.isValidElement)(e)&&("checkbox"===e.props.type||void 0!==e.props.checked||d(e.props.children)))}function h(e){return n.Children.map(e,e=>{if(!(0,n.isValidElement)(e))return e;const s="checkbox"===e.props.type||void 0!==e.props.checked;return(0,n.cloneElement)(e,s?{disabled:!0}:{},void 0===e.props.children?void 0:h(e.props.children))})}function g({children:e,labels:s,pageSize:t=25,...a}){const[l,g]=(0,n.useState)(""),[u,_]=(0,n.useState)({column:-1,direction:1}),[p,m]=(0,n.useState)(1),y=n.Children.toArray(e),f=y.find(e=>"tbody"===e.type),w=y.find(e=>"thead"===e.type),x=n.Children.toArray(f?.props.children);if(!w||!f||x.some(e=>"tr"!==e.type))return(0,n.createElement)("table",a,e);d(w)&&(t=Math.max(x.length,1));const v=l.toLocaleLowerCase().trim().split(/\s+/).filter(Boolean),j=x.filter(e=>!e.props.hidden&&v.every(s=>o(e).toLocaleLowerCase().includes(s)));u.column>=0&&j.sort((e,s)=>o(n.Children.toArray(e.props.children)[u.column]).localeCompare(o(n.Children.toArray(s.props.children)[u.column]),void 0,{numeric:!0,sensitivity:"base"})*u.direction);const b=Math.max(1,Math.ceil(j.length/t)),N=Math.min(p,b),C=new Set(j.slice((N-1)*t,N*t).map(e=>e.key)),S=[...j,...x.filter(e=>!j.includes(e))],k=(0,n.cloneElement)(w,{},n.Children.map(w.props.children,e=>(0,n.cloneElement)(e,{},n.Children.map(e.props.children,(e,s)=>(0,n.isValidElement)(e)&&!c(e.props.children)&&o(e).trim()?(0,n.cloneElement)(e,{"aria-sort":u.column===s?{1:"ascending","-1":"descending"}[u.direction]:"none"},(0,n.createElement)("button",{type:"button",className:"wpshelf-table__sort",onClick:()=>{_({column:s,direction:u.column===s?-u.direction:1}),m(1)}},e.props.children,(0,n.createElement)("span",{"aria-hidden":!0}," ↕"))):l&&(0,n.isValidElement)(e)?(0,n.cloneElement)(e,{},h(e.props.children)):e))));return(0,n.createElement)(n.Fragment,null,(0,n.createElement)(i,{search:{value:l,onChange:e=>{g(e),m(1)},label:s.search,placeholder:s.search},count:j.length,countLabel:`${j.length} / ${x.length}`}),(0,n.createElement)("table",{...a,"data-shelf-table":"react"},y.map(e=>e===w?k:e===f?(0,n.cloneElement)(f,{},S.map(e=>(0,n.cloneElement)(e,{hidden:!C.has(e.key)}))):e)),b>1?(0,n.createElement)(r,{label:`${N} / ${b}`,prevLabel:s.previous,nextLabel:s.next,prevDisabled:N<=1,nextDisabled:N>=b,onPrev:()=>m(N-1),onNext:()=>m(N+1)}):null)}const u=window.ReactJSXRuntime;function _(e){return(0,u.jsx)(g,{...e,labels:{search:(0,l.__)("Filter loaded rows","gloty"),previous:(0,l.__)("Previous","gloty"),next:(0,l.__)("Next","gloty")}})}const p=window.wp.apiFetch;var m=t.n(p);const y=window.wp.components,f=window.wp.data;var w=(0,n.forwardRef)(({icon:e,size:s=24,...t},a)=>(0,n.cloneElement)(e,{width:s,height:s,...t,ref:a}));const x=window.wp.primitives;var v=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M6.5 12.4L12 8l5.5 4.4-.9 1.2L12 10l-4.5 3.6-1-1.2z"})}),j=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"})}),b=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8Zm6.5 8c0 .6 0 1.2-.2 1.8h-2.7c0-.6.2-1.1.2-1.8s0-1.2-.2-1.8h2.7c.2.6.2 1.1.2 1.8Zm-.9-3.2h-2.4c-.3-.9-.7-1.8-1.1-2.4-.1-.2-.2-.4-.3-.5 1.6.5 3 1.6 3.8 3ZM12.8 17c-.3.5-.6 1-.8 1.3-.2-.3-.5-.8-.8-1.3-.3-.5-.6-1.1-.8-1.7h3.3c-.2.6-.5 1.2-.8 1.7Zm-2.9-3.2c-.1-.6-.2-1.1-.2-1.8s0-1.2.2-1.8H14c.1.6.2 1.1.2 1.8s0 1.2-.2 1.8H9.9ZM11.2 7c.3-.5.6-1 .8-1.3.2.3.5.8.8 1.3.3.5.6 1.1.8 1.7h-3.3c.2-.6.5-1.2.8-1.7Zm-1-1.2c-.1.2-.2.3-.3.5-.4.7-.8 1.5-1.1 2.4H6.4c.8-1.4 2.2-2.5 3.8-3Zm-1.8 8H5.7c-.2-.6-.2-1.1-.2-1.8s0-1.2.2-1.8h2.7c0 .6-.2 1.1-.2 1.8s0 1.2.2 1.8Zm-2 1.4h2.4c.3.9.7 1.8 1.1 2.4.1.2.2.4.3.5-1.6-.5-3-1.6-3.8-3Zm7.4 3c.1-.2.2-.3.3-.5.4-.7.8-1.5 1.1-2.4h2.4c-.8 1.4-2.2 2.5-3.8 3Z"})}),N=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M12 4L4 7.9V20h16V7.9L12 4zm6.5 14.5H14V13h-4v5.5H5.5V8.8L12 5.7l6.5 3.1v9.7z"})}),C=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"m11.3 17.2-5-5c-.1-.1-.1-.3 0-.4l2.3-2.3-1.1-1-2.3 2.3c-.7.7-.7 1.8 0 2.5l5 5H7.5v1.5h5.3v-5.2h-1.5v2.6zm7.5-6.4-5-5h2.7V4.2h-5.2v5.2h1.5V6.8l5 5c.1.1.1.3 0 .4l-2.3 2.3 1.1 1.1 2.3-2.3c.6-.7.6-1.9-.1-2.5z"})}),S=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M11.25 5h1.5v15h-1.5V5zM6 10h1.5v10H6V10zm12 4h-1.5v6H18v-6z"})}),k=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M17.5 10h-1.7l-3.7 10.5h1.7l.9-2.6h3.9l.9 2.6h1.7L17.5 10zm-2.2 6.3 1.4-4 1.4 4h-2.8zm-4.8-3.8c1.6-1.8 2.9-3.6 3.7-5.7H16V5.2h-5.8V3H8.8v2.2H3v1.5h9.6c-.7 1.6-1.8 3.1-3.1 4.6C8.6 10.2 7.8 9 7.2 8H5.6c.6 1.4 1.7 2.9 2.9 4.4l-2.4 2.4c-.3.4-.7.8-1.1 1.2l1 1 1.2-1.2c.8-.8 1.6-1.5 2.3-2.3.8.9 1.7 1.7 2.5 2.5l.6-1.5c-.7-.6-1.4-1.3-2.1-2z"})}),T=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M4.75 4a.75.75 0 0 0-.75.75v7.826c0 .2.08.39.22.53l6.72 6.716a2.313 2.313 0 0 0 3.276-.001l5.61-5.611-.531-.53.532.528a2.315 2.315 0 0 0 0-3.264L13.104 4.22a.75.75 0 0 0-.53-.22H4.75ZM19 12.576a.815.815 0 0 1-.236.574l-5.61 5.611a.814.814 0 0 1-1.153 0L5.5 12.264V5.5h6.763l6.5 6.502a.816.816 0 0 1 .237.574ZM8.75 9.75a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"})}),B=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M13 5c-3.3 0-6 2.7-6 6 0 1.4.5 2.7 1.3 3.7l-3.8 3.8 1.1 1.1 3.8-3.8c1 .8 2.3 1.3 3.7 1.3 3.3 0 6-2.7 6-6S16.3 5 13 5zm0 10.5c-2.5 0-4.5-2-4.5-4.5s2-4.5 4.5-4.5 4.5 2 4.5 4.5-2 4.5-4.5 4.5z"})}),E=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M10.289 4.836A1 1 0 0111.275 4h1.306a1 1 0 01.987.836l.244 1.466c.787.26 1.503.679 2.108 1.218l1.393-.522a1 1 0 011.216.437l.653 1.13a1 1 0 01-.23 1.273l-1.148.944a6.025 6.025 0 010 2.435l1.149.946a1 1 0 01.23 1.272l-.653 1.13a1 1 0 01-1.216.437l-1.394-.522c-.605.54-1.32.958-2.108 1.218l-.244 1.466a1 1 0 01-.987.836h-1.306a1 1 0 01-.986-.836l-.244-1.466a5.995 5.995 0 01-2.108-1.218l-1.394.522a1 1 0 01-1.217-.436l-.653-1.131a1 1 0 01.23-1.272l1.149-.946a6.026 6.026 0 010-2.435l-1.148-.944a1 1 0 01-.23-1.272l.653-1.131a1 1 0 011.217-.437l1.393.522a5.994 5.994 0 012.108-1.218l.244-1.466zM14.929 12a3 3 0 11-6 0 3 3 0 016 0z"})}),L=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M16.83 6.342l.602.3.625-.25.443-.176v12.569l-.443-.178-.625-.25-.603.301-1.444.723-2.41-.804-.475-.158-.474.158-2.41.803-1.445-.722-.603-.3-.625.25-.443.177V6.215l.443.178.625.25.603-.301 1.444-.722 2.41.803.475.158.474-.158 2.41-.803 1.445.722zM20 4l-1.5.6-1 .4-2-1-3 1-3-1-2 1-1-.4L5 4v17l1.5-.6 1-.4 2 1 3-1 3 1 2-1 1 .4 1.5.6V4zm-3.5 6.25v-1.5h-8v1.5h8zm0 3v-1.5h-8v1.5h8zm-8 3v-1.5h8v1.5h-8z"})}),M=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M12 4a8 8 0 1 1 .001 16.001A8 8 0 0 1 12 4Zm0 1.5a6.5 6.5 0 1 0-.001 13.001A6.5 6.5 0 0 0 12 5.5Zm.75 11h-1.5V15h1.5v1.5Zm-.445-9.234a3 3 0 0 1 .445 5.89V14h-1.5v-1.25c0-.57.452-.958.917-1.01A1.5 1.5 0 0 0 12 8.75a1.5 1.5 0 0 0-1.5 1.5H9a3 3 0 0 1 3.305-2.984Z"})}),A=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M4 20h8v-1.5H4V20zM18.9 3.5c-.6-.6-1.5-.6-2.1 0l-7.2 7.2c-.4-.1-.7 0-1.1.1-.5.2-1.5.7-1.9 2.2-.4 1.7-.8 2.2-1.1 2.7-.1.1-.2.3-.3.4l-.6 1.1H6c2 0 3.4-.4 4.7-1.4.8-.6 1.2-1.4 1.3-2.3 0-.3 0-.5-.1-.7L19 5.7c.5-.6.5-1.6-.1-2.2zM9.7 14.7c-.7.5-1.5.8-2.4 1 .2-.5.5-1.2.8-2.3.2-.6.4-1 .8-1.1.5-.1 1 .1 1.3.3.2.2.3.5.2.8 0 .3-.1.9-.7 1.3z"})});const D=Object.freeze({width:720,height:180,top:16,right:14,bottom:26,left:48}),R=Object.freeze({width:96,height:24,inset:3});function O(e){return Math.round(100*e)/100}function P(e){const s=/^(\d{4})-(\d{2})-(\d{2})$/.exec(String(e||""));if(!s)return null;const t=new Date(Number(s[1]),Number(s[2])-1,Number(s[3]));return Number.isNaN(t.getTime())?null:t}function $(e){const s=P(e);return s?new Intl.DateTimeFormat(void 0,{month:"short",day:"numeric"}).format(s):String(e||"")}function I(e){return(new Intl.NumberFormat).format(Math.round(e||0))}const H=D.height-D.bottom;function G(e){return!e||e.length<2?"":e.map((e,s)=>`${0===s?"M":"L"}${e.x} ${e.y}`).join(" ")}function z(e){const s=G(e);if(""===s)return"";const t=e[0];return`${s} L${e[e.length-1].x} ${H} L${t.x} ${H} Z`}function F(e){const s=(Array.isArray(e)?e:[]).map(e=>Number(e)||0);if(s.length<2)return"single";const t=Math.floor(s.length/2),a=e=>0===e.length?0:e.reduce((e,s)=>e+s,0)/e.length,l=a(s.slice(0,t)),n=a(s.slice(t));return 0===l?n>0?"rising":"steady":n>1.1*l?"rising":n<.9*l?"falling":"steady"}function V(e){switch(e){case"rising":return(0,l.__)("Rising","gloty");case"falling":return(0,l.__)("Falling","gloty");case"single":return(0,l.__)("One day","gloty");default:return(0,l.__)("Steady","gloty")}}function U({values:e=[],label:s=""}){const{mode:t,points:a,max:n}=function(e,s={}){const t=s.width??R.width,a=s.height??R.height,l=s.inset??R.inset,n=(Array.isArray(e)?e:[]).map(e=>Number(e)||0);if(0===n.length)return{mode:"empty",points:[],max:0};if(1===n.length)return{mode:"single",points:[{x:O(t/2),y:O(a/2)}],max:n[0]};const i=Math.max(...n),r=t-2*l,o=a-2*l,c=e=>O(l+e/(n.length-1)*r);return i<=0?{mode:"flat",points:n.map((e,s)=>({x:c(s),y:O(a-l)})),max:0}:{mode:"line",points:n.map((e,s)=>({x:c(s),y:O(l+o*(1-e/i))})),max:i}}(e),i=F(e),r=n<=0&&"empty"!==t?(0,l.sprintf)(/* translators: %s: series name. */ /* translators: %s: series name. */1 (()=>{"use strict";var e,s={843(e,s,t){var a=t(930);const l=window.wp.i18n,n=window.wp.element;function i({search:e=null,filters:s=[],count:t=null,countLabel:a=null,onClear:l=null,clearLabel:i=null,children:r=null}){const o=e&&e.value||s.some(e=>""!==e.value&&null!=e.value);return(0,n.createElement)("div",{className:"wpshelf-filters"},e?(0,n.createElement)("div",{className:"wpshelf-filters__search"},(0,n.createElement)("input",{type:"search",className:"wpshelf-filters__search-input",value:e.value,placeholder:e.placeholder,"aria-label":e.label||e.placeholder,onChange:s=>e.onChange(s.target.value)})):null,s.map(e=>(0,n.createElement)("select",{key:e.label,className:"wpshelf-filters__select",value:e.value,"aria-label":e.label,onChange:s=>e.onChange(s.target.value)},e.options.map(e=>(0,n.createElement)("option",{key:e.value,value:e.value},e.label)))),r,null!==t&&a?(0,n.createElement)("span",{className:"wpshelf-filters__count",role:"status"},a):null,l&&o&&i?(0,n.createElement)("button",{type:"button",className:"wpshelf-linkbtn",onClick:l},i):null)}function r({label:e,onPrev:s,onNext:t,prevDisabled:a=!1,nextDisabled:l=!1,prevLabel:i,nextLabel:r}){return(0,n.createElement)("div",{className:"wpshelf-pager"},(0,n.createElement)("span",{className:"wpshelf-pager__label"},e),(0,n.createElement)("span",{className:"wpshelf-pager__controls"},(0,n.createElement)("button",{type:"button",className:"button",onClick:s,disabled:a},i),(0,n.createElement)("button",{type:"button",className:"button",onClick:t,disabled:l},r)))}const o=new Intl.Collator(void 0,{numeric:!0,sensitivity:"base"});function c(e){return n.Children.toArray(e).map(e=>(0,n.isValidElement)(e)?e.props["data-search"]??c(e.props.children??e.props.label??e.props.value??""):String(e)).join(" ")}function d(e){return n.Children.toArray(e).some(e=>(0,n.isValidElement)(e)&&("string"!=typeof e.type||["input","button","select","a"].includes(e.type)||d(e.props.children)))}function h(e){return n.Children.toArray(e).some(e=>(0,n.isValidElement)(e)&&("checkbox"===e.props.type||void 0!==e.props.checked||h(e.props.children)))}function g(e){return n.Children.map(e,e=>{if(!(0,n.isValidElement)(e))return e;const s="checkbox"===e.props.type||void 0!==e.props.checked;return(0,n.cloneElement)(e,s?{disabled:!0}:{},void 0===e.props.children?void 0:g(e.props.children))})}function u({children:e,labels:s,pageSize:t=25,...a}){const[l,u]=(0,n.useState)(""),[_,p]=(0,n.useState)({column:-1,direction:1}),[m,y]=(0,n.useState)(1),f=n.Children.toArray(e),w=f.find(e=>"tbody"===e.type),x=f.find(e=>"thead"===e.type),v=n.Children.toArray(w?.props.children);if(!x||!w||v.some(e=>"tr"!==e.type))return(0,n.createElement)("table",a,e);h(x)&&(t=Math.max(v.length,1));const j=l.toLocaleLowerCase().trim().split(/\s+/).filter(Boolean),b=v.filter(e=>!e.props.hidden&&j.every(s=>c(e).toLocaleLowerCase().includes(s)));_.column>=0&&b.sort((e,s)=>o.compare(c(n.Children.toArray(e.props.children)[_.column]),c(n.Children.toArray(s.props.children)[_.column]))*_.direction);const N=Math.max(1,Math.ceil(b.length/t)),C=Math.min(m,N),S=new Set(b.slice((C-1)*t,C*t).map(e=>e.key)),k=[...b,...v.filter(e=>!b.includes(e))],T=(0,n.cloneElement)(x,{},n.Children.map(x.props.children,e=>(0,n.cloneElement)(e,{},n.Children.map(e.props.children,(e,s)=>(0,n.isValidElement)(e)&&!d(e.props.children)&&c(e).trim()?(0,n.cloneElement)(e,{"aria-sort":_.column===s?{1:"ascending","-1":"descending"}[_.direction]:"none"},(0,n.createElement)("button",{type:"button",className:"wpshelf-table__sort",onClick:()=>{p({column:s,direction:_.column===s?-_.direction:1}),y(1)}},e.props.children,(0,n.createElement)("span",{"aria-hidden":!0}," ↕"))):l&&(0,n.isValidElement)(e)?(0,n.cloneElement)(e,{},g(e.props.children)):e))));return(0,n.createElement)(n.Fragment,null,(0,n.createElement)(i,{search:{value:l,onChange:e=>{u(e),y(1)},label:s.search,placeholder:s.search},count:b.length,countLabel:`${b.length} / ${v.length}`}),(0,n.createElement)("table",{...a,"data-shelf-table":"react"},f.map(e=>e===x?T:e===w?(0,n.cloneElement)(w,{},k.map(e=>(0,n.cloneElement)(e,{hidden:!S.has(e.key)}))):e)),N>1?(0,n.createElement)(r,{label:`${C} / ${N}`,prevLabel:s.previous,nextLabel:s.next,prevDisabled:C<=1,nextDisabled:C>=N,onPrev:()=>y(C-1),onNext:()=>y(C+1)}):null)}const _=window.ReactJSXRuntime;function p(e){return(0,_.jsx)(u,{...e,labels:{search:(0,l.__)("Filter loaded rows","gloty"),previous:(0,l.__)("Previous","gloty"),next:(0,l.__)("Next","gloty")}})}const m=window.wp.apiFetch;var y=t.n(m);const f=window.wp.components,w=window.wp.data;var x=(0,n.forwardRef)(({icon:e,size:s=24,...t},a)=>(0,n.cloneElement)(e,{width:s,height:s,...t,ref:a}));const v=window.wp.primitives;var j=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M6.5 12.4L12 8l5.5 4.4-.9 1.2L12 10l-4.5 3.6-1-1.2z"})}),b=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"})}),N=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8Zm6.5 8c0 .6 0 1.2-.2 1.8h-2.7c0-.6.2-1.1.2-1.8s0-1.2-.2-1.8h2.7c.2.6.2 1.1.2 1.8Zm-.9-3.2h-2.4c-.3-.9-.7-1.8-1.1-2.4-.1-.2-.2-.4-.3-.5 1.6.5 3 1.6 3.8 3ZM12.8 17c-.3.5-.6 1-.8 1.3-.2-.3-.5-.8-.8-1.3-.3-.5-.6-1.1-.8-1.7h3.3c-.2.6-.5 1.2-.8 1.7Zm-2.9-3.2c-.1-.6-.2-1.1-.2-1.8s0-1.2.2-1.8H14c.1.6.2 1.1.2 1.8s0 1.2-.2 1.8H9.9ZM11.2 7c.3-.5.6-1 .8-1.3.2.3.5.8.8 1.3.3.5.6 1.1.8 1.7h-3.3c.2-.6.5-1.2.8-1.7Zm-1-1.2c-.1.2-.2.3-.3.5-.4.7-.8 1.5-1.1 2.4H6.4c.8-1.4 2.2-2.5 3.8-3Zm-1.8 8H5.7c-.2-.6-.2-1.1-.2-1.8s0-1.2.2-1.8h2.7c0 .6-.2 1.1-.2 1.8s0 1.2.2 1.8Zm-2 1.4h2.4c.3.9.7 1.8 1.1 2.4.1.2.2.4.3.5-1.6-.5-3-1.6-3.8-3Zm7.4 3c.1-.2.2-.3.3-.5.4-.7.8-1.5 1.1-2.4h2.4c-.8 1.4-2.2 2.5-3.8 3Z"})}),C=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M12 4L4 7.9V20h16V7.9L12 4zm6.5 14.5H14V13h-4v5.5H5.5V8.8L12 5.7l6.5 3.1v9.7z"})}),S=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"m11.3 17.2-5-5c-.1-.1-.1-.3 0-.4l2.3-2.3-1.1-1-2.3 2.3c-.7.7-.7 1.8 0 2.5l5 5H7.5v1.5h5.3v-5.2h-1.5v2.6zm7.5-6.4-5-5h2.7V4.2h-5.2v5.2h1.5V6.8l5 5c.1.1.1.3 0 .4l-2.3 2.3 1.1 1.1 2.3-2.3c.6-.7.6-1.9-.1-2.5z"})}),k=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M11.25 5h1.5v15h-1.5V5zM6 10h1.5v10H6V10zm12 4h-1.5v6H18v-6z"})}),T=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M17.5 10h-1.7l-3.7 10.5h1.7l.9-2.6h3.9l.9 2.6h1.7L17.5 10zm-2.2 6.3 1.4-4 1.4 4h-2.8zm-4.8-3.8c1.6-1.8 2.9-3.6 3.7-5.7H16V5.2h-5.8V3H8.8v2.2H3v1.5h9.6c-.7 1.6-1.8 3.1-3.1 4.6C8.6 10.2 7.8 9 7.2 8H5.6c.6 1.4 1.7 2.9 2.9 4.4l-2.4 2.4c-.3.4-.7.8-1.1 1.2l1 1 1.2-1.2c.8-.8 1.6-1.5 2.3-2.3.8.9 1.7 1.7 2.5 2.5l.6-1.5c-.7-.6-1.4-1.3-2.1-2z"})}),B=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M4.75 4a.75.75 0 0 0-.75.75v7.826c0 .2.08.39.22.53l6.72 6.716a2.313 2.313 0 0 0 3.276-.001l5.61-5.611-.531-.53.532.528a2.315 2.315 0 0 0 0-3.264L13.104 4.22a.75.75 0 0 0-.53-.22H4.75ZM19 12.576a.815.815 0 0 1-.236.574l-5.61 5.611a.814.814 0 0 1-1.153 0L5.5 12.264V5.5h6.763l6.5 6.502a.816.816 0 0 1 .237.574ZM8.75 9.75a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"})}),E=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M13 5c-3.3 0-6 2.7-6 6 0 1.4.5 2.7 1.3 3.7l-3.8 3.8 1.1 1.1 3.8-3.8c1 .8 2.3 1.3 3.7 1.3 3.3 0 6-2.7 6-6S16.3 5 13 5zm0 10.5c-2.5 0-4.5-2-4.5-4.5s2-4.5 4.5-4.5 4.5 2 4.5 4.5-2 4.5-4.5 4.5z"})}),L=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M10.289 4.836A1 1 0 0111.275 4h1.306a1 1 0 01.987.836l.244 1.466c.787.26 1.503.679 2.108 1.218l1.393-.522a1 1 0 011.216.437l.653 1.13a1 1 0 01-.23 1.273l-1.148.944a6.025 6.025 0 010 2.435l1.149.946a1 1 0 01.23 1.272l-.653 1.13a1 1 0 01-1.216.437l-1.394-.522c-.605.54-1.32.958-2.108 1.218l-.244 1.466a1 1 0 01-.987.836h-1.306a1 1 0 01-.986-.836l-.244-1.466a5.995 5.995 0 01-2.108-1.218l-1.394.522a1 1 0 01-1.217-.436l-.653-1.131a1 1 0 01.23-1.272l1.149-.946a6.026 6.026 0 010-2.435l-1.148-.944a1 1 0 01-.23-1.272l.653-1.131a1 1 0 011.217-.437l1.393.522a5.994 5.994 0 012.108-1.218l.244-1.466zM14.929 12a3 3 0 11-6 0 3 3 0 016 0z"})}),M=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M16.83 6.342l.602.3.625-.25.443-.176v12.569l-.443-.178-.625-.25-.603.301-1.444.723-2.41-.804-.475-.158-.474.158-2.41.803-1.445-.722-.603-.3-.625.25-.443.177V6.215l.443.178.625.25.603-.301 1.444-.722 2.41.803.475.158.474-.158 2.41-.803 1.445.722zM20 4l-1.5.6-1 .4-2-1-3 1-3-1-2 1-1-.4L5 4v17l1.5-.6 1-.4 2 1 3-1 3 1 2-1 1 .4 1.5.6V4zm-3.5 6.25v-1.5h-8v1.5h8zm0 3v-1.5h-8v1.5h8zm-8 3v-1.5h8v1.5h-8z"})}),A=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M12 4a8 8 0 1 1 .001 16.001A8 8 0 0 1 12 4Zm0 1.5a6.5 6.5 0 1 0-.001 13.001A6.5 6.5 0 0 0 12 5.5Zm.75 11h-1.5V15h1.5v1.5Zm-.445-9.234a3 3 0 0 1 .445 5.89V14h-1.5v-1.25c0-.57.452-.958.917-1.01A1.5 1.5 0 0 0 12 8.75a1.5 1.5 0 0 0-1.5 1.5H9a3 3 0 0 1 3.305-2.984Z"})}),D=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M4 20h8v-1.5H4V20zM18.9 3.5c-.6-.6-1.5-.6-2.1 0l-7.2 7.2c-.4-.1-.7 0-1.1.1-.5.2-1.5.7-1.9 2.2-.4 1.7-.8 2.2-1.1 2.7-.1.1-.2.3-.3.4l-.6 1.1H6c2 0 3.4-.4 4.7-1.4.8-.6 1.2-1.4 1.3-2.3 0-.3 0-.5-.1-.7L19 5.7c.5-.6.5-1.6-.1-2.2zM9.7 14.7c-.7.5-1.5.8-2.4 1 .2-.5.5-1.2.8-2.3.2-.6.4-1 .8-1.1.5-.1 1 .1 1.3.3.2.2.3.5.2.8 0 .3-.1.9-.7 1.3z"})});const R=Object.freeze({width:720,height:180,top:16,right:14,bottom:26,left:48}),O=Object.freeze({width:96,height:24,inset:3});function P(e){return Math.round(100*e)/100}function $(e){const s=/^(\d{4})-(\d{2})-(\d{2})$/.exec(String(e||""));if(!s)return null;const t=new Date(Number(s[1]),Number(s[2])-1,Number(s[3]));return Number.isNaN(t.getTime())?null:t}function I(e){const s=$(e);return s?new Intl.DateTimeFormat(void 0,{month:"short",day:"numeric"}).format(s):String(e||"")}function H(e){return(new Intl.NumberFormat).format(Math.round(e||0))}const G=R.height-R.bottom;function z(e){return!e||e.length<2?"":e.map((e,s)=>`${0===s?"M":"L"}${e.x} ${e.y}`).join(" ")}function F(e){const s=z(e);if(""===s)return"";const t=e[0];return`${s} L${e[e.length-1].x} ${G} L${t.x} ${G} Z`}function V(e){const s=(Array.isArray(e)?e:[]).map(e=>Number(e)||0);if(s.length<2)return"single";const t=Math.floor(s.length/2),a=e=>0===e.length?0:e.reduce((e,s)=>e+s,0)/e.length,l=a(s.slice(0,t)),n=a(s.slice(t));return 0===l?n>0?"rising":"steady":n>1.1*l?"rising":n<.9*l?"falling":"steady"}function U(e){switch(e){case"rising":return(0,l.__)("Rising","gloty");case"falling":return(0,l.__)("Falling","gloty");case"single":return(0,l.__)("One day","gloty");default:return(0,l.__)("Steady","gloty")}}function q({values:e=[],label:s=""}){const{mode:t,points:a,max:n}=function(e,s={}){const t=s.width??O.width,a=s.height??O.height,l=s.inset??O.inset,n=(Array.isArray(e)?e:[]).map(e=>Number(e)||0);if(0===n.length)return{mode:"empty",points:[],max:0};if(1===n.length)return{mode:"single",points:[{x:P(t/2),y:P(a/2)}],max:n[0]};const i=Math.max(...n),r=t-2*l,o=a-2*l,c=e=>P(l+e/(n.length-1)*r);return i<=0?{mode:"flat",points:n.map((e,s)=>({x:c(s),y:P(a-l)})),max:0}:{mode:"line",points:n.map((e,s)=>({x:c(s),y:P(l+o*(1-e/i))})),max:i}}(e),i=V(e),r=n<=0&&"empty"!==t?(0,l.sprintf)(/* translators: %s: series name. */ /* translators: %s: series name. */ 2 2 (0,l.__)("%s — no views in this window","gloty"),s):(0,l.sprintf)(/* translators: 1: series name, 2: trend direction, 3: busiest-day views. */ /* translators: 1: series name, 2: trend direction, 3: busiest-day views. */ 3 (0,l.__)("%1$s — %2$s, busiest day %3$d views","gloty"),s, V(i).toLocaleLowerCase(),n);return"empty"===t?(0,u.jsx)("span",{className:"wpshelf-sparkline__none",role:"img","aria-label":(0,l.sprintf)(/* translators: %s: series name. */ /* translators: %s: series name. */4 (0,l.__)("%s — nothing recorded","gloty"),s),children:"—"}):(0, u.jsx)("svg",{className:"wpshelf-sparkline",viewBox:`0 0 ${R.width} ${R.height}`,width:R.width,height:R.height,role:"img","aria-label":r,children:"single"===t?(0,u.jsx)("circle",{className:"wpshelf-sparkline__dot",cx:a[0].x,cy:a[0].y,r:2.5}):(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("polyline",{className:"wpshelf-sparkline__line",points:a.map(e=>`${e.x},${e.y}`).join(" "),vectorEffect:"non-scaling-stroke"}),(0,u.jsx)("circle",{className:"wpshelf-sparkline__dot",cx:a[a.length-1].x,cy:a[a.length-1].y,r:2})]})})}function q({trend:e,windowDays:s=0,firstRecorded:t="",languageNames:a={}}){const[i,r]=(0,n.useState)(null),o=(0,n.useId)(),c=(0,n.useId)(),{days:d,mode:h,peak:g}=e,_=function(e){const s=Number(e);if(!Number.isFinite(s)||s<=0)return 2;const t=Math.floor(Math.log10(s));for(const e of[t-1,t,t+1]){const t=Math.pow(10,e);for(const e of[1,1.5,2,2.5,3,4,5,6,8,10]){const a=e*t;if(a>=s&&Number.isInteger(a)&&a%2==0)return a}}return 2*Math.ceil(s/2)}(e.max),p=(0,n.useMemo)(()=>function(e,s){const t=D.width-D.left-D.right,a=D.height-D.top-D.bottom,l=Math.max(1,Number(s)||1),n=(e||[]).length;return(e||[]).map((e,s)=>({x:O(n<2?D.left+t/2:D.left+s/(n-1)*t),y:O(D.top+a*(1-e.total/l)),date:e.date,total:e.total}))}(d,_),[d,_]);if("empty"===h)return(0,u.jsx)("p",{className:"wpshelf-chart__blank wpshelf-muted",children:"never"===e.reason?(0,l.__)("No views recorded yet, so there is no trend to draw. Counting starts from the moment this version was installed — give it a day of traffic.","gloty"):(0,l.sprintf)(/* translators: 1: number of days in the window, 2: date counting began. */ /* translators: 1: number of days in the window, 2: date counting began. */5 (0,l.__)("No views in the last %1$d days, so there is no trend to draw. Counting began on %2$s, so there is history — just none inside this window. Try a longer range.","gloty"),s,t)});if("single"===h){const e=d[0];return(0, u.jsxs)("div",{className:"wpshelf-chart__single",children:[(0,u.jsx)("p",{className:"wpshelf-chart__single-value",children:I(e.total)}),(0,u.jsx)("p",{className:"wpshelf-chart__single-label wpshelf-muted",children:(0,l.sprintf)(/* translators: %s: a date. */ /* translators: %s: a date. */6 (0,l.__)("Views on %s — the first day on record. A trend needs a second day; this chart appears tomorrow.","gloty"), $(e.date))})]})}const m=(y=d.length)<2?[0]:y<14?[0,y-1]:[0,Math.floor((y-1)/2),y-1];var y;const f=[_,_/2,0],w=null===i?null:p[i],x=(0,l.sprintf)(/* translators: 1: number of days, 2: first date, 3: last date, 4: peak views, 5: date of the peak. */ /* translators: 1: number of days, 2: first date, 3: last date, 4: peak views, 5: date of the peak. */7 (0,l.__)("Daily views across %1$d days, %2$s to %3$s. Busiest day %4$s views on %5$s. Every day is listed in the table below.","gloty"),d.length, $(e.from),$(e.to),I(g?.total||0),$(g?.date||e.to)),v=g?p[g.index]:null,j=!!v&&v.y-D.top>18,b=v?v.x<D.left+32?"start":v.x>D.width-D.right-32?"end":"middle":"middle";return(0,u.jsxs)("div",{className:"wpshelf-chart",children:[(0,u.jsxs)("svg",{className:"wpshelf-chart__svg",viewBox:`0 0 ${D.width} ${D.height}`,preserveAspectRatio:"xMidYMid meet",role:"img",tabIndex:0,"aria-labelledby":`${o} ${c}`,onPointerMove:e=>{const s=e.currentTarget.getBoundingClientRect();if(s.width<=0)return;const t=(e.clientX-s.left)/s.width*D.width,a=D.width-D.left-D.right,l=(t-D.left)/a,n=Math.round(l*(d.length-1));r(Math.min(d.length-1,Math.max(0,n)))},onPointerLeave:()=>r(null),onBlur:()=>r(null),onKeyDown:e=>{const s={ArrowLeft:-1,ArrowRight:1,Home:-d.length,End:d.length};var t;"Escape"!==e.key?void 0!==s[e.key]&&(e.preventDefault(),t=s[e.key],r(e=>{const s=(null===e?d.length-1:e)+t;return Math.min(d.length-1,Math.max(0,s))})):r(null)},children:[(0,u.jsx)("title",{id:o,children:(0,l.__)("Views per day","gloty")}),(0,u.jsx)("desc",{id:c,children:x}),f.map(e=>{const s=D.top+(D.height-D.top-D.bottom)*(1-e/_);return(0,u.jsxs)("g",{children:[(0,u.jsx)("line",{className:"wpshelf-chart__grid",x1:D.left,x2:D.width-D.right,y1:s,y2:s,vectorEffect:"non-scaling-stroke"}),(0,u.jsx)("text",{className:"wpshelf-chart__tick",x:D.left-8,y:s+4,textAnchor:"end",children:I(e)})]},e)}),(0,u.jsx)("path",{className:"wpshelf-chart__area",d:z(p)}),(0,u.jsx)("path",{className:"wpshelf-chart__line",d:G(p),vectorEffect:"non-scaling-stroke"}),v&&(0,u.jsx)("text",{className:"wpshelf-chart__peak",x:v.x,y:j?v.y-10:v.y+18,textAnchor:b,children:I(g.total)}),m.map(e=>(0,u.jsx)("text",{className:"wpshelf-chart__tick",x:p[e].x,y:D.height-8,textAnchor:0===e?"start":e===d.length-1?"end":"middle",children:$(d[e].date)},e)),w&&(0,u.jsxs)("g",{children:[(0,u.jsx)("line",{className:"wpshelf-chart__crosshair",x1:w.x,x2:w.x,y1:D.top,y2:H,vectorEffect:"non-scaling-stroke"}),(0,u.jsx)("circle",{className:"wpshelf-chart__dot",cx:w.x,cy:w.y,r:4,vectorEffect:"non-scaling-stroke"})]})]}),w&&(0,u.jsxs)("div",{className:"wpshelf-chart__tip",role:"status",style:{left:w.x/D.width*100+"%"},children:[(0,u.jsx)("span",{className:"wpshelf-chart__tip-value",children:(0,l.sprintf)(/* translators: %s: a number of views. */ /* translators: %s: a number of views. */8 (0,l._x)("%s views","tooltip readout","gloty"), I(w.total))}),(0,u.jsx)("span",{className:"wpshelf-chart__tip-date",children:$(w.date)}),Object.entries(d[i].perLanguage).length>0&&(0,u.jsx)("ul",{className:"wpshelf-chart__tip-list",children:Object.entries(d[i].perLanguage).map(([e,s])=>(0,u.jsxs)("li",{children:[a[e]||e.toUpperCase()," ",(0,u.jsx)("b",{children:I(s)})]},e))})]}),(0,u.jsx)("p",{className:"wpshelf-chart__note wpshelf-muted",children:(0,l.__)("Hover or focus the chart and use the arrow keys to read a single day. The last day is still in progress.","gloty")})]})}const W=[7,30,90];function X(){const[e,s]=(0,n.useState)(30),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)(!0),[o,c]=(0,n.useState)(null),d=(0,n.useCallback)(async e=>{r(!0),c(null);try{const s=await m()({path:`/gloty/v1/analytics/traffic?days=${e}`});a(s)}catch(e){c(e?.message||(0,l.__)("Could not load traffic data.","gloty"))}finally{r(!1)}},[]);(0,n.useEffect)(()=>{d(e)},[d,e]);const h=t?.totals||[],g=t?.total_views||0,p=(0,n.useMemo)(()=>function({series:e=[],range:s=null,firstRecorded:t=""}={}){const a=Array.isArray(e)?e:[],l=s?.from||"",n=s?.to||"";if(!l||!n||0===a.length)return{mode:"empty",reason:t?"window":"never",days:[],max:0,peak:null,from:l,to:n};const i=function(e,s){const t=P(e),a=P(s);if(!t||!a||t>a)return[];const l=[],n=new Date(t.getTime());for(;n<=a&&l.length<400;){const e=String(n.getMonth()+1).padStart(2,"0"),s=String(n.getDate()).padStart(2,"0");l.push(`${n.getFullYear()}-${e}-${s}`),n.setDate(n.getDate()+1)}return l}(t&&t>l?t:l,n),r=i.length>0?i:[n],o=new Map;for(const e of a){const s=e?.per_language;e?.date&&s&&o.set(e.date,s)}let c=0,d=null;const h=r.map((e,s)=>{const t=o.get(e)||{};let a=0;for(const e of Object.values(t))a+=Number(e)||0;return a>c&&(c=a,d={index:s,date:e,total:a}),{date:e,total:a,perLanguage:t}});return{mode:h.length<2?"single":"line",reason:null,days:h,max:c,peak:d,from:r[0],to:r[r.length-1]}}({series:t?.series||[],range:t?.range||null,firstRecorded:t?.first_recorded||""}),[t]),f=(0,n.useMemo)(()=>Object.fromEntries((t?.totals||[]).map(e=>[e.code,e.name])),[t]);return(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-analytics-screen",children:[(0,u.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("How much of your traffic reads which language. Counted on this site, in your own database — no visitor data is collected and nothing is sent anywhere.","gloty")}),o&&(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:o}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsxs)(y.CardHeader,{size:"small",children:[(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Views by language","gloty")}),(0,u.jsx)("div",{className:"wpshelf-range-picker",role:"group","aria-label":(0,l.__)("Range","gloty"),children:W.map(t=>(0,u.jsx)(y.Button,{size:"compact",variant:t===e?"primary":"secondary","aria-pressed":t===e,onClick:()=>s(t),children:(0,l.sprintf)(/* translators: %d: number of days. */ /* translators: %d: number of days. */9 (0,l.__)("%d days","gloty"),t)},t))})]}),(0, u.jsxs)(y.CardBody,{children:[i&&!t&&(0,u.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,u.jsx)(y.Spinner,{}),(0,u.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading traffic…","gloty")})]}),t&&(0,u.jsxs)("div",{className:i?"wpshelf-analytics-body wpshelf-analytics-body--stale":"wpshelf-analytics-body","aria-busy":i,children:[h.length>0&&(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.sprintf)(/* translators: 1: total views, 2: start date, 3: end date. */ /* translators: 1: total views, 2: start date, 3: end date. */10 (0,l.__)("%1$s views between %2$s and %3$s.","gloty"), I(g),t?.range?.from||"",t?.range?.to||"")}),(0,u.jsx)(q,{trend:p,windowDays:t?.range?.days||0,firstRecorded:t?.first_recorded||"",languageNames:f}),h.length>0&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsxs)(_,{className:"wp-list-table widefat striped wpshelf-table",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Language","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Views","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Share","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Trend","gloty")})]})}),(0,u.jsx)("tbody",{children:h.map(e=>{const s=function(e,s){return(e||[]).map(e=>Number(e?.perLanguage?.[s])||0)}(p.days,e.code);return(0,u.jsxs)("tr",{children:[(0,u.jsxs)("td",{children:[e.name," ",(0,u.jsx)("span",{className:"wpshelf-muted",children:e.code.toUpperCase()}),!e.is_translated&&(0,u.jsxs)("span",{className:"wpshelf-muted",children:[" — ",(0,l.__)("source","gloty")]})]}),(0,u.jsx)("td",{children:I(e.views)}),(0,u.jsxs)("td",{children:[e.share,"%"]}),(0,u.jsx)("td",{"data-search":V(F(s)),children:(0,u.jsx)(U,{values:s,label:e.name})})]},e.code)})})]}),(0,u.jsx)("p",{className:"wpshelf-chart__note wpshelf-muted",children:(0,l.__)("Each row’s trend is scaled to its own busiest day, so the shapes are comparable but their heights are not — read magnitude from the Views column.","gloty")})]})]})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("What this counts","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsxs)("ul",{className:"wpshelf-muted",style:{marginTop:0},children:[(0,u.jsx)("li",{children:(0,l.__)("Views, not visitors. Telling one person apart from another needs a cookie or a fingerprint, and this feature exists precisely so that neither is set.","gloty")}),(0,u.jsx)("li",{children:"browser"===t?.counter?(0,l.__)("Counted from the browser, so pages your cache served are included. A visitor with JavaScript disabled is not counted, and neither is most automated traffic.","gloty"):(0,l.__)("Requests that reached WordPress. A full-page cache (WP Rocket, LiteSpeed, Cloudflare) serves pages without starting PHP, so those views cannot be counted here and your real totals are higher. Settings → Analytics can move counting into the browser.","gloty")}),(0,u.jsx)("li",{children:(0,l.__)("Obvious crawlers are left out by their user agent, which is read and discarded. No IP address, page URL, user agent or account is ever stored.","gloty")}),t?.first_recorded&&(0,u.jsx)("li",{children:(0,l.sprintf)(/* translators: %s: date counting began. */ /* translators: %s: date counting began. */11 (0,l.__)("Counting began on %s.","gloty"),t.first_recorded)})]})})]})]})}const Y={not_translated:{label:(0,l.__)("Not translated","gloty"),description:(0,l.__)("No translation stored yet. Ready to queue.","gloty"),next:(0,l.__)("Queue translation","gloty"),tone:"muted"},pending:{label:(0,l.__)("Pending","gloty"),description:(0,l.__)("Captured and queued, waiting for dispatch.","gloty"),next:(0,l.__)("Wait or inspect the queue","gloty"),tone:"warn"},processing:{label:(0,l.__)("Processing","gloty"),description:(0,l.__)("In progress with the translation provider.","gloty"),next:(0,l.__)("Wait for the provider","gloty"),tone:"warn"},synced:{label:(0,l.__)("Synced","gloty"),description:(0,l.__)("Machine-translated and stored in local cache.","gloty"),next:null,tone:"success"},stale:{label:(0,l.__)("Out of date","gloty"),description:(0,l.__)("Source changed since the last translation. Needs re-sync.","gloty"),next:(0,l.__)("Re-sync","gloty"),tone:"warn"},failed:{label:(0,l.__)("Failed","gloty"),description:(0,l.__)("Could not be completed. Inspect error details.","gloty"),next:(0,l.__)("Retry or fix config","gloty"),tone:"error"},manually_edited:{label:(0,l.__)("Manually edited","gloty"),description:(0,l.__)("Human-reviewed. Machine sync will not overwrite it.","gloty"),next:(0,l.__)("Protected from overwrite","gloty"),tone:"info"},auto:{label:(0,l.__)("Synced","gloty"),description:(0,l.__)("Machine-translated and stored in local cache.","gloty"),next:null,tone:"success",alias:"synced"},manual:{label:(0,l.__)("Manually edited","gloty"),description:(0,l.__)("Human-reviewed. Machine sync will not overwrite it.","gloty"),next:(0,l.__)("Protected from overwrite","gloty"),tone:"info",alias:"manually_edited"},queued:{label:(0,l.__)("Queued","gloty"),description:(0,l.__)("Job created and waiting for execution.","gloty"),next:(0,l.__)("Wait for dispatch","gloty"),tone:"warn"},completed:{label:(0,l.__)("Completed","gloty"),description:(0,l.__)("Job finished and results persisted.","gloty"),next:null,tone:"success"},complete:{label:(0,l.__)("Completed","gloty"),description:(0,l.__)("Scan finished for all currently discovered entities.","gloty"),next:null,tone:"success",alias:"completed"},cancelled:{label:(0,l.__)("Cancelled","gloty"),description:(0,l.__)("Stopped by an operator action.","gloty"),next:null,tone:"muted"},running:{label:(0,l.__)("Running","gloty"),description:(0,l.__)("Background scan is in progress.","gloty"),next:null,tone:"info"},idle:{label:(0,l.__)("Idle","gloty"),description:(0,l.__)("No active processing right now.","gloty"),next:null,tone:"muted"},paused:{label:(0,l.__)("Paused","gloty"),description:(0,l.__)("Scan paused by an operator and ready to resume.","gloty"),next:(0,l.__)("Resume scan","gloty"),tone:"muted"}},Z={success:"wpshelf-chip wpshelf-chip--success",warn:"wpshelf-chip wpshelf-chip--warn",error:"wpshelf-chip wpshelf-chip--error",info:"wpshelf-chip wpshelf-chip--info",muted:"wpshelf-chip wpshelf-chip--muted"};function J(e){const s=Y[e]?.tone;return Z[s]||"wpshelf-chip"}function K({status:e}){const s=Y[e],t=s?.label||e,a=s?.description||"",l=s?.next?`${t}: ${s.next}`:a||t;return(0,n.createElement)("span",{className:J(e),title:a||t,"aria-label":l,"data-status":e},t)}function Q({statuses:e}){return(0,n.createElement)("div",{className:"wpshelf-status-glossary"},e.map(e=>{const s=function(e){return Y[e]||null}(e);return s?(0,n.createElement)("div",{key:e,className:"wpshelf-status-glossary__item"},(0,n.createElement)(K,{status:e}),(0,n.createElement)("p",{className:"wpshelf-status-glossary__text"},s.description||(s.next?`${(0,l.__)("Next","gloty")}: ${s.next}.`:(0,l.__)("No action needed.","gloty")))):null}))}function ee({title:e,subtitle:s,children:t,actions:a}){return(0,u.jsxs)("div",{className:"wpshelf-section-card",children:[(0,u.jsxs)("div",{className:"wpshelf-section-card__header",children:[(0,u.jsxs)("div",{children:[(0,u.jsx)("h2",{className:"wpshelf-section-card__title",children:e}),s&&(0,u.jsx)("p",{className:"wpshelf-section-card__subtitle",children:s})]}),a&&(0,u.jsx)("div",{className:"wpshelf-section-card__actions",children:a})]}),t]})}function se(e){const s=Number(e);return Number.isFinite(s)?s.toLocaleString():String(e??"")}function te(e){if(!e)return"—";let s=String(e).trim();s.includes("T")||(s=s.replace(" ","T")),/(?:[zZ]|[+-]\d\d:?\d\d)$/.test(s)||(s+="Z");const t=new Date(s).getTime();if(Number.isNaN(t))return"—";const a=(Date.now()-t)/1e3;return a<60?(0,l.__)("just now","gloty"):a<3600?Math.floor(a/60)+(0,l.__)("m ago","gloty"):a<86400?Math.floor(a/3600)+(0,l.__)("h ago","gloty"):Math.floor(a/86400)+(0,l.__)("d ago","gloty")}function ae(e){const s=String(e||"");if(""===s)return"";let t=s;try{t="undefined"!=typeof DOMParser?(new DOMParser).parseFromString(s,"text/html").body.textContent||"":s.replace(/<[^>]*>/g," ")}catch(e){t=s.replace(/<[^>]*>/g," ")}return t.replace(/\s+/g," ").trim()}function le(e){return ae(e)||String(e||"").trim()}function ne({icon:e,title:s,hint:t}){return(0,u.jsxs)("div",{className:"wpshelf-empty",children:[e&&(0,u.jsx)("div",{className:"wpshelf-empty__icon",children:e}),(0,u.jsx)("p",{className:"wpshelf-empty__title",children:s}),t&&(0,u.jsx)("p",{className:"wpshelf-empty__hint",children:t})]})}function ie({title:e,message:s,confirmLabel:t,isDestructive:a=!0,busy:n=!1,onConfirm:i,onCancel:r}){return(0,u.jsxs)(y.Modal,{title:e,onRequestClose:r,className:"wpshelf-confirm-modal",size:"small",children:[(0,u.jsx)("p",{className:"wpshelf-confirm-modal__message",children:s}),(0,u.jsxs)("div",{className:"wpshelf-confirm-modal__actions",children:[(0,u.jsx)(y.Button,{variant:"tertiary",onClick:r,disabled:n,children:(0,l.__)("Cancel","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",isDestructive:a,onClick:i,isBusy:n,disabled:n,children:t||(0,l.__)("Delete","gloty")})]})]})}function re({label:e}){return(0,u.jsxs)("span",{className:"wpshelf-inline-busy",role:"status","aria-live":"polite",children:[(0,u.jsx)(y.Spinner,{}),(0,u.jsx)("span",{className:"wpshelf-inline-busy__label",children:e})]})}function oe({text:e}){return(0,u.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,u.jsx)(y.Spinner,{}),e&&(0,u.jsx)("span",{className:"wpshelf-skeleton__text",children:e})]})}function ce({cols:e=4,rows:s=5,headers:t}){const a=t?t.length:e;return(0,u.jsxs)("table",{className:"wp-list-table widefat striped wpshelf-table-skeleton",children:[(0,u.jsx)("thead",{children:(0,u.jsx)("tr",{children:Array.from({length:a},(e,s)=>(0,u.jsx)("th",{scope:"col",children:t?.[s]?t[s]:(0,u.jsx)("span",{className:"wpshelf-shimmer wpshelf-shimmer--header"})},s))})}),(0,u.jsx)("tbody",{children:Array.from({length:s},(e,s)=>(0,u.jsx)("tr",{children:Array.from({length:a},(e,t)=>(0,u.jsx)("td",{children:(0,u.jsx)("span",{className:"wpshelf-shimmer",style:{width:55+(7*s+13*t)%35+"%"}})},t))},s))})]})}function de(e){return e>=90?"danger":e>=75?"warn":""}const he={success:"var(--wpshelf-success)",warn:"var(--wpshelf-warn)",danger:"var(--wpshelf-danger)"},ge={success:"var(--wpshelf-success-dark)",warn:"var(--wpshelf-warn-dark)",danger:"var(--wpshelf-danger)"};function ue({value:e,max:s,label:t,tone:a,scale:l="usage"}){const n=s>0?Math.min(e/s*100,100):0,i=t||`${Math.round(n)}%`,r=a||("completion"===l?function(e){return e>=67?"success":e>=34?"warn":"danger"}(n):de(n)),o=he[r]||"",c=ge[r]||"";return(0,u.jsxs)("div",{className:"wpshelf-progress",children:[(0,u.jsx)("div",{className:"wpshelf-progress__bar",role:"progressbar","aria-valuenow":Math.round(n),"aria-valuemin":0,"aria-valuemax":100,"aria-valuetext":i,children:(0,u.jsx)("div",{className:"wpshelf-progress__fill",style:{width:`${n}%`,...o?{background:o}:{}}})}),(0,u.jsx)("span",{className:"wpshelf-progress__label","aria-hidden":"true",style:c?{color:c}:void 0,children:i})]})}function _e({steps:e,current:s}){return(0,u.jsx)("ol",{className:"wpshelf-stepper","aria-label":(0,l.__)("Setup progress","gloty"),children:e.map((t,a)=>{const l=a===s;let n="wpshelf-stepper__step";return a<s&&(n+=" wpshelf-stepper__step--done"),l&&(n+=" wpshelf-stepper__step--active"),(0,u.jsxs)("li",{className:n,"aria-current":l?"step":void 0,children:[a<e.length-1&&(0,u.jsx)("span",{className:"wpshelf-stepper__connector","aria-hidden":"true"}),(0,u.jsx)("span",{className:"wpshelf-stepper__label",children:t.label})]},t.key)})})}function pe({items:e}){return(0,u.jsx)("div",{className:"wpshelf-milestones",role:"list",children:e.map(e=>{const s=e.done?(0,l.__)("Complete","gloty"):(0,l.__)("Pending","gloty");return(0,u.jsxs)("div",{className:"wpshelf-milestone "+(e.done?"wpshelf-milestone--done":"wpshelf-milestone--todo"),role:"listitem","aria-label":`${e.title}: ${s}`,children:[(0,u.jsx)("div",{className:"wpshelf-milestone__title",children:e.title}),(0,u.jsx)("div",{className:"wpshelf-milestone__state",children:s})]},e.key)})})}function me({oldText:e,newText:s}){const t=(e||"").split(/(\s+)/),a=(s||"").split(/(\s+)/),l=t.length,n=a.length,i=Array.from({length:l+1},()=>new Array(n+1).fill(0));for(let e=1;e<=l;e++)for(let s=1;s<=n;s++)i[e][s]=t[e-1]===a[s-1]?i[e-1][s-1]+1:Math.max(i[e-1][s],i[e][s-1]);const r=[];let o=l,c=n;for(;o>0||c>0;)o>0&&c>0&&t[o-1]===a[c-1]?(r.unshift({type:"same",text:t[o-1]}),o--,c--):c>0&&(0===o||i[o][c-1]>=i[o-1][c])?(r.unshift({type:"add",text:a[c-1]}),c--):(r.unshift({type:"del",text:t[o-1]}),o--);return(0,u.jsx)("div",{className:"wpshelf-diff__content",children:r.map((e,s)=>"del"===e.type?(0,u.jsx)("del",{className:"wpshelf-diff__del",children:e.text},s):"add"===e.type?(0,u.jsx)("ins",{className:"wpshelf-diff__ins",children:e.text},s):(0,u.jsx)("span",{children:e.text},s))})}async function ye(){try{const e=await m()({path:"/gloty/v1/license/plans"});return Array.isArray(e?.plans)?e.plans:[]}catch{return[]}}function fe(e,s){const t=e?.plan_slug||"",a=e?.characters_limit??0;return(s||[]).filter(e=>e.slug!==t).filter(e=>!e.renews||(e.quota?.limit??0)>a).sort((e,s)=>e.price-s.price)}function we(e){const s=`$${(e.price/100).toLocaleString(void 0,{maximumFractionDigits:2})}`;return e.renews?"year"===e.interval?(0,l.sprintf)(/* translators: %s: price, e.g. $290 */ /* translators: %s: price, e.g. $290 */3 (0,l.__)("%1$s — %2$s, busiest day %3$d views","gloty"),s,U(i).toLocaleLowerCase(),n);return"empty"===t?(0,_.jsx)("span",{className:"wpshelf-sparkline__none",role:"img","aria-label":(0,l.sprintf)(/* translators: %s: series name. */ /* translators: %s: series name. */ 4 (0,l.__)("%s — nothing recorded","gloty"),s),children:"—"}):(0,_.jsx)("svg",{className:"wpshelf-sparkline",viewBox:`0 0 ${O.width} ${O.height}`,width:O.width,height:O.height,role:"img","aria-label":r,children:"single"===t?(0,_.jsx)("circle",{className:"wpshelf-sparkline__dot",cx:a[0].x,cy:a[0].y,r:2.5}):(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("polyline",{className:"wpshelf-sparkline__line",points:a.map(e=>`${e.x},${e.y}`).join(" "),vectorEffect:"non-scaling-stroke"}),(0,_.jsx)("circle",{className:"wpshelf-sparkline__dot",cx:a[a.length-1].x,cy:a[a.length-1].y,r:2})]})})}function W({trend:e,windowDays:s=0,firstRecorded:t="",languageNames:a={}}){const[i,r]=(0,n.useState)(null),o=(0,n.useId)(),c=(0,n.useId)(),{days:d,mode:h,peak:g}=e,u=function(e){const s=Number(e);if(!Number.isFinite(s)||s<=0)return 2;const t=Math.floor(Math.log10(s));for(const e of[t-1,t,t+1]){const t=Math.pow(10,e);for(const e of[1,1.5,2,2.5,3,4,5,6,8,10]){const a=e*t;if(a>=s&&Number.isInteger(a)&&a%2==0)return a}}return 2*Math.ceil(s/2)}(e.max),p=(0,n.useMemo)(()=>function(e,s){const t=R.width-R.left-R.right,a=R.height-R.top-R.bottom,l=Math.max(1,Number(s)||1),n=(e||[]).length;return(e||[]).map((e,s)=>({x:P(n<2?R.left+t/2:R.left+s/(n-1)*t),y:P(R.top+a*(1-e.total/l)),date:e.date,total:e.total}))}(d,u),[d,u]);if("empty"===h)return(0,_.jsx)("p",{className:"wpshelf-chart__blank wpshelf-muted",children:"never"===e.reason?(0,l.__)("No views recorded yet, so there is no trend to draw. Counting starts from the moment this version was installed — give it a day of traffic.","gloty"):(0,l.sprintf)(/* translators: 1: number of days in the window, 2: date counting began. */ /* translators: 1: number of days in the window, 2: date counting began. */ 5 (0,l.__)("No views in the last %1$d days, so there is no trend to draw. Counting began on %2$s, so there is history — just none inside this window. Try a longer range.","gloty"),s,t)});if("single"===h){const e=d[0];return(0,_.jsxs)("div",{className:"wpshelf-chart__single",children:[(0,_.jsx)("p",{className:"wpshelf-chart__single-value",children:H(e.total)}),(0,_.jsx)("p",{className:"wpshelf-chart__single-label wpshelf-muted",children:(0,l.sprintf)(/* translators: %s: a date. */ /* translators: %s: a date. */ 6 (0,l.__)("Views on %s — the first day on record. A trend needs a second day; this chart appears tomorrow.","gloty"),I(e.date))})]})}const m=(y=d.length)<2?[0]:y<14?[0,y-1]:[0,Math.floor((y-1)/2),y-1];var y;const f=[u,u/2,0],w=null===i?null:p[i],x=(0,l.sprintf)(/* translators: 1: number of days, 2: first date, 3: last date, 4: peak views, 5: date of the peak. */ /* translators: 1: number of days, 2: first date, 3: last date, 4: peak views, 5: date of the peak. */ 7 (0,l.__)("Daily views across %1$d days, %2$s to %3$s. Busiest day %4$s views on %5$s. Every day is listed in the table below.","gloty"),d.length,I(e.from),I(e.to),H(g?.total||0),I(g?.date||e.to)),v=g?p[g.index]:null,j=!!v&&v.y-R.top>18,b=v?v.x<R.left+32?"start":v.x>R.width-R.right-32?"end":"middle":"middle";return(0,_.jsxs)("div",{className:"wpshelf-chart",children:[(0,_.jsxs)("svg",{className:"wpshelf-chart__svg",viewBox:`0 0 ${R.width} ${R.height}`,preserveAspectRatio:"xMidYMid meet",role:"img",tabIndex:0,"aria-labelledby":`${o} ${c}`,onPointerMove:e=>{const s=e.currentTarget.getBoundingClientRect();if(s.width<=0)return;const t=(e.clientX-s.left)/s.width*R.width,a=R.width-R.left-R.right,l=(t-R.left)/a,n=Math.round(l*(d.length-1));r(Math.min(d.length-1,Math.max(0,n)))},onPointerLeave:()=>r(null),onBlur:()=>r(null),onKeyDown:e=>{const s={ArrowLeft:-1,ArrowRight:1,Home:-d.length,End:d.length};var t;"Escape"!==e.key?void 0!==s[e.key]&&(e.preventDefault(),t=s[e.key],r(e=>{const s=(null===e?d.length-1:e)+t;return Math.min(d.length-1,Math.max(0,s))})):r(null)},children:[(0,_.jsx)("title",{id:o,children:(0,l.__)("Views per day","gloty")}),(0,_.jsx)("desc",{id:c,children:x}),f.map(e=>{const s=R.top+(R.height-R.top-R.bottom)*(1-e/u);return(0,_.jsxs)("g",{children:[(0,_.jsx)("line",{className:"wpshelf-chart__grid",x1:R.left,x2:R.width-R.right,y1:s,y2:s,vectorEffect:"non-scaling-stroke"}),(0,_.jsx)("text",{className:"wpshelf-chart__tick",x:R.left-8,y:s+4,textAnchor:"end",children:H(e)})]},e)}),(0,_.jsx)("path",{className:"wpshelf-chart__area",d:F(p)}),(0,_.jsx)("path",{className:"wpshelf-chart__line",d:z(p),vectorEffect:"non-scaling-stroke"}),v&&(0,_.jsx)("text",{className:"wpshelf-chart__peak",x:v.x,y:j?v.y-10:v.y+18,textAnchor:b,children:H(g.total)}),m.map(e=>(0,_.jsx)("text",{className:"wpshelf-chart__tick",x:p[e].x,y:R.height-8,textAnchor:0===e?"start":e===d.length-1?"end":"middle",children:I(d[e].date)},e)),w&&(0,_.jsxs)("g",{children:[(0,_.jsx)("line",{className:"wpshelf-chart__crosshair",x1:w.x,x2:w.x,y1:R.top,y2:G,vectorEffect:"non-scaling-stroke"}),(0,_.jsx)("circle",{className:"wpshelf-chart__dot",cx:w.x,cy:w.y,r:4,vectorEffect:"non-scaling-stroke"})]})]}),w&&(0,_.jsxs)("div",{className:"wpshelf-chart__tip",role:"status",style:{left:w.x/R.width*100+"%"},children:[(0,_.jsx)("span",{className:"wpshelf-chart__tip-value",children:(0,l.sprintf)(/* translators: %s: a number of views. */ /* translators: %s: a number of views. */ 8 (0,l._x)("%s views","tooltip readout","gloty"),H(w.total))}),(0,_.jsx)("span",{className:"wpshelf-chart__tip-date",children:I(w.date)}),Object.entries(d[i].perLanguage).length>0&&(0,_.jsx)("ul",{className:"wpshelf-chart__tip-list",children:Object.entries(d[i].perLanguage).map(([e,s])=>(0,_.jsxs)("li",{children:[a[e]||e.toUpperCase()," ",(0,_.jsx)("b",{children:H(s)})]},e))})]}),(0,_.jsx)("p",{className:"wpshelf-chart__note wpshelf-muted",children:(0,l.__)("Hover or focus the chart and use the arrow keys to read a single day. The last day is still in progress.","gloty")})]})}const X=[7,30,90];function Y(){const[e,s]=(0,n.useState)(30),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)(!0),[o,c]=(0,n.useState)(null),d=(0,n.useCallback)(async e=>{r(!0),c(null);try{const s=await y()({path:`/gloty/v1/analytics/traffic?days=${e}`});a(s)}catch(e){c(e?.message||(0,l.__)("Could not load traffic data.","gloty"))}finally{r(!1)}},[]);(0,n.useEffect)(()=>{d(e)},[d,e]);const h=t?.totals||[],g=t?.total_views||0,u=(0,n.useMemo)(()=>function({series:e=[],range:s=null,firstRecorded:t=""}={}){const a=Array.isArray(e)?e:[],l=s?.from||"",n=s?.to||"";if(!l||!n||0===a.length)return{mode:"empty",reason:t?"window":"never",days:[],max:0,peak:null,from:l,to:n};const i=function(e,s){const t=$(e),a=$(s);if(!t||!a||t>a)return[];const l=[],n=new Date(t.getTime());for(;n<=a&&l.length<400;){const e=String(n.getMonth()+1).padStart(2,"0"),s=String(n.getDate()).padStart(2,"0");l.push(`${n.getFullYear()}-${e}-${s}`),n.setDate(n.getDate()+1)}return l}(t&&t>l?t:l,n),r=i.length>0?i:[n],o=new Map;for(const e of a){const s=e?.per_language;e?.date&&s&&o.set(e.date,s)}let c=0,d=null;const h=r.map((e,s)=>{const t=o.get(e)||{};let a=0;for(const e of Object.values(t))a+=Number(e)||0;return a>c&&(c=a,d={index:s,date:e,total:a}),{date:e,total:a,perLanguage:t}});return{mode:h.length<2?"single":"line",reason:null,days:h,max:c,peak:d,from:r[0],to:r[r.length-1]}}({series:t?.series||[],range:t?.range||null,firstRecorded:t?.first_recorded||""}),[t]),m=(0,n.useMemo)(()=>Object.fromEntries((t?.totals||[]).map(e=>[e.code,e.name])),[t]);return(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-analytics-screen",children:[(0,_.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("How much of your traffic reads which language. Counted on this site, in your own database — no visitor data is collected and nothing is sent anywhere.","gloty")}),o&&(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:o}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsxs)(f.CardHeader,{size:"small",children:[(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Views by language","gloty")}),(0,_.jsx)("div",{className:"wpshelf-range-picker",role:"group","aria-label":(0,l.__)("Range","gloty"),children:X.map(t=>(0,_.jsx)(f.Button,{size:"compact",variant:t===e?"primary":"secondary","aria-pressed":t===e,onClick:()=>s(t),children:(0,l.sprintf)(/* translators: %d: number of days. */ /* translators: %d: number of days. */ 9 (0,l.__)("%d days","gloty"),t)},t))})]}),(0,_.jsxs)(f.CardBody,{children:[i&&!t&&(0,_.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,_.jsx)(f.Spinner,{}),(0,_.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading traffic…","gloty")})]}),t&&(0,_.jsxs)("div",{className:i?"wpshelf-analytics-body wpshelf-analytics-body--stale":"wpshelf-analytics-body","aria-busy":i,children:[h.length>0&&(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.sprintf)(/* translators: 1: total views, 2: start date, 3: end date. */ /* translators: 1: total views, 2: start date, 3: end date. */ 10 (0,l.__)("%1$s views between %2$s and %3$s.","gloty"),H(g),t?.range?.from||"",t?.range?.to||"")}),(0,_.jsx)(W,{trend:u,windowDays:t?.range?.days||0,firstRecorded:t?.first_recorded||"",languageNames:m}),h.length>0&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsxs)(p,{className:"wp-list-table widefat striped wpshelf-table",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Language","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Views","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Share","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Trend","gloty")})]})}),(0,_.jsx)("tbody",{children:h.map(e=>{const s=function(e,s){return(e||[]).map(e=>Number(e?.perLanguage?.[s])||0)}(u.days,e.code);return(0,_.jsxs)("tr",{children:[(0,_.jsxs)("td",{children:[e.name," ",(0,_.jsx)("span",{className:"wpshelf-muted",children:e.code.toUpperCase()}),!e.is_translated&&(0,_.jsxs)("span",{className:"wpshelf-muted",children:[" — ",(0,l.__)("source","gloty")]})]}),(0,_.jsx)("td",{children:H(e.views)}),(0,_.jsxs)("td",{children:[e.share,"%"]}),(0,_.jsx)("td",{"data-search":U(V(s)),children:(0,_.jsx)(q,{values:s,label:e.name})})]},e.code)})})]}),(0,_.jsx)("p",{className:"wpshelf-chart__note wpshelf-muted",children:(0,l.__)("Each row’s trend is scaled to its own busiest day, so the shapes are comparable but their heights are not — read magnitude from the Views column.","gloty")})]})]})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("What this counts","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsxs)("ul",{className:"wpshelf-muted",style:{marginTop:0},children:[(0,_.jsx)("li",{children:(0,l.__)("Views, not visitors. Telling one person apart from another needs a cookie or a fingerprint, and this feature exists precisely so that neither is set.","gloty")}),(0,_.jsx)("li",{children:"browser"===t?.counter?(0,l.__)("Counted from the browser, so pages your cache served are included. A visitor with JavaScript disabled is not counted, and neither is most automated traffic.","gloty"):(0,l.__)("Requests that reached WordPress. A full-page cache (WP Rocket, LiteSpeed, Cloudflare) serves pages without starting PHP, so those views cannot be counted here and your real totals are higher. Settings → Analytics can move counting into the browser.","gloty")}),(0,_.jsx)("li",{children:(0,l.__)("Obvious crawlers are left out by their user agent, which is read and discarded. No IP address, page URL, user agent or account is ever stored.","gloty")}),t?.first_recorded&&(0,_.jsx)("li",{children:(0,l.sprintf)(/* translators: %s: date counting began. */ /* translators: %s: date counting began. */ 11 (0,l.__)("Counting began on %s.","gloty"),t.first_recorded)})]})})]})]})}const Z={not_translated:{label:(0,l.__)("Not translated","gloty"),description:(0,l.__)("No translation stored yet. Ready to queue.","gloty"),next:(0,l.__)("Queue translation","gloty"),tone:"muted"},pending:{label:(0,l.__)("Pending","gloty"),description:(0,l.__)("Captured and queued, waiting for dispatch.","gloty"),next:(0,l.__)("Wait or inspect the queue","gloty"),tone:"warn"},processing:{label:(0,l.__)("Processing","gloty"),description:(0,l.__)("In progress with the translation provider.","gloty"),next:(0,l.__)("Wait for the provider","gloty"),tone:"warn"},synced:{label:(0,l.__)("Synced","gloty"),description:(0,l.__)("Machine-translated and stored in local cache.","gloty"),next:null,tone:"success"},stale:{label:(0,l.__)("Out of date","gloty"),description:(0,l.__)("Source changed since the last translation. Needs re-sync.","gloty"),next:(0,l.__)("Re-sync","gloty"),tone:"warn"},failed:{label:(0,l.__)("Failed","gloty"),description:(0,l.__)("Could not be completed. Inspect error details.","gloty"),next:(0,l.__)("Retry or fix config","gloty"),tone:"error"},manually_edited:{label:(0,l.__)("Manually edited","gloty"),description:(0,l.__)("Human-reviewed. Machine sync will not overwrite it.","gloty"),next:(0,l.__)("Protected from overwrite","gloty"),tone:"info"},auto:{label:(0,l.__)("Synced","gloty"),description:(0,l.__)("Machine-translated and stored in local cache.","gloty"),next:null,tone:"success",alias:"synced"},manual:{label:(0,l.__)("Manually edited","gloty"),description:(0,l.__)("Human-reviewed. Machine sync will not overwrite it.","gloty"),next:(0,l.__)("Protected from overwrite","gloty"),tone:"info",alias:"manually_edited"},queued:{label:(0,l.__)("Queued","gloty"),description:(0,l.__)("Job created and waiting for execution.","gloty"),next:(0,l.__)("Wait for dispatch","gloty"),tone:"warn"},completed:{label:(0,l.__)("Completed","gloty"),description:(0,l.__)("Job finished and results persisted.","gloty"),next:null,tone:"success"},complete:{label:(0,l.__)("Completed","gloty"),description:(0,l.__)("Scan finished for all currently discovered entities.","gloty"),next:null,tone:"success",alias:"completed"},cancelled:{label:(0,l.__)("Cancelled","gloty"),description:(0,l.__)("Stopped by an operator action.","gloty"),next:null,tone:"muted"},running:{label:(0,l.__)("Running","gloty"),description:(0,l.__)("Background scan is in progress.","gloty"),next:null,tone:"info"},idle:{label:(0,l.__)("Idle","gloty"),description:(0,l.__)("No active processing right now.","gloty"),next:null,tone:"muted"},paused:{label:(0,l.__)("Paused","gloty"),description:(0,l.__)("Scan paused by an operator and ready to resume.","gloty"),next:(0,l.__)("Resume scan","gloty"),tone:"muted"}},J={success:"wpshelf-chip wpshelf-chip--success",warn:"wpshelf-chip wpshelf-chip--warn",error:"wpshelf-chip wpshelf-chip--error",info:"wpshelf-chip wpshelf-chip--info",muted:"wpshelf-chip wpshelf-chip--muted"};function K(e){const s=Z[e]?.tone;return J[s]||"wpshelf-chip"}function Q({status:e}){const s=Z[e],t=s?.label||e,a=s?.description||"",l=s?.next?`${t}: ${s.next}`:a||t;return(0,n.createElement)("span",{className:K(e),title:a||t,"aria-label":l,"data-status":e},t)}function ee({statuses:e}){return(0,n.createElement)("div",{className:"wpshelf-status-glossary"},e.map(e=>{const s=function(e){return Z[e]||null}(e);return s?(0,n.createElement)("div",{key:e,className:"wpshelf-status-glossary__item"},(0,n.createElement)(Q,{status:e}),(0,n.createElement)("p",{className:"wpshelf-status-glossary__text"},s.description||(s.next?`${(0,l.__)("Next","gloty")}: ${s.next}.`:(0,l.__)("No action needed.","gloty")))):null}))}function se({title:e,subtitle:s,children:t,actions:a}){return(0,_.jsxs)("div",{className:"wpshelf-section-card",children:[(0,_.jsxs)("div",{className:"wpshelf-section-card__header",children:[(0,_.jsxs)("div",{children:[(0,_.jsx)("h2",{className:"wpshelf-section-card__title",children:e}),s&&(0,_.jsx)("p",{className:"wpshelf-section-card__subtitle",children:s})]}),a&&(0,_.jsx)("div",{className:"wpshelf-section-card__actions",children:a})]}),t]})}function te(e){const s=Number(e);return Number.isFinite(s)?s.toLocaleString():String(e??"")}function ae(e){if(!e)return"—";let s=String(e).trim();s.includes("T")||(s=s.replace(" ","T")),/(?:[zZ]|[+-]\d\d:?\d\d)$/.test(s)||(s+="Z");const t=new Date(s).getTime();if(Number.isNaN(t))return"—";const a=(Date.now()-t)/1e3;return a<60?(0,l.__)("just now","gloty"):a<3600?Math.floor(a/60)+(0,l.__)("m ago","gloty"):a<86400?Math.floor(a/3600)+(0,l.__)("h ago","gloty"):Math.floor(a/86400)+(0,l.__)("d ago","gloty")}function le(e){const s=String(e||"");if(""===s)return"";let t=s;try{t="undefined"!=typeof DOMParser?(new DOMParser).parseFromString(s,"text/html").body.textContent||"":s.replace(/<[^>]*>/g," ")}catch(e){t=s.replace(/<[^>]*>/g," ")}return t.replace(/\s+/g," ").trim()}function ne(e){return le(e)||String(e||"").trim()}function ie({icon:e,title:s,hint:t}){return(0,_.jsxs)("div",{className:"wpshelf-empty",children:[e&&(0,_.jsx)("div",{className:"wpshelf-empty__icon",children:e}),(0,_.jsx)("p",{className:"wpshelf-empty__title",children:s}),t&&(0,_.jsx)("p",{className:"wpshelf-empty__hint",children:t})]})}function re({title:e,message:s,confirmLabel:t,isDestructive:a=!0,busy:n=!1,onConfirm:i,onCancel:r}){return(0,_.jsxs)(f.Modal,{title:e,onRequestClose:r,className:"wpshelf-confirm-modal",size:"small",children:[(0,_.jsx)("p",{className:"wpshelf-confirm-modal__message",children:s}),(0,_.jsxs)("div",{className:"wpshelf-confirm-modal__actions",children:[(0,_.jsx)(f.Button,{variant:"tertiary",onClick:r,disabled:n,children:(0,l.__)("Cancel","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",isDestructive:a,onClick:i,isBusy:n,disabled:n,children:t||(0,l.__)("Delete","gloty")})]})]})}function oe({label:e}){return(0,_.jsxs)("span",{className:"wpshelf-inline-busy",role:"status","aria-live":"polite",children:[(0,_.jsx)(f.Spinner,{}),(0,_.jsx)("span",{className:"wpshelf-inline-busy__label",children:e})]})}function ce({text:e}){return(0,_.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,_.jsx)(f.Spinner,{}),e&&(0,_.jsx)("span",{className:"wpshelf-skeleton__text",children:e})]})}function de({cols:e=4,rows:s=5,headers:t}){const a=t?t.length:e;return(0,_.jsxs)("table",{className:"wp-list-table widefat striped wpshelf-table-skeleton",children:[(0,_.jsx)("thead",{children:(0,_.jsx)("tr",{children:Array.from({length:a},(e,s)=>(0,_.jsx)("th",{scope:"col",children:t?.[s]?t[s]:(0,_.jsx)("span",{className:"wpshelf-shimmer wpshelf-shimmer--header"})},s))})}),(0,_.jsx)("tbody",{children:Array.from({length:s},(e,s)=>(0,_.jsx)("tr",{children:Array.from({length:a},(e,t)=>(0,_.jsx)("td",{children:(0,_.jsx)("span",{className:"wpshelf-shimmer",style:{width:55+(7*s+13*t)%35+"%"}})},t))},s))})]})}function he(e){return e>=90?"danger":e>=75?"warn":""}const ge={success:"var(--wpshelf-success)",warn:"var(--wpshelf-warn)",danger:"var(--wpshelf-danger)"},ue={success:"var(--wpshelf-success-dark)",warn:"var(--wpshelf-warn-dark)",danger:"var(--wpshelf-danger)"};function _e({value:e,max:s,label:t,tone:a,scale:l="usage"}){const n=s>0?Math.min(e/s*100,100):0,i=t||`${Math.round(n)}%`,r=a||("completion"===l?function(e){return e>=67?"success":e>=34?"warn":"danger"}(n):he(n)),o=ge[r]||"",c=ue[r]||"";return(0,_.jsxs)("div",{className:"wpshelf-progress",children:[(0,_.jsx)("div",{className:"wpshelf-progress__bar",role:"progressbar","aria-valuenow":Math.round(n),"aria-valuemin":0,"aria-valuemax":100,"aria-valuetext":i,children:(0,_.jsx)("div",{className:"wpshelf-progress__fill",style:{width:`${n}%`,...o?{background:o}:{}}})}),(0,_.jsx)("span",{className:"wpshelf-progress__label","aria-hidden":"true",style:c?{color:c}:void 0,children:i})]})}function pe({steps:e,current:s}){return(0,_.jsx)("ol",{className:"wpshelf-stepper","aria-label":(0,l.__)("Setup progress","gloty"),children:e.map((t,a)=>{const l=a===s;let n="wpshelf-stepper__step";return a<s&&(n+=" wpshelf-stepper__step--done"),l&&(n+=" wpshelf-stepper__step--active"),(0,_.jsxs)("li",{className:n,"aria-current":l?"step":void 0,children:[a<e.length-1&&(0,_.jsx)("span",{className:"wpshelf-stepper__connector","aria-hidden":"true"}),(0,_.jsx)("span",{className:"wpshelf-stepper__label",children:t.label})]},t.key)})})}function me({items:e}){return(0,_.jsx)("div",{className:"wpshelf-milestones",role:"list",children:e.map(e=>{const s=e.done?(0,l.__)("Complete","gloty"):(0,l.__)("Pending","gloty");return(0,_.jsxs)("div",{className:"wpshelf-milestone "+(e.done?"wpshelf-milestone--done":"wpshelf-milestone--todo"),role:"listitem","aria-label":`${e.title}: ${s}`,children:[(0,_.jsx)("div",{className:"wpshelf-milestone__title",children:e.title}),(0,_.jsx)("div",{className:"wpshelf-milestone__state",children:s})]},e.key)})})}function ye({oldText:e,newText:s}){const t=(e||"").split(/(\s+)/),a=(s||"").split(/(\s+)/),l=t.length,n=a.length,i=Array.from({length:l+1},()=>new Array(n+1).fill(0));for(let e=1;e<=l;e++)for(let s=1;s<=n;s++)i[e][s]=t[e-1]===a[s-1]?i[e-1][s-1]+1:Math.max(i[e-1][s],i[e][s-1]);const r=[];let o=l,c=n;for(;o>0||c>0;)o>0&&c>0&&t[o-1]===a[c-1]?(r.unshift({type:"same",text:t[o-1]}),o--,c--):c>0&&(0===o||i[o][c-1]>=i[o-1][c])?(r.unshift({type:"add",text:a[c-1]}),c--):(r.unshift({type:"del",text:t[o-1]}),o--);return(0,_.jsx)("div",{className:"wpshelf-diff__content",children:r.map((e,s)=>"del"===e.type?(0,_.jsx)("del",{className:"wpshelf-diff__del",children:e.text},s):"add"===e.type?(0,_.jsx)("ins",{className:"wpshelf-diff__ins",children:e.text},s):(0,_.jsx)("span",{children:e.text},s))})}async function fe(){try{const e=await y()({path:"/gloty/v1/license/plans"});return Array.isArray(e?.plans)?e.plans:[]}catch{return[]}}function we(e,s){const t=e?.plan_slug||"",a=e?.characters_limit??0;return(s||[]).filter(e=>e.slug!==t).filter(e=>!e.renews||(e.quota?.limit??0)>a).sort((e,s)=>e.price-s.price)}function xe(e){const s=`$${(e.price/100).toLocaleString(void 0,{maximumFractionDigits:2})}`;return e.renews?"year"===e.interval?(0,l.sprintf)(/* translators: %s: price, e.g. $290 */ /* translators: %s: price, e.g. $290 */ 12 12 (0,l.__)("%s / yr","gloty"),s):(0,l.sprintf)(/* translators: %s: price, e.g. $29 */ /* translators: %s: price, e.g. $29 */ 13 13 (0,l.__)("%s / mo","gloty"),s):(0,l.sprintf)(/* translators: %s: price, e.g. $149 */ /* translators: %s: price, e.g. $149 */ 14 (0,l.__)("%s once","gloty"),s)}function xe(e){const s=(e.quota?.limit??0).toLocaleString();return e.renews?(0,l.sprintf)(/* translators: %s: character allowance, e.g. 500,000 */ /* translators: %s: character allowance, e.g. 500,000 */14 (0,l.__)("%s once","gloty"),s)}function ve(e){const s=(e.quota?.limit??0).toLocaleString();return e.renews?(0,l.sprintf)(/* translators: %s: character allowance, e.g. 500,000 */ /* translators: %s: character allowance, e.g. 500,000 */ 15 15 (0,l.__)("%s characters / mo","gloty"),s):(0,l.sprintf)(/* translators: %s: character allowance, e.g. 3,000,000 */ /* translators: %s: character allowance, e.g. 3,000,000 */ 16 (0,l.__)("%s characters, once","gloty"),s)}function ve(e){const s=String(e||"");return/not available for purchase|not configured|stripe/i.test(s)?{status:"warning",message:(0,l.__)("Plan upgrades aren’t available on this server — billing isn’t configured. Translations keep working on your current plan.","gloty")}:{status:"error",message:s||(0,l.__)("Could not create checkout session.","gloty")}}function je(e){let s=null;try{s=window.open(e,"_blank")}catch{s=null}return s?null:{status:"warning",message:(0,l.__)("Your browser blocked the checkout tab. Allow pop-ups for this site and press Upgrade again.","gloty")}}function be({used:e,limit:s}){const t=s>0?Math.min(100,Math.round(e/s*100)):0,a=de(t),n=(0,l.sprintf)(/* translators: 1: characters used, 2: character limit, 3: percentage used. */ /* translators: 1: characters used, 2: character limit, 3: percentage used. */17 (0,l.__)("%1$s / %2$s characters (%3$d%%)","gloty"),e.toLocaleString(),s.toLocaleString(),t);return(0, u.jsxs)("div",{className:"wpshelf-usage-bar",children:[(0,u.jsx)("div",{className:"wpshelf-usage-bar__track",role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":t,"aria-label":n,children:(0,u.jsx)("div",{className:"wpshelf-usage-bar__fill"+(a?` wpshelf-usage-bar__fill--${a}`:""),style:{width:`${t}%`}})}),(0,u.jsx)("span",{className:"wpshelf-usage-bar__label",children:n})]})}function Ne({slug:e}){return(0,u.jsx)("span",{className:"wpshelf-plan-badge",children:e||"free"})}function Ce({boot:e}){const[s,t]=(0,n.useState)(""),[a,i]=(0,n.useState)(e?.connection?.accountEmail||""),[r,o]=(0,n.useState)(e?.connection?.accountName||""),[c,d]=(0,n.useState)("getStarted"),[h,g]=(0,n.useState)(e?.license?.status||null),[_,p]=(0,n.useState)(e?.license?.hasKey||!1),[f,w]=(0,n.useState)(e?.license?.keyMasked||""),[x,v]=(0,n.useState)(!1),[j,b]=(0,n.useState)(!1),[N,C]=(0,n.useState)(null),[S,k]=(0,n.useState)(!1),[T,B]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=!0;return ye().then(s=>{e&&B(s)}),()=>{e=!1}},[]);const E=(0,n.useCallback)(async(e=!1)=>{b(!0);try{const s=e?"/gloty/v1/license/status?force=1":"/gloty/v1/license/status",t=await m()({path:s});p(t?.has_key||!1),g(t?.status||null),t?.key_masked&&w(t.key_masked),window.dispatchEvent(new CustomEvent("gloty-license-checked",{detail:t?.status||null}))}catch{}finally{b(!1)}},[]);(0,n.useEffect)(()=>{const e=()=>{E(!0)};return window.addEventListener("gloty-license-refresh",e),()=>window.removeEventListener("gloty-license-refresh",e)},[E]),(0,n.useEffect)(()=>{_&&!h&&E()},[_,h,E]);const L=e=>{const s=String(e||""),t=/no stripe customer|not configured|not found|stripe/i.test(s);C(t?{status:"warning",message:(0,l.__)("No billing portal is available for this license — there’s no Stripe subscription to manage. This is normal for free or manually-granted plans.","gloty")}:{status:"error",message:s||(0,l.__)("Could not open the billing portal.","gloty")})},M=fe(h,T);return(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsxs)("h3",{className:"wpshelf-settings-card__title",children:[(0,l.__)("License","gloty"),h&&(0,u.jsx)(Ne,{slug:h.plan_slug})]})}),(0,u.jsxs)(y.CardBody,{children:[N&&(0,u.jsx)(y.Notice,{status:N.status,isDismissible:!0,onDismiss:()=>C(null),className:"wpshelf-mb",children:N.message}),!_&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Get started with Gloty translation credits, or enter an existing license key.","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-license-tabs",style:{display:"flex",gap:12,marginBottom:16},children:[(0,u.jsx)(y.Button,{variant:"getStarted"===c?"primary":"secondary",isSmall:!0,onClick:()=>d("getStarted"),children:(0,l.__)("Get Started","gloty")}),(0,u.jsx)(y.Button,{variant:"existingKey"===c?"primary":"secondary",isSmall:!0,onClick:()=>d("existingKey"),children:(0,l.__)("I have a license key","gloty")})]}),"getStarted"===c&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextControl,{label:(0,l.__)("Email","gloty"),value:a,onChange:i,type:"email",__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextControl,{label:(0,l.__)("Name","gloty"),value:r,onChange:o,__nextHasNoMarginBottom:!0})}),(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{if(a.trim()&&r.trim()){v(!0),C(null);try{const e=await m()({path:"/gloty/v1/license/provision",method:"POST",data:{email:a.trim(),name:r.trim()}});e?.ok?(p(!0),C({status:"success",message:(0,l.__)("License provisioned and activated.","gloty")}),await E(!0)):C({status:"error",message:e?.message||(0,l.__)("Provisioning failed.","gloty")})}catch(e){C({status:"error",message:e?.message||(0,l.__)("Provisioning failed.","gloty")})}finally{v(!1)}}},isBusy:x,disabled:x||!a.trim()||!r.trim(),children:(0,l.__)("Get Free License","gloty")})]}),"existingKey"===c&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextControl,{label:(0,l.__)("License Key","gloty"),value:s,onChange:t,placeholder:"GLOTY-XXXX-XXXX-XXXX-XXXX",__nextHasNoMarginBottom:!0})}),(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{if(s.trim()){v(!0),C(null);try{const e=await m()({path:"/gloty/v1/license/activate",method:"POST",data:{license_key:s.trim()}});e?.ok?(p(!0),t(""),C({status:"success",message:(0,l.__)("License activated.","gloty")}),await E()):C({status:"error",message:e?.message||(0,l.__)("Activation failed.","gloty")})}catch(e){C({status:"error",message:e?.message||(0,l.__)("Activation failed.","gloty")})}finally{v(!1)}}},isBusy:x,disabled:x||!s.trim(),children:(0,l.__)("Activate","gloty")})]})]}),_&&h&&(0,u.jsxs)("div",{className:"wpshelf-license-details",children:[f&&(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("License key","gloty")}),(0,u.jsx)("code",{className:"wpshelf-license-key-masked",children:f})]}),(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Plan","gloty")}),(0,u.jsx)("span",{children:h.plan_name||"—"})]}),(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Status","gloty")}),(0,u.jsx)("span",{children:h.status||"—"})]}),(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Sites","gloty")}),(0,u.jsxs)("span",{children:[h.activations_used," / ",h.site_limit]})]}),(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Usage","gloty")}),(0,u.jsx)(be,{used:h.characters_used,limit:h.characters_limit})]}),h.characters_limit>0&&(0,u.jsx)("p",{className:"wpshelf-license-usage-note wpshelf-muted",children:h.characters_used/h.characters_limit>=.8?(0,l.__)("You’re approaching your monthly limit. Translation pauses at 100% until the limit resets or you upgrade — existing translations keep serving.","gloty"):(0,l.__)("Translation pauses when you reach your monthly limit, then resumes after it resets or you upgrade. Already-stored translations always keep serving.","gloty")}),h.period_end&&(0,u.jsxs)("div",{className:"wpshelf-license-row",children:[(0,u.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Resets","gloty")}),(0,u.jsx)("span",{children:new Date(h.period_end).toLocaleDateString()})]}),M.length>0&&(0,u.jsxs)("div",{className:"wpshelf-license-plans",children:[(0,u.jsx)("h4",{className:"wpshelf-license-plans__title",children:(0,l.__)("Upgrade","gloty")}),(0,u.jsx)("ul",{className:"wpshelf-license-plans__list",children:M.map(e=>(0,u.jsxs)("li",{className:"wpshelf-license-plans__item",children:[(0,u.jsxs)("div",{children:[(0,u.jsx)("strong",{children:e.name})," ",(0,u.jsx)("span",{className:"wpshelf-muted",children:we(e)}),(0,u.jsxs)("div",{className:"wpshelf-muted wpshelf-license-plans__meta",children:[xe(e)," · ",1===e.siteLimit?(0,l.__)("1 site","gloty"):(0,l.sprintf)(/* translators: %d: number of sites */ /* translators: %d: number of sites */18 (0,l.__)("Up to %d sites","gloty"),e.siteLimit)]})]}),(0, u.jsx)(y.Button,{variant:"primary",onClick:()=>(async e=>{v(!0),C(null);try{const s=await m()({path:"/gloty/v1/license/checkout",method:"POST",data:{plan_slug:e}});C(s?.url?je(s.url):ve(s?.message))}catch(e){C(ve(e?.message))}finally{v(!1)}})(e.slug),isBusy:x,disabled:x,children:e.renews?(0,l.__)("Upgrade","gloty"):(0,l.__)("Buy","gloty")})]},e.slug))})]}),(0,u.jsxs)("div",{className:"wpshelf-license-actions",children:[h.has_billing&&(0,u.jsx)(y.Button,{variant:"secondary",onClick:async()=>{v(!0),C(null);try{const e=await m()({path:"/gloty/v1/license/portal"});e?.url?window.open(e.url,"_blank","noopener,noreferrer"):L(e?.message)}catch(e){L(e?.message)}finally{v(!1)}},isBusy:x,disabled:x,children:(0,l.__)("Manage Subscription","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>E(!0),disabled:x||j,isBusy:j,"aria-live":"polite",children:j?(0,l.__)("Checking…","gloty"):(0,l.__)("Refresh status","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",isDestructive:!0,onClick:()=>k(!0),disabled:x,children:(0,l.__)("Deactivate","gloty")})]}),(0,u.jsx)("p",{className:"wpshelf-license-deactivate-note wpshelf-muted",children:(0,l.__)("Deactivating frees this license for another site. Your translations stay in place — nothing is deleted.","gloty")})]}),S&&(0,u.jsx)(ie,{title:(0,l.__)("Deactivate license on this site?","gloty"),message:(0,l.__)("This frees the license seat for use on another site. Your stored translations stay in place and keep serving, but new translations stop until you reactivate. Nothing is deleted.","gloty"),confirmLabel:(0,l.__)("Deactivate","gloty"),busy:x,onConfirm:()=>{k(!1),(async()=>{v(!0),C(null);try{await m()({path:"/gloty/v1/license/deactivate",method:"POST"}),p(!1),g(null),C({status:"info",message:(0,l.__)("License deactivated.","gloty")})}catch(e){C({status:"error",message:e?.message||(0,l.__)("Deactivation failed.","gloty")})}finally{v(!1)}})()},onCancel:()=>k(!1)}),_&&!h&&(0,u.jsxs)("p",{className:"wpshelf-muted",children:[f&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("code",{className:"wpshelf-license-key-masked",children:f})," — "]}),(0,l.__)("License key is configured but the license server could not be reached.","gloty"),(0,u.jsx)(y.Button,{variant:"link",onClick:()=>E(!0),disabled:j,isBusy:j,style:{marginLeft:8},"aria-live":"polite",children:j?(0,l.__)("Retrying…","gloty"):(0,l.__)("Retry","gloty")})]})]})]})}function Se({boot:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(!1),r=(0,n.useRef)(e?.license?.status||null);return(0,n.useEffect)(()=>{if("undefined"==typeof window)return;const e=new URL(window.location.href),s=e.searchParams.get("checkout");if(!s)return;if(e.searchParams.delete("checkout"),window.history.replaceState({},"",e.toString()),"cancel"===s)return void t({status:"info",message:(0,l.__)("Checkout closed — nothing was charged. Pick a plan below whenever you’re ready.","gloty")});if("success"!==s)return;i(!0),t({status:"info",message:(0,l.__)("Payment received. Waiting for Stripe to confirm it — your plan and allowance update here as soon as it does.","gloty")});let a=0;const n=()=>window.dispatchEvent(new CustomEvent("gloty-license-refresh"));n();const r=window.setInterval(()=>{if(a+=1,a>=12)return window.clearInterval(r),i(!1),void t({status:"warning",message:(0,l.__)("Payment received, but Stripe has not confirmed it here yet. Nothing is lost — use Refresh status in a few minutes, and contact support if your new plan still is not shown.","gloty")});n()},5e3);return()=>window.clearInterval(r)},[]),(0,n.useEffect)(()=>{if(!a)return;const e=e=>{var s,a;s=r.current,(a=e.detail)&&(s?a.has_billing&&!s.has_billing||a.plan_slug!==s.plan_slug||(a.characters_limit??0)>(s.characters_limit??0):Boolean(a.has_billing))&&(i(!1),t({status:"success",message:(0,l.__)("Checkout complete — your plan and allowance are up to date.","gloty")}))};return window.addEventListener("gloty-license-checked",e),()=>window.removeEventListener("gloty-license-checked",e)},[a]),(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-billing-screen",role:"region","aria-label":(0,l.__)("Billing","gloty"),children:[(0,u.jsxs)("p",{className:"wpshelf-screen__lead",children:[(0,l.__)("Manage your Gloty license, view plan usage, and update your subscription.","gloty")," ",(0,u.jsx)(y.ExternalLink,{href:"https://wp-shelf.com/gloty#pricing",children:(0,l.__)("Compare plans and pricing","gloty")})]}),s&&(0,u.jsx)(y.Notice,{status:s.status,isDismissible:!0,onDismiss:()=>t(null),className:"wpshelf-mb",children:s.message}),(0,u.jsx)(Ce,{boot:e})]})}const ke=(0,n.createContext)(null),Te={success:"✓",error:"!",info:"i"};let Be=0;function Ee({children:e}){const[s,t]=(0,n.useState)([]),a=(0,n.useCallback)((e,s="success",a=4e3)=>{const l=++Be;t(t=>[...t,{id:l,message:e,status:s}]),a>0&&window.setTimeout(()=>{t(e=>e.filter(e=>e.id!==l))},a)},[]),l=(0,n.useCallback)(e=>{t(s=>s.filter(s=>s.id!==e))},[]),i={success:e=>a(e,"success"),error:e=>a(e,"error",6e3),info:e=>a(e,"info"),add:a,dismiss:l};return(0,u.jsxs)(ke.Provider,{value:i,children:[e,(0,u.jsx)(Me,{toasts:s,onDismiss:l})]})}function Le(){return(0,n.useContext)(ke)}function Me({toasts:e,onDismiss:s}){return 0===e.length?null:(0,u.jsx)("div",{className:"wpshelf-toast-container","aria-live":"polite",children:e.map(e=>(0,u.jsxs)("div",{className:`wpshelf-toast wpshelf-toast--${e.status}`,role:"status",children:[(0,u.jsx)("span",{className:"wpshelf-toast__icon","aria-hidden":"true",children:Te[e.status]??Te.info}),(0,u.jsx)("span",{className:"wpshelf-toast__message",children:e.message}),(0,u.jsx)("button",{className:"wpshelf-toast__close",onClick:()=>s(e.id),"aria-label":(0,l.__)("Dismiss","gloty"),children:"×"})]},e.id))})}const Ae=[{label:"Surface",tokens:["--wpshelf-bg","--wpshelf-surface","--wpshelf-surface-alt"]},{label:"Ink",tokens:["--wpshelf-ink","--wpshelf-ink-soft","--wpshelf-muted"]},{label:"Line",tokens:["--wpshelf-line","--wpshelf-line-soft"]},{label:"Fill (primary action)",tokens:["--wpshelf-fill","--wpshelf-fill-hover","--wpshelf-fill-ink"]},{label:"Accent",tokens:["--wpshelf-accent","--wpshelf-accent-dark","--wpshelf-accent-50","--wpshelf-accent-100"]},{label:"Success",tokens:["--wpshelf-success","--wpshelf-success-dark","--wpshelf-success-50"]},{label:"Warning",tokens:["--wpshelf-warn","--wpshelf-warn-dark","--wpshelf-warn-50"]},{label:"Danger",tokens:["--wpshelf-danger","--wpshelf-danger-50"]}],De=["--wpshelf-text-2xs","--wpshelf-text-xs","--wpshelf-text-sm","--wpshelf-text-base","--wpshelf-text-md","--wpshelf-text-lg","--wpshelf-text-xl","--wpshelf-text-2xl","--wpshelf-text-stat-md","--wpshelf-text-stat-lg"],Re=["--wpshelf-space-1","--wpshelf-space-2","--wpshelf-space-3","--wpshelf-space-4","--wpshelf-space-5","--wpshelf-space-6","--wpshelf-space-7","--wpshelf-space-8","--wpshelf-space-10","--wpshelf-space-14","--wpshelf-space-16"],Oe=["--wpshelf-radius-xs","--wpshelf-radius-sm","--wpshelf-radius","--wpshelf-radius-lg","--wpshelf-radius-pill"],Pe=["--wpshelf-shadow","--wpshelf-shadow-hover","--wpshelf-shadow-overlay","--wpshelf-shadow-brand","--wpshelf-shadow-mark"],$e=["not_translated","pending","processing","synced","stale","failed","manually_edited"],Ie=["queued","processing","completed","cancelled","paused"],He=[{tone:"loading",label:(0,l.__)("Checking…","gloty")},{tone:"ok",label:(0,l.__)("Connected","gloty")},{tone:"warning",label:(0,l.__)("Degraded","gloty")},{tone:"error",label:(0,l.__)("Disconnected","gloty")}],Ge=[{key:"welcome",label:(0,l.__)("Welcome","gloty")},{key:"connection",label:(0,l.__)("Connection","gloty")},{key:"languages",label:(0,l.__)("Languages","gloty")},{key:"scan",label:(0,l.__)("Content scan","gloty")},{key:"done",label:(0,l.__)("Ready","gloty")}];function ze(e){const[s,t]=(0,n.useState)("");return(0,n.useEffect)(()=>{if("undefined"==typeof window)return;const s=window.getComputedStyle(document.documentElement).getPropertyValue(e).trim();t(s)},[e]),s}function Fe({name:e}){const s=ze(e);return(0,u.jsxs)("div",{className:"wpshelf-ds-swatch",children:[(0,u.jsx)("div",{className:"wpshelf-ds-swatch__chip",style:{background:`var(${e})`}}),(0,u.jsx)("code",{className:"wpshelf-ds-swatch__name",children:e}),(0,u.jsx)("span",{className:"wpshelf-ds-swatch__value",children:s||"—"})]})}function Ve({name:e}){const s=ze(e);return(0,u.jsxs)("div",{className:"wpshelf-ds-type-row",children:[(0,u.jsx)("span",{style:{fontSize:`var(${e})`,lineHeight:1.1},children:(0,l.__)("The quick brown fox","gloty")}),(0,u.jsxs)("span",{className:"wpshelf-ds-type-row__meta",children:[(0,u.jsx)("code",{children:e})," · ",s||"—"]})]})}function Ue({name:e}){const s=ze(e);return(0,u.jsxs)("div",{className:"wpshelf-ds-space-row",children:[(0,u.jsx)("span",{className:"wpshelf-ds-space-row__bar",style:{width:`var(${e})`}}),(0,u.jsx)("code",{children:e}),(0,u.jsx)("span",{className:"wpshelf-ds-swatch__value",children:s||"—"})]})}function qe(){const e=Le(),[s,t]=(0,n.useState)(!1),[a,i]=(0,n.useState)(!1);return(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-ds",role:"region","aria-label":(0,l.__)("Design system preview","gloty"),children:[(0,u.jsx)(ee,{title:(0,l.__)("Design system","gloty"),subtitle:(0,l.__)("Live catalog of every token and shared primitive. Source of truth: docs/design-system/. This screen is developer-facing and hidden from customers.","gloty")}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Color tokens","gloty")}),Ae.map(e=>(0,u.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,u.jsx)("div",{className:"wpshelf-ds-group__label",children:e.label}),(0,u.jsx)("div",{className:"wpshelf-ds-swatch-grid",children:e.tokens.map(e=>(0,u.jsx)(Fe,{name:e},e))})]},e.label)),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Type scale","gloty")}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsx)(y.CardBody,{children:De.map(e=>(0,u.jsx)(Ve,{name:e},e))})}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Spacing scale","gloty")}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsx)(y.CardBody,{children:Re.map(e=>(0,u.jsx)(Ue,{name:e},e))})}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Radius & elevation","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,u.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Radius","gloty")}),(0,u.jsx)("div",{className:"wpshelf-ds-cluster",children:Oe.map(e=>(0,u.jsxs)("div",{className:"wpshelf-ds-radius-box",children:[(0,u.jsx)("div",{className:"wpshelf-ds-radius-box__shape",style:{borderRadius:`var(${e})`}}),(0,u.jsx)("code",{children:e})]},e))})]}),(0,u.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,u.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Shadow","gloty")}),(0,u.jsx)("div",{className:"wpshelf-ds-cluster",children:Pe.map(e=>(0,u.jsxs)("div",{className:"wpshelf-ds-shadow-box",children:[(0,u.jsx)("div",{className:"wpshelf-ds-shadow-box__shape",style:{boxShadow:`var(${e})`}}),(0,u.jsx)("code",{children:e})]},e))})]}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Status vocabulary","gloty")}),(0,u.jsxs)(y.Card,{className:"wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Translation statuses","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-ds-cluster wpshelf-mb",children:$e.map(e=>(0,u.jsx)(K,{status:e},e))}),(0,u.jsx)(Q,{statuses:$e})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Job / scan statuses","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)("div",{className:"wpshelf-ds-cluster",children:Ie.map(e=>(0,u.jsx)(K,{status:e},e))})})]}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Stat cards","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--translated",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Translated","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:"128"}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("of 240 source strings","gloty")})]})}),(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--pending",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Pending","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:"12"}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("awaiting dispatch","gloty")})]})}),(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--stale",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Stale","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:"4"}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("source content changed","gloty")})]})})]}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Progress bar","gloty")}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted wpshelf-mb",children:(0,l.__)('scale="usage" — a full bar is bad (quota, rate limit).',"gloty")}),(0,u.jsx)(ue,{value:3,max:240,label:"3 of 240"}),(0,u.jsx)(ue,{value:180,max:240,label:"180 of 240 (warn ≥75%)"}),(0,u.jsx)(ue,{value:232,max:240,label:"232 of 240 (danger ≥90%)"}),(0,u.jsx)(ue,{value:240,max:240,tone:"success",label:"Complete"})]})}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted wpshelf-mb",children:(0,l.__)('scale="completion" — a full bar is good (translation coverage). The inverse of the scale above, which is why the meaning is declared at the call site rather than inferred from the number.',"gloty")}),(0,u.jsx)(ue,{value:18,max:240,scale:"completion",label:"8% (danger <34%)"}),(0,u.jsx)(ue,{value:120,max:240,scale:"completion",label:"50% (warn ≥34%)"}),(0,u.jsx)(ue,{value:228,max:240,scale:"completion",label:"95% (success ≥67%)"})]})}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Feedback states","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-ds-states",children:[(0,u.jsxs)(y.Card,{children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Loading","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)(oe,{text:(0,l.__)("Loading translations…","gloty")})})]}),(0,u.jsxs)(y.Card,{children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Empty","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)(ne,{icon:"🌐",title:(0,l.__)("No target languages","gloty"),hint:(0,l.__)("Enable at least one language to start translating your site.","gloty")})})]}),(0,u.jsxs)(y.Card,{children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Error","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,children:(0,l.__)("Could not connect to the translator service. Check that your API key is valid in Settings → Connection.","gloty")})})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-mt wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Table skeleton","gloty")})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)(ce,{rows:3,headers:[(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Updated","gloty")]})})]}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Navigation","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,u.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Health pill","gloty")}),(0,u.jsx)("div",{className:"wpshelf-ds-cluster",children:He.map(e=>(0,u.jsxs)("span",{className:`wpshelf-health-pill wpshelf-health-pill--${e.tone}`,children:[(0,u.jsx)("span",{className:"wpshelf-health-pill__dot","aria-hidden":"true"}),(0,u.jsx)("span",{className:"wpshelf-health-pill__label",children:e.label})]},e.tone))})]}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)(_e,{steps:Ge,current:2}),(0,u.jsx)(pe,{items:[{key:"connection",title:(0,l.__)("Site connected to Gloty","gloty"),done:!0},{key:"languages",title:(0,l.__)("Target languages enabled","gloty"),done:!0},{key:"scan",title:(0,l.__)("Initial content scan started","gloty"),done:!1}]})]})}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Chips & buttons","gloty")}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsxs)("div",{className:"wpshelf-ds-cluster wpshelf-mb",children:[(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success",children:"success"}),(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--warn",children:"warn"}),(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--error",children:"error"}),(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--info",children:"info"}),(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--muted",children:"muted"}),(0,u.jsx)("span",{className:"wpshelf-chip",children:"neutral"})]}),(0,u.jsxs)("div",{className:"wpshelf-ds-cluster",children:[(0,u.jsx)(y.Button,{variant:"primary",children:(0,l.__)("Primary","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",children:(0,l.__)("Secondary","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",children:(0,l.__)("Tertiary","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",isDestructive:!0,children:(0,l.__)("Destructive","gloty")}),(0,u.jsx)(y.Button,{variant:"link",children:(0,l.__)("Link","gloty")})]})]})}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Overlays","gloty")}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsx)(y.CardBody,{children:(0,u.jsxs)("div",{className:"wpshelf-ds-cluster",children:[(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>e.success((0,l.__)("Settings saved.","gloty")),children:(0,l.__)("Success toast","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>e.error((0,l.__)("Could not save changes.","gloty")),children:(0,l.__)("Error toast","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>e.info((0,l.__)("Scan started in background.","gloty")),children:(0,l.__)("Info toast","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>t(!0),children:(0,l.__)("Open confirm modal","gloty")})]})})}),s&&(0,u.jsx)(ie,{title:(0,l.__)("Delete translations","gloty"),message:(0,l.__)("Delete 3 cached translations? They may be regenerated later.","gloty"),confirmLabel:(0,l.__)("Delete","gloty"),busy:a,onConfirm:()=>{i(!0),window.setTimeout(()=>{i(!1),t(!1),e.success((0,l.__)("Deleted 3 translations.","gloty"))},900)},onCancel:()=>t(!1)})]})}function We({boot:e,onNavigate:s}){const t=e?.firstTranslation||{},a=e?.siteUrl||window?.location?.origin||"",i=e?.routing?.url_structure||"subdirectory",[r,o]=(0,n.useState)(!!t.dismissedAt),[c,d]=(0,n.useState)(!1);if(!(0,n.useMemo)(()=>!r&&!!t.at&&function(e){if(!e)return 1/0;const s=String(e).replace(" ","T")+"Z",t=Date.parse(s);return Number.isNaN(t)?1/0:(Date.now()-t)/36e5}(t.at)<48,[r,t.at]))return null;const h=t.lang||"",g=h?h.toUpperCase():"",_=(()=>{if(!h)return a||"/";if("parameter"===i){const e=a.includes("?")?"&":"?";return`${a}${e}lang=${encodeURIComponent(h)}`}return`${a.replace(/\/$/,"")}/${encodeURIComponent(h)}/`})();return(0,u.jsx)(y.Card,{className:"wpshelf-first-translation wpshelf-mb",role:"region","aria-label":(0,l.__)("First translation welcome","gloty"),children:(0,u.jsx)(y.CardBody,{children:(0,u.jsxs)("div",{className:"wpshelf-first-translation__body",children:[(0,u.jsxs)("div",{className:"wpshelf-first-translation__text",children:[(0,u.jsx)("h2",{className:"wpshelf-first-translation__title",children:g?(0,l.sprintf)(/* translators: %s: language code, e.g. FR */ /* translators: %s: language code, e.g. FR */19 (0,l.__)("🎉 Your first %s translation is live","gloty"),g):(0,l.__)("🎉 Your first translation is live","gloty")}),(0, u.jsx)("p",{className:"wpshelf-first-translation__hint wpshelf-muted",children:(0,l.__)("Open the front end in the target language to see it in place. Share the preview link with your team so they can review.","gloty")})]}),(0,u.jsxs)("div",{className:"wpshelf-first-translation__actions",children:[(0,u.jsx)(y.Button,{variant:"primary",href:_,target:"_blank",rel:"noreferrer",children:g?(0,l.sprintf)(/* translators: %s: language code */ /* translators: %s: language code */20 (0,l.__)("View site in %s","gloty"),g):(0,l.__)("View translated site","gloty")}),(0, u.jsx)(y.Button,{variant:"secondary",onClick:async()=>{try{await navigator.clipboard.writeText(_),d(!0),window.setTimeout(()=>d(!1),2e3)}catch{window.prompt((0,l.__)("Copy this link:","gloty"),_)}},children:c?(0,l.__)("Copied!","gloty"):(0,l.__)("Share with your team","gloty")}),s&&(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>s("translations"),children:(0,l.__)("Review translations","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",onClick:async()=>{o(!0);try{await m()({path:"/gloty/v1/first-translation/dismiss",method:"POST"})}catch{}},"aria-label":(0,l.__)("Dismiss welcome","gloty"),children:(0,l.__)("Dismiss","gloty")})]})]})})})}function Xe({position:e,total:s,step:t,onNavigate:a}){let n="wpshelf-gs__step--todo";return t.done?n="wpshelf-gs__step--done":t.active&&(n="wpshelf-gs__step--active"),(0,u.jsxs)("li",{className:`wpshelf-gs__step ${n}`,children:[(0,u.jsx)("span",{className:"wpshelf-gs__marker","aria-hidden":"true",children:t.done?"✓":e}),(0,u.jsxs)("div",{className:"wpshelf-gs__body",children:[(0,u.jsxs)("div",{className:"wpshelf-gs__title",children:[t.title,t.done&&(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success wpshelf-gs__badge",children:(0,l.__)("Done","gloty")})]}),(0,u.jsx)("p",{className:"wpshelf-gs__desc wpshelf-muted",children:t.description})]}),!t.done&&t.action&&a&&(0,u.jsx)("div",{className:"wpshelf-gs__action",children:(0,u.jsx)(y.Button,{variant:t.active?"primary":"secondary",onClick:()=>a(t.action.tab),children:t.action.label})}),e<s&&(0,u.jsx)("span",{className:"wpshelf-gs__connector","aria-hidden":"true"})]})}function Ye({hasLanguages:e,hasSource:s,hasTranslated:t,pendingCount:a=0,onNavigate:n}){if(t)return null;const i=[{key:"languages",done:e,title:(0,l.__)("Choose your languages","gloty"),description:(0,l.__)("Pick the languages you want your site translated into.","gloty"),action:{tab:"languages",label:e?(0,l.__)("Manage languages","gloty"):(0,l.__)("Add a language","gloty")}},{key:"scan",done:s,title:(0,l.__)("Scan your content","gloty"),description:(0,l.__)("Gloty collects every translatable piece of text on your site.","gloty"),action:{tab:"sync",label:s?(0,l.__)("Open Sync","gloty"):(0,l.__)("Run a scan","gloty")}},{key:"translate",done:t,title:(0,l.__)("Translate","gloty"),description:a>0?(0,l.sprintf)(/* translators: %s: number of pending strings */ /* translators: %s: number of pending strings */21 (0,l.__)("%s strings are ready — send them to your AI provider to translate.","gloty"),Number(a).toLocaleString()):(0,l.__)("Send collected strings to your AI provider to translate.","gloty"),action:{tab:"sync",label:(0,l.__)("Translate now","gloty")}}],r=i.findIndex(e=>!e.done);return i.forEach((e,s)=>{e.active=s===r}),(0, u.jsxs)(y.Card,{className:"wpshelf-getting-started wpshelf-mb",role:"region","aria-label":(0,l.__)("Getting started","gloty"),children:[(0,u.jsxs)(y.CardHeader,{children:[(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Get started with Gloty","gloty")}),(0,u.jsxs)("span",{className:"wpshelf-gs__flow wpshelf-muted","aria-hidden":"true",children:[(0,l.__)("Scan","gloty")," ","→"," ",(0,l.__)("Translate","gloty")," ","→"," ",(0,l.__)("Serve","gloty")]})]}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)("ol",{className:"wpshelf-gs__steps",children:i.map((e,s)=>(0,u.jsx)(Xe,{position:s+1,total:i.length,step:e,onNavigate:n},e.key))})})]})}const Ze=[{code:"en",name:"English",native_name:"English"},{code:"es",name:"Spanish",native_name:"Español"},{code:"fr",name:"French",native_name:"Français"},{code:"de",name:"German",native_name:"Deutsch"},{code:"it",name:"Italian",native_name:"Italiano"},{code:"pt",name:"Portuguese",native_name:"Português"},{code:"nl",name:"Dutch",native_name:"Nederlands"},{code:"pl",name:"Polish",native_name:"Polski"},{code:"ru",name:"Russian",native_name:"Русский"},{code:"uk",name:"Ukrainian",native_name:"Українська"},{code:"cs",name:"Czech",native_name:"Čeština"},{code:"sk",name:"Slovak",native_name:"Slovenčina"},{code:"sl",name:"Slovenian",native_name:"Slovenščina"},{code:"hu",name:"Hungarian",native_name:"Magyar"},{code:"ro",name:"Romanian",native_name:"Română"},{code:"bg",name:"Bulgarian",native_name:"Български"},{code:"hr",name:"Croatian",native_name:"Hrvatski"},{code:"sr",name:"Serbian",native_name:"Српски"},{code:"bs",name:"Bosnian",native_name:"Bosanski"},{code:"mk",name:"Macedonian",native_name:"Македонски"},{code:"sq",name:"Albanian",native_name:"Shqip"},{code:"el",name:"Greek",native_name:"Ελληνικά"},{code:"tr",name:"Turkish",native_name:"Türkçe"},{code:"sv",name:"Swedish",native_name:"Svenska"},{code:"no",name:"Norwegian",native_name:"Norsk"},{code:"nb",name:"Norwegian Bokmål",native_name:"Norsk bokmål"},{code:"nn",name:"Norwegian Nynorsk",native_name:"Norsk nynorsk"},{code:"da",name:"Danish",native_name:"Dansk"},{code:"fi",name:"Finnish",native_name:"Suomi"},{code:"is",name:"Icelandic",native_name:"Íslenska"},{code:"et",name:"Estonian",native_name:"Eesti"},{code:"lv",name:"Latvian",native_name:"Latviešu"},{code:"lt",name:"Lithuanian",native_name:"Lietuvių"},{code:"ga",name:"Irish",native_name:"Gaeilge"},{code:"cy",name:"Welsh",native_name:"Cymraeg"},{code:"eu",name:"Basque",native_name:"Euskara"},{code:"ca",name:"Catalan",native_name:"Català"},{code:"gl",name:"Galician",native_name:"Galego"},{code:"mt",name:"Maltese",native_name:"Malti"},{code:"ja",name:"Japanese",native_name:"日本語"},{code:"ko",name:"Korean",native_name:"한국어"},{code:"zh",name:"Chinese",native_name:"中文"},{code:"vi",name:"Vietnamese",native_name:"Tiếng Việt"},{code:"th",name:"Thai",native_name:"ไทย"},{code:"lo",name:"Lao",native_name:"ລາວ"},{code:"km",name:"Khmer",native_name:"ខ្មែរ"},{code:"my",name:"Burmese",native_name:"မြန်မာ"},{code:"id",name:"Indonesian",native_name:"Bahasa Indonesia"},{code:"ms",name:"Malay",native_name:"Bahasa Melayu"},{code:"tl",name:"Tagalog",native_name:"Tagalog"},{code:"fil",name:"Filipino",native_name:"Filipino"},{code:"hi",name:"Hindi",native_name:"हिन्दी"},{code:"bn",name:"Bengali",native_name:"বাংলা"},{code:"ta",name:"Tamil",native_name:"தமிழ்"},{code:"te",name:"Telugu",native_name:"తెలుగు"},{code:"ml",name:"Malayalam",native_name:"മലയാളം"},{code:"kn",name:"Kannada",native_name:"ಕನ್ನಡ"},{code:"mr",name:"Marathi",native_name:"मराठी"},{code:"gu",name:"Gujarati",native_name:"ગુજરાતી"},{code:"pa",name:"Punjabi",native_name:"ਪੰਜਾਬੀ"},{code:"or",name:"Odia",native_name:"ଓଡ଼ିଆ"},{code:"as",name:"Assamese",native_name:"অসমীয়া"},{code:"ne",name:"Nepali",native_name:"नेपाली"},{code:"si",name:"Sinhala",native_name:"සිංහල"},{code:"ur",name:"Urdu",native_name:"اردو",is_rtl:!0},{code:"ar",name:"Arabic",native_name:"العربية",is_rtl:!0},{code:"he",name:"Hebrew",native_name:"עברית",is_rtl:!0},{code:"fa",name:"Persian",native_name:"فارسی",is_rtl:!0},{code:"ps",name:"Pashto",native_name:"پښتو",is_rtl:!0},{code:"ku",name:"Kurdish",native_name:"Kurdî"},{code:"az",name:"Azerbaijani",native_name:"Azərbaycanca"},{code:"hy",name:"Armenian",native_name:"Հայերեն"},{code:"ka",name:"Georgian",native_name:"ქართული"},{code:"kk",name:"Kazakh",native_name:"Қазақша"},{code:"uz",name:"Uzbek",native_name:"Oʻzbekcha"},{code:"ky",name:"Kyrgyz",native_name:"Кыргызча"},{code:"tg",name:"Tajik",native_name:"Тоҷикӣ"},{code:"tk",name:"Turkmen",native_name:"Türkmençe"},{code:"mn",name:"Mongolian",native_name:"Монгол"},{code:"sw",name:"Swahili",native_name:"Kiswahili"},{code:"am",name:"Amharic",native_name:"አማርኛ"},{code:"yo",name:"Yoruba",native_name:"Yorùbá"},{code:"ig",name:"Igbo",native_name:"Igbo"},{code:"ha",name:"Hausa",native_name:"Hausa"},{code:"zu",name:"Zulu",native_name:"isiZulu"},{code:"xh",name:"Xhosa",native_name:"isiXhosa"},{code:"af",name:"Afrikaans",native_name:"Afrikaans"},{code:"so",name:"Somali",native_name:"Soomaali"},{code:"eo",name:"Esperanto",native_name:"Esperanto"},{code:"en-GB",name:"English (United Kingdom)",native_name:"English (UK)"},{code:"en-US",name:"English (United States)",native_name:"English (US)"},{code:"en-AU",name:"English (Australia)",native_name:"English (AU)"},{code:"en-CA",name:"English (Canada)",native_name:"English (CA)"},{code:"en-IE",name:"English (Ireland)",native_name:"English (IE)"},{code:"en-IN",name:"English (India)",native_name:"English (IN)"},{code:"en-NZ",name:"English (New Zealand)",native_name:"English (NZ)"},{code:"en-ZA",name:"English (South Africa)",native_name:"English (ZA)"},{code:"es-ES",name:"Spanish (Spain)",native_name:"Español (España)"},{code:"es-MX",name:"Spanish (Mexico)",native_name:"Español (México)"},{code:"es-AR",name:"Spanish (Argentina)",native_name:"Español (Argentina)"},{code:"es-CL",name:"Spanish (Chile)",native_name:"Español (Chile)"},{code:"es-CO",name:"Spanish (Colombia)",native_name:"Español (Colombia)"},{code:"es-419",name:"Spanish (Latin America)",native_name:"Español (Latinoamérica)"},{code:"pt-BR",name:"Portuguese (Brazil)",native_name:"Português (Brasil)"},{code:"pt-PT",name:"Portuguese (Portugal)",native_name:"Português (Portugal)"},{code:"fr-FR",name:"French (France)",native_name:"Français (France)"},{code:"fr-CA",name:"French (Canada)",native_name:"Français (Canada)"},{code:"fr-BE",name:"French (Belgium)",native_name:"Français (Belgique)"},{code:"fr-CH",name:"French (Switzerland)",native_name:"Français (Suisse)"},{code:"de-DE",name:"German (Germany)",native_name:"Deutsch (Deutschland)"},{code:"de-AT",name:"German (Austria)",native_name:"Deutsch (Österreich)"},{code:"de-CH",name:"German (Switzerland)",native_name:"Deutsch (Schweiz)"},{code:"it-IT",name:"Italian (Italy)",native_name:"Italiano (Italia)"},{code:"it-CH",name:"Italian (Switzerland)",native_name:"Italiano (Svizzera)"},{code:"nl-NL",name:"Dutch (Netherlands)",native_name:"Nederlands (Nederland)"},{code:"nl-BE",name:"Dutch (Belgium)",native_name:"Nederlands (België)"},{code:"zh-CN",name:"Chinese (Simplified)",native_name:"中文 (简体)"},{code:"zh-TW",name:"Chinese (Traditional)",native_name:"中文 (繁體)"},{code:"zh-HK",name:"Chinese (Hong Kong)",native_name:"中文 (香港)"},{code:"zh-SG",name:"Chinese (Singapore)",native_name:"中文 (新加坡)"},{code:"ar-SA",name:"Arabic (Saudi Arabia)",native_name:"العربية (السعودية)",is_rtl:!0},{code:"ar-EG",name:"Arabic (Egypt)",native_name:"العربية (مصر)",is_rtl:!0},{code:"ar-AE",name:"Arabic (UAE)",native_name:"العربية (الإمارات)",is_rtl:!0},{code:"sr-Latn",name:"Serbian (Latin)",native_name:"Srpski"}],Je=new Set(["en","es","fr","de","it","pt","nl","pl","ru","uk","cs","sk","sl","hu","ro","bg","hr","sr","el","tr","sv","no","da","fi","et","lv","lt","ja","ko","zh","vi","th","id","hi","bn","ar","he","sw"]),Ke=Ze.filter(e=>function(e){const s=String(e||"").toLowerCase();return!s.includes("-")&&Je.has(s)}(e.code));function Qe(e){if(!e)return null;const s=String(e).toLowerCase();return Ze.find(e=>e.code.toLowerCase()===s)||null}const es={pt:{kind:"ambiguous",variants:["pt-BR","pt-PT"]},zh:{kind:"ambiguous",variants:["zh-CN","zh-TW"]}},ss={id:null,source_term:"",rule_type:"never_translate",case_sensitive:!1,notes:"",translations:{}};function ts({boot:e}){const s=Le(),t=String(e?.language?.default||"en").toLowerCase(),a=(0,n.useMemo)(()=>Array.isArray(e?.language?.active)?e.language.active:[],[e]),i=(0,n.useMemo)(()=>a.map(e=>String(e).toLowerCase()).filter(e=>e&&e!==t),[a,t]),[r,o]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[h,g]=(0,n.useState)(null),[p,f]=(0,n.useState)(!1),[x,v]=(0,n.useState)(null),[j,b]=(0,n.useState)(!1),[N,C]=(0,n.useState)(null),S=(0,n.useCallback)(async()=>{d(null);try{const e=await m()({path:"/gloty/v1/glossary",parse:!0});o(Array.isArray(e?.terms)?e.terms:[])}catch(e){o([]),d({status:"error",message:e?.message||(0,l.__)("Could not load the glossary.","gloty")})}},[]);(0,n.useEffect)(()=>{S()},[S]);const k=(0,n.useCallback)(e=>{const s=Qe(e);return s?`${s.name} (${e.toUpperCase()})`:e.toUpperCase()},[]),B=(e,s)=>g(t=>({...t,[e]:s})),E=e=>{if("translate_as"!==e.rule_type)return(0,l.__)("Kept exactly as written","gloty");const s=i.map(s=>{const t=e.translations?.[s];return t?`${s.toUpperCase()}: ${t}`:null}).filter(Boolean);return s.length?s.join(" · "):(0,l.__)("No per-language values set yet","gloty")},L=null===r;return(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-glossary-screen",children:[(0,u.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Keep your brand and product names exactly right in every language. Add a term to stop it being translated, or set exactly how it should appear per language.","gloty")}),c&&(0,u.jsx)(y.Notice,{status:c.status,isDismissible:!0,onDismiss:()=>d(null),className:"wpshelf-mb",children:c.message}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card",children:[(0,u.jsxs)(y.CardHeader,{size:"small",children:[(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Glossary terms","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:()=>g({...ss,translations:{}}),disabled:L,children:(0,l.__)("Add term","gloty")})]}),(0,u.jsxs)(y.CardBody,{children:[L&&(0,u.jsx)(ce,{rows:4,headers:[(0,l.__)("Term","gloty"),(0,l.__)("Behavior","gloty"),(0,l.__)("Rendering","gloty"),(0,l.__)("Active","gloty"),""]}),!L&&0===r.length&&(0,u.jsx)(ne,{icon:(0,u.jsx)(w,{icon:T}),title:(0,l.__)("No glossary terms yet","gloty"),hint:(0,l.__)("Add a brand or product name to protect it from translation across your whole site.","gloty")}),!L&&r.length>0&&(0,u.jsxs)(_,{className:"wp-list-table widefat striped wpshelf-table",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Term","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Behavior","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Rendering","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Active","gloty")}),(0,u.jsx)("th",{scope:"col"})]})}),(0,u.jsx)("tbody",{children:r.map(e=>(0,u.jsxs)("tr",{children:[(0,u.jsxs)("td",{children:[(0,u.jsx)("strong",{children:e.source_term}),!!e.case_sensitive&&(0,u.jsxs)("span",{className:"wpshelf-muted",children:[" ","·"," ",(0,l.__)("case-sensitive","gloty")]}),e.notes&&(0,u.jsx)("div",{className:"wpshelf-muted",children:e.notes})]}),(0,u.jsx)("td",{children:"translate_as"===e.rule_type?(0,l.__)("Translate as…","gloty"):(0,l.__)("Never translate","gloty")}),(0,u.jsx)("td",{className:"wpshelf-muted",children:E(e)}),(0,u.jsx)("td",{children:(0,u.jsx)(y.ToggleControl,{__nextHasNoMarginBottom:!0,checked:!!e.is_active,disabled:N===e.id,onChange:t=>(async(e,t)=>{if(N!==e.id){C(e.id),o(s=>s.map(s=>s.id===e.id?{...s,is_active:t?1:0}:s));try{await m()({path:`/gloty/v1/glossary/${e.id}`,method:"PUT",data:{is_active:t?1:0}})}catch(e){s.error(e?.message||(0,l.__)("Could not update the term.","gloty")),await S()}finally{C(null)}}})(e,t),label:""})}),(0,u.jsxs)("td",{children:[(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>(e=>g({id:e.id,source_term:e.source_term||"",rule_type:"translate_as"===e.rule_type?"translate_as":"never_translate",case_sensitive:!!e.case_sensitive,notes:e.notes||"",translations:e.translations&&"object"==typeof e.translations?{...e.translations}:{}}))(e),children:(0,l.__)("Edit","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",isDestructive:!0,onClick:()=>v(e),children:(0,l.__)("Delete","gloty")})]})]},e.id))})]})]})]}),h&&(0,u.jsxs)(y.Modal,{title:h.id?(0,l.__)("Edit glossary term","gloty"):(0,l.__)("Add glossary term","gloty"),onRequestClose:()=>g(null),className:"wpshelf-glossary-modal",children:[(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Term","gloty"),value:h.source_term,onChange:e=>B("source_term",e),placeholder:(0,l.__)("e.g. Chanel N°5","gloty"),help:(0,l.__)("The exact brand or product name as it appears on your site.","gloty")})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.SelectControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Behavior","gloty"),value:h.rule_type,options:[{label:(0,l.__)("Never translate — keep it verbatim","gloty"),value:"never_translate"},{label:(0,l.__)("Translate as… — set it per language","gloty"),value:"translate_as"}],onChange:e=>B("rule_type",e)})}),"translate_as"===h.rule_type&&(0,u.jsx)("div",{className:"wpshelf-settings-field",children:0===i.length?(0,u.jsx)(y.Notice,{status:"info",isDismissible:!1,children:(0,l.__)("Add a target language first to set per-language values. Until then the term is kept verbatim.","gloty")}):i.map(e=>(0,u.jsx)(y.TextControl,{__nextHasNoMarginBottom:!0,label:k(e),value:h.translations?.[e]||"",onChange:s=>((e,s)=>g(t=>({...t,translations:{...t.translations,[e]:s}})))(e,s),placeholder:(0,l.__)("Leave blank to keep verbatim","gloty")},e))}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Case-sensitive match","gloty"),help:(0,l.__)("Only match the exact capitalization above. Leave off for most brands.","gloty"),checked:h.case_sensitive,onChange:e=>B("case_sensitive",e)})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Note (optional)","gloty"),value:h.notes,onChange:e=>B("notes",e)})}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:8,marginTop:16,justifyContent:"flex-end"},children:[(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>g(null),children:(0,l.__)("Cancel","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{if(!h)return;const e=(h.source_term||"").trim();if(!e)return void s.error((0,l.__)("Enter a term first.","gloty"));const t={source_term:e,rule_type:h.rule_type,case_sensitive:h.case_sensitive?1:0,notes:h.notes||"",translations:"translate_as"===h.rule_type?h.translations:{}};f(!0);try{h.id?(await m()({path:`/gloty/v1/glossary/${h.id}`,method:"PUT",data:t}),s.success((0,l.__)("Term updated.","gloty"))):(await m()({path:"/gloty/v1/glossary",method:"POST",data:t}),s.success((0,l.__)("Term added.","gloty"))),g(null),await S()}catch(e){s.error(e?.message||(0,l.__)("Could not save the term.","gloty"))}finally{f(!1)}},isBusy:p,disabled:p,children:h.id?(0,l.__)("Save changes","gloty"):(0,l.__)("Add term","gloty")})]})]}),x&&(0,u.jsx)(ie,{title:(0,l.__)("Remove glossary term","gloty"),message:(M=x.source_term,(0,l.__)("This term will be translated normally again on future syncs.","gloty").concat(M?` (“${M}”)`:"")),confirmLabel:(0,l.__)("Remove term","gloty"),busy:j,onConfirm:async()=>{if(x){b(!0);try{await m()({path:`/gloty/v1/glossary/${x.id}`,method:"DELETE"}),s.success((0,l.__)("Term removed.","gloty")),v(null),await S()}catch(e){s.error(e?.message||(0,l.__)("Could not remove the term.","gloty"))}finally{b(!1)}}},onCancel:()=>v(null)})]});var M}function as(e){if(!e)return"";const s=(Date.now()-e)/1e3;return s<60?(0,l.__)("just now","gloty"):s<3600?Math.floor(s/60)+(0,l.__)("m ago","gloty"):s<86400?Math.floor(s/3600)+(0,l.__)("h ago","gloty"):Math.floor(s/86400)+(0,l.__)("d ago","gloty")}function ls({onNavigate:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(null),r=(0,n.useRef)(!0),o=(0,n.useCallback)(async()=>{try{const e=await m()({path:"/gloty/v1/issues",parse:!0});r.current&&(t(e?.count||{error:0,warning:0,info:0}),i(Date.now()))}catch{}},[]);(0,n.useEffect)(()=>{r.current=!0,o();const e=window.setInterval(o,6e4),s=()=>{"visible"===document.visibilityState&&o()};return document.addEventListener("visibilitychange",s),window.addEventListener("gloty-license-refresh",o),()=>{r.current=!1,window.clearInterval(e),document.removeEventListener("visibilitychange",s),window.removeEventListener("gloty-license-refresh",o)}},[o]);const[,c]=(0,n.useReducer)(e=>e+1,0);(0,n.useEffect)(()=>{const e=window.setInterval(c,3e4);return()=>window.clearInterval(e)},[]);const d=function(e){return e?(e.error||0)>0?{tone:"error",label:(0,l.__)("Disconnected","gloty")}:(e.warning||0)>0?{tone:"warning",label:(0,l.__)("Degraded","gloty")}:{tone:"ok",label:(0,l.__)("Connected","gloty")}:{tone:"loading",label:(0,l.__)("Checking…","gloty")}}(s),h=s&&"ok"!==d.tone&&"loading"!==d.tone?` (${(s.error||0)+(s.warning||0)})`:"";return(0,u.jsxs)("button",{type:"button",className:`wpshelf-health-pill wpshelf-health-pill--${d.tone}`,onClick:()=>e&&e("dashboard"),"aria-label":(0,l.__)("Connection health — click to view details","gloty"),title:(0,l.__)("Connection health. Click to jump to the Overview tab.","gloty"),children:[(0,u.jsx)("span",{className:"wpshelf-health-pill__dot","aria-hidden":"true"}),(0,u.jsxs)("span",{className:"wpshelf-health-pill__label",children:[d.label,h]}),a&&(0,u.jsx)("span",{className:"wpshelf-health-pill__time",children:as(a)})]})}const ns={error:"⚠",warning:"⚠",info:"ℹ"},is={error:(0,l.__)("Critical","gloty"),warning:(0,l.__)("Warning","gloty"),info:(0,l.__)("Info","gloty")};function rs({issue:e,onNavigate:s}){const t=e.severity||"info";return(0,u.jsxs)("li",{className:`wpshelf-issue wpshelf-issue--${t}`,children:[(0,u.jsx)("span",{className:"wpshelf-issue__icon","aria-hidden":"true",children:ns[t]}),(0,u.jsxs)("div",{className:"wpshelf-issue__body",children:[(0,u.jsxs)("div",{className:"wpshelf-issue__title",children:[(0,u.jsxs)("span",{className:"screen-reader-text",children:[is[t],":"]}),e.title]}),e.detail&&(0,u.jsx)("div",{className:"wpshelf-issue__detail wpshelf-muted",children:e.detail})]}),e.action&&s&&(0,u.jsx)(y.Button,{variant:"error"===t?"primary":"secondary",isSmall:!0,onClick:()=>s(e.action.view,e.action.filters||null),children:e.action.label})]})}function os({onNavigate:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(!0),[r,o]=(0,n.useState)(null),c=(0,n.useCallback)(async()=>{i(!0),o(null);try{const e=await m()({path:"/gloty/v1/issues",parse:!0});t(e)}catch(e){o(e?.message||(0,l.__)("Could not load issues.","gloty"))}finally{i(!1)}},[]);if((0,n.useEffect)(()=>{c()},[c]),a&&!s)return null;if(r)return null;const d=s?.count||{error:0,warning:0,info:0},h=d.error+d.warning+d.info,g=s?.issues||[];let _=(0,l.__)("Needs attention","gloty");return 0===h?_=(0,l.__)("All clear","gloty"):d.error>0?_=(0,l.sprintf)(/* translators: %d: number of critical issues */ /* translators: %d: number of critical issues */22 (0,l._n)("Needs attention · %d critical issue","Needs attention · %d critical issues",d.error,"gloty"),d.error):d.warning>0&&( _=(0,l.sprintf)(/* translators: %d: number of warnings */ /* translators: %d: number of warnings */23 (0,l._n)("Needs attention · %d warning","Needs attention · %d warnings",d.warning,"gloty"),d.warning)),(0, u.jsxs)(y.Card,{className:"wpshelf-issues-card wpshelf-mb "+(d.error>0?"wpshelf-issues-card--error":d.warning>0?"wpshelf-issues-card--warning":""),role:"region","aria-label":(0,l.__)("System health","gloty"),children:[(0,u.jsxs)(y.CardHeader,{children:[(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:_}),(0,u.jsx)(y.Button,{variant:"tertiary",size:"small",onClick:c,disabled:a,isBusy:a,"aria-live":"polite",children:a?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]}),(0,u.jsx)(y.CardBody,{children:0===h?(0,u.jsx)("p",{className:"wpshelf-muted",style:{margin:0},children:(0,l.__)("No issues detected. Translator service is reachable and your license is in good standing.","gloty")}):(0,u.jsx)("ul",{className:"wpshelf-issues",children:g.map(s=>(0,u.jsx)(rs,{issue:s,onNavigate:e},s.id))})})]})}function cs(e){return Qe(e)?.name||e}function ds({code:e}){const s=function(e,s=es){const t=String(e||"").toLowerCase();if(!t)return null;const a=Object.keys(s).find(e=>e.toLowerCase()===t);return a?{code:a,kind:s[a].kind,variants:s[a].variants||[]}:null}(e);if(!s)return null;const t=function(e){const s=cs(e.code);if("ambiguous"===e.kind){const t=e.variants.map(e=>`${cs(e)} (${e})`);return(0,l.sprintf)(/* translators: 1: language name, 2: code, 3: one regional variant, 4: another */ /* translators: 1: language name, 2: code, 3: one regional variant, 4: another */16 (0,l.__)("%s characters, once","gloty"),s)}function je(e){const s=String(e||"");return/not available for purchase|not configured|stripe/i.test(s)?{status:"warning",message:(0,l.__)("Plan upgrades aren’t available on this server — billing isn’t configured. Translations keep working on your current plan.","gloty")}:{status:"error",message:s||(0,l.__)("Could not create checkout session.","gloty")}}function be(e){let s=null;try{s=window.open(e,"_blank")}catch{s=null}return s?null:{status:"warning",message:(0,l.__)("Your browser blocked the checkout tab. Allow pop-ups for this site and press Upgrade again.","gloty")}}function Ne({used:e,limit:s}){const t=s>0?Math.min(100,Math.round(e/s*100)):0,a=he(t),n=(0,l.sprintf)(/* translators: 1: characters used, 2: character limit, 3: percentage used. */ /* translators: 1: characters used, 2: character limit, 3: percentage used. */ 17 (0,l.__)("%1$s / %2$s characters (%3$d%%)","gloty"),e.toLocaleString(),s.toLocaleString(),t);return(0,_.jsxs)("div",{className:"wpshelf-usage-bar",children:[(0,_.jsx)("div",{className:"wpshelf-usage-bar__track",role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":t,"aria-label":n,children:(0,_.jsx)("div",{className:"wpshelf-usage-bar__fill"+(a?` wpshelf-usage-bar__fill--${a}`:""),style:{width:`${t}%`}})}),(0,_.jsx)("span",{className:"wpshelf-usage-bar__label",children:n})]})}function Ce({slug:e}){return(0,_.jsx)("span",{className:"wpshelf-plan-badge",children:e||"free"})}function Se({boot:e}){const[s,t]=(0,n.useState)(""),[a,i]=(0,n.useState)(e?.connection?.accountEmail||""),[r,o]=(0,n.useState)(e?.connection?.accountName||""),[c,d]=(0,n.useState)("getStarted"),[h,g]=(0,n.useState)(e?.license?.status||null),[u,p]=(0,n.useState)(e?.license?.hasKey||!1),[m,w]=(0,n.useState)(e?.license?.keyMasked||""),[x,v]=(0,n.useState)(e?.license?.keyRefused||!1),[j,b]=(0,n.useState)(!1),[N,C]=(0,n.useState)(!1),[S,k]=(0,n.useState)(null),[T,B]=(0,n.useState)(!1),[E,L]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=!0;return fe().then(s=>{e&&L(s)}),()=>{e=!1}},[]);const M=(0,n.useCallback)(async(e=!1)=>{C(!0);try{const s=e?"/gloty/v1/license/status?force=1":"/gloty/v1/license/status",t=await y()({path:s});p(t?.has_key||!1),g(t?.status||null),v(t?.key_refused||!1),t?.key_masked&&w(t.key_masked),window.dispatchEvent(new CustomEvent("gloty-license-checked",{detail:t?.status||null}))}catch{}finally{C(!1)}},[]);(0,n.useEffect)(()=>{const e=()=>{M(!0)};return window.addEventListener("gloty-license-refresh",e),()=>window.removeEventListener("gloty-license-refresh",e)},[M]),(0,n.useEffect)(()=>{u&&!h&&M()},[u,h,M]);const A=async()=>{if(s.trim()){b(!0),k(null);try{const e=await y()({path:"/gloty/v1/license/activate",method:"POST",data:{license_key:s.trim()}});e?.ok?(p(!0),v(!1),t(""),k({status:"success",message:(0,l.__)("License activated.","gloty")}),await M()):k({status:"error",message:e?.message||(0,l.__)("Activation failed.","gloty")})}catch(e){k({status:"error",message:e?.message||(0,l.__)("Activation failed.","gloty")})}finally{b(!1)}}},D=e=>{const s=String(e||""),t=/no stripe customer|not configured|not found|stripe/i.test(s);k(t?{status:"warning",message:(0,l.__)("No billing portal is available for this license — there’s no Stripe subscription to manage. This is normal for free or manually-granted plans.","gloty")}:{status:"error",message:s||(0,l.__)("Could not open the billing portal.","gloty")})},R=we(h,E);return(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsxs)("h3",{className:"wpshelf-settings-card__title",children:[(0,l.__)("License","gloty"),h&&(0,_.jsx)(Ce,{slug:h.plan_slug})]})}),(0,_.jsxs)(f.CardBody,{children:[S&&(0,_.jsx)(f.Notice,{status:S.status,isDismissible:!0,onDismiss:()=>k(null),className:"wpshelf-mb",children:S.message}),!u&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Get started with Gloty translation credits, or enter an existing license key.","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-license-tabs",style:{display:"flex",gap:12,marginBottom:16},children:[(0,_.jsx)(f.Button,{variant:"getStarted"===c?"primary":"secondary",isSmall:!0,onClick:()=>d("getStarted"),children:(0,l.__)("Get Started","gloty")}),(0,_.jsx)(f.Button,{variant:"existingKey"===c?"primary":"secondary",isSmall:!0,onClick:()=>d("existingKey"),children:(0,l.__)("I have a license key","gloty")})]}),"getStarted"===c&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{label:(0,l.__)("Email","gloty"),value:a,onChange:i,type:"email",__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{label:(0,l.__)("Name","gloty"),value:r,onChange:o,__nextHasNoMarginBottom:!0})}),(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{if(a.trim()&&r.trim()){b(!0),k(null);try{const e=await y()({path:"/gloty/v1/license/provision",method:"POST",data:{email:a.trim(),name:r.trim()}});e?.ok?(p(!0),k({status:"success",message:(0,l.__)("License provisioned and activated.","gloty")}),await M(!0)):k({status:"error",message:e?.message||(0,l.__)("Provisioning failed.","gloty")})}catch(e){k({status:"error",message:e?.message||(0,l.__)("Provisioning failed.","gloty")})}finally{b(!1)}}},isBusy:j,disabled:j||!a.trim()||!r.trim(),children:(0,l.__)("Get Free License","gloty")})]}),"existingKey"===c&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{label:(0,l.__)("License Key","gloty"),value:s,onChange:t,placeholder:"GLOTY-XXXX-XXXX-XXXX-XXXX",__nextHasNoMarginBottom:!0})}),(0,_.jsx)(f.Button,{variant:"primary",onClick:A,isBusy:j,disabled:j||!s.trim(),children:(0,l.__)("Activate","gloty")})]})]}),u&&h&&(0,_.jsxs)("div",{className:"wpshelf-license-details",children:[m&&(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("License key","gloty")}),(0,_.jsx)("code",{className:"wpshelf-license-key-masked",children:m})]}),(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Plan","gloty")}),(0,_.jsx)("span",{children:h.plan_name||"—"})]}),(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Status","gloty")}),(0,_.jsx)("span",{children:h.status||"—"})]}),(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Sites","gloty")}),(0,_.jsxs)("span",{children:[h.activations_used," / ",h.site_limit]})]}),(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Usage","gloty")}),(0,_.jsx)(Ne,{used:h.characters_used,limit:h.characters_limit})]}),h.characters_limit>0&&(0,_.jsx)("p",{className:"wpshelf-license-usage-note wpshelf-muted",children:h.characters_used/h.characters_limit>=.8?(0,l.__)("You’re approaching your monthly limit. Translation pauses at 100% until the limit resets or you upgrade — existing translations keep serving.","gloty"):(0,l.__)("Translation pauses when you reach your monthly limit, then resumes after it resets or you upgrade. Already-stored translations always keep serving.","gloty")}),h.period_end&&(0,_.jsxs)("div",{className:"wpshelf-license-row",children:[(0,_.jsx)("span",{className:"wpshelf-license-label",children:(0,l.__)("Resets","gloty")}),(0,_.jsx)("span",{children:new Date(h.period_end).toLocaleDateString()})]}),R.length>0&&(0,_.jsxs)("div",{className:"wpshelf-license-plans",children:[(0,_.jsx)("h4",{className:"wpshelf-license-plans__title",children:(0,l.__)("Upgrade","gloty")}),(0,_.jsx)("ul",{className:"wpshelf-license-plans__list",children:R.map(e=>(0,_.jsxs)("li",{className:"wpshelf-license-plans__item",children:[(0,_.jsxs)("div",{children:[(0,_.jsx)("strong",{children:e.name})," ",(0,_.jsx)("span",{className:"wpshelf-muted",children:xe(e)}),(0,_.jsxs)("div",{className:"wpshelf-muted wpshelf-license-plans__meta",children:[ve(e)," · ",1===e.siteLimit?(0,l.__)("1 site","gloty"):(0,l.sprintf)(/* translators: %d: number of sites */ /* translators: %d: number of sites */ 18 (0,l.__)("Up to %d sites","gloty"),e.siteLimit)]})]}),(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>(async e=>{b(!0),k(null);try{const s=await y()({path:"/gloty/v1/license/checkout",method:"POST",data:{plan_slug:e}});k(s?.url?be(s.url):je(s?.message))}catch(e){k(je(e?.message))}finally{b(!1)}})(e.slug),isBusy:j,disabled:j,children:e.renews?(0,l.__)("Upgrade","gloty"):(0,l.__)("Buy","gloty")})]},e.slug))})]}),(0,_.jsxs)("div",{className:"wpshelf-license-actions",children:[h.has_billing&&(0,_.jsx)(f.Button,{variant:"secondary",onClick:async()=>{b(!0),k(null);try{const e=await y()({path:"/gloty/v1/license/portal"});e?.url?window.open(e.url,"_blank","noopener,noreferrer"):D(e?.message)}catch(e){D(e?.message)}finally{b(!1)}},isBusy:j,disabled:j,children:(0,l.__)("Manage Subscription","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>M(!0),disabled:j||N,isBusy:N,"aria-live":"polite",children:N?(0,l.__)("Checking…","gloty"):(0,l.__)("Refresh status","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",isDestructive:!0,onClick:()=>B(!0),disabled:j,children:(0,l.__)("Deactivate","gloty")})]}),(0,_.jsx)("p",{className:"wpshelf-license-deactivate-note wpshelf-muted",children:(0,l.__)("Deactivating frees this license for another site. Your translations stay in place — nothing is deleted.","gloty")})]}),T&&(0,_.jsx)(re,{title:(0,l.__)("Deactivate license on this site?","gloty"),message:(0,l.__)("This frees the license seat for use on another site. Your stored translations stay in place and keep serving, but new translations stop until you reactivate. Nothing is deleted.","gloty"),confirmLabel:(0,l.__)("Deactivate","gloty"),busy:j,onConfirm:()=>{B(!1),(async()=>{b(!0),k(null);try{await y()({path:"/gloty/v1/license/deactivate",method:"POST"}),p(!1),g(null),v(!1),k({status:"info",message:(0,l.__)("License deactivated.","gloty")})}catch(e){k({status:"error",message:e?.message||(0,l.__)("Deactivation failed.","gloty")})}finally{b(!1)}})()},onCancel:()=>B(!1)}),u&&!h&&x&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsxs)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mb",children:[(0,_.jsx)("p",{children:(0,_.jsx)("strong",{children:(0,l.__)("This license key is no longer accepted.","gloty")})}),(0,_.jsxs)("p",{children:[(0,l.__)("Translations keep running, but usage is not recorded against your plan. If you were sent a replacement key, or can see one in your WP Shelf account, paste it here and activate it.","gloty")," ",(0,_.jsx)("a",{href:"https://wp-shelf.com/dashboard/licenses",target:"_blank",rel:"noopener noreferrer",children:(0,l.__)("Open your WP Shelf licenses","gloty")})]})]}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{label:(0,l.__)("Replacement license key","gloty"),value:s,onChange:t,placeholder:"GLOTY-XXXX-XXXX-XXXX-XXXX",__nextHasNoMarginBottom:!0})}),(0,_.jsx)(f.Button,{variant:"primary",onClick:A,isBusy:j,disabled:j||!s.trim(),children:(0,l.__)("Activate","gloty")})]}),u&&!h&&!x&&(0,_.jsxs)("p",{className:"wpshelf-muted",children:[m&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("code",{className:"wpshelf-license-key-masked",children:m})," — "]}),(0,l.__)("License key is configured but the license server could not be reached.","gloty"),(0,_.jsx)(f.Button,{variant:"link",onClick:()=>M(!0),disabled:N,isBusy:N,style:{marginLeft:8},"aria-live":"polite",children:N?(0,l.__)("Retrying…","gloty"):(0,l.__)("Retry","gloty")})]})]})]})}function ke({boot:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(!1),r=(0,n.useRef)(e?.license?.status||null);return(0,n.useEffect)(()=>{if("undefined"==typeof window)return;const e=new URL(window.location.href),s=e.searchParams.get("checkout");if(!s)return;if(e.searchParams.delete("checkout"),window.history.replaceState({},"",e.toString()),"cancel"===s)return void t({status:"info",message:(0,l.__)("Checkout closed — nothing was charged. Pick a plan below whenever you’re ready.","gloty")});if("success"!==s)return;i(!0),t({status:"info",message:(0,l.__)("Payment received. Waiting for Stripe to confirm it — your plan and allowance update here as soon as it does.","gloty")});let a=0;const n=()=>window.dispatchEvent(new CustomEvent("gloty-license-refresh"));n();const r=window.setInterval(()=>{if(a+=1,a>=12)return window.clearInterval(r),i(!1),void t({status:"warning",message:(0,l.__)("Payment received, but Stripe has not confirmed it here yet. Nothing is lost — use Refresh status in a few minutes, and contact support if your new plan still is not shown.","gloty")});n()},5e3);return()=>window.clearInterval(r)},[]),(0,n.useEffect)(()=>{if(!a)return;const e=e=>{var s,a;s=r.current,(a=e.detail)&&(s?a.has_billing&&!s.has_billing||a.plan_slug!==s.plan_slug||(a.characters_limit??0)>(s.characters_limit??0):Boolean(a.has_billing))&&(i(!1),t({status:"success",message:(0,l.__)("Checkout complete — your plan and allowance are up to date.","gloty")}))};return window.addEventListener("gloty-license-checked",e),()=>window.removeEventListener("gloty-license-checked",e)},[a]),(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-billing-screen",role:"region","aria-label":(0,l.__)("Billing","gloty"),children:[(0,_.jsxs)("p",{className:"wpshelf-screen__lead",children:[(0,l.__)("Manage your Gloty license, view plan usage, and update your subscription.","gloty")," ",(0,_.jsx)(f.ExternalLink,{href:"https://wp-shelf.com/gloty#pricing",children:(0,l.__)("Compare plans and pricing","gloty")})]}),s&&(0,_.jsx)(f.Notice,{status:s.status,isDismissible:!0,onDismiss:()=>t(null),className:"wpshelf-mb",children:s.message}),(0,_.jsx)(Se,{boot:e})]})}const Te=(0,n.createContext)(null),Be={success:"✓",error:"!",info:"i"};let Ee=0;function Le({children:e}){const[s,t]=(0,n.useState)([]),a=(0,n.useCallback)((e,s="success",a=4e3)=>{const l=++Ee;t(t=>[...t,{id:l,message:e,status:s}]),a>0&&window.setTimeout(()=>{t(e=>e.filter(e=>e.id!==l))},a)},[]),l=(0,n.useCallback)(e=>{t(s=>s.filter(s=>s.id!==e))},[]),i={success:e=>a(e,"success"),error:e=>a(e,"error",6e3),info:e=>a(e,"info"),add:a,dismiss:l};return(0,_.jsxs)(Te.Provider,{value:i,children:[e,(0,_.jsx)(Ae,{toasts:s,onDismiss:l})]})}function Me(){return(0,n.useContext)(Te)}function Ae({toasts:e,onDismiss:s}){return 0===e.length?null:(0,_.jsx)("div",{className:"wpshelf-toast-container","aria-live":"polite",children:e.map(e=>(0,_.jsxs)("div",{className:`wpshelf-toast wpshelf-toast--${e.status}`,role:"status",children:[(0,_.jsx)("span",{className:"wpshelf-toast__icon","aria-hidden":"true",children:Be[e.status]??Be.info}),(0,_.jsx)("span",{className:"wpshelf-toast__message",children:e.message}),(0,_.jsx)("button",{className:"wpshelf-toast__close",onClick:()=>s(e.id),"aria-label":(0,l.__)("Dismiss","gloty"),children:"×"})]},e.id))})}const De=[{label:"Surface",tokens:["--wpshelf-bg","--wpshelf-surface","--wpshelf-surface-alt"]},{label:"Ink",tokens:["--wpshelf-ink","--wpshelf-ink-soft","--wpshelf-muted"]},{label:"Line",tokens:["--wpshelf-line","--wpshelf-line-soft"]},{label:"Fill (primary action)",tokens:["--wpshelf-fill","--wpshelf-fill-hover","--wpshelf-fill-ink"]},{label:"Accent",tokens:["--wpshelf-accent","--wpshelf-accent-dark","--wpshelf-accent-50","--wpshelf-accent-100"]},{label:"Success",tokens:["--wpshelf-success","--wpshelf-success-dark","--wpshelf-success-50"]},{label:"Warning",tokens:["--wpshelf-warn","--wpshelf-warn-dark","--wpshelf-warn-50"]},{label:"Danger",tokens:["--wpshelf-danger","--wpshelf-danger-50"]}],Re=["--wpshelf-text-2xs","--wpshelf-text-xs","--wpshelf-text-sm","--wpshelf-text-base","--wpshelf-text-md","--wpshelf-text-lg","--wpshelf-text-xl","--wpshelf-text-2xl","--wpshelf-text-stat-md","--wpshelf-text-stat-lg"],Oe=["--wpshelf-space-1","--wpshelf-space-2","--wpshelf-space-3","--wpshelf-space-4","--wpshelf-space-5","--wpshelf-space-6","--wpshelf-space-7","--wpshelf-space-8","--wpshelf-space-10","--wpshelf-space-14","--wpshelf-space-16"],Pe=["--wpshelf-radius-xs","--wpshelf-radius-sm","--wpshelf-radius","--wpshelf-radius-lg","--wpshelf-radius-pill"],$e=["--wpshelf-shadow","--wpshelf-shadow-hover","--wpshelf-shadow-overlay","--wpshelf-shadow-brand","--wpshelf-shadow-mark"],Ie=["not_translated","pending","processing","synced","stale","failed","manually_edited"],He=["queued","processing","completed","cancelled","paused"],Ge=[{tone:"loading",label:(0,l.__)("Checking…","gloty")},{tone:"ok",label:(0,l.__)("Connected","gloty")},{tone:"warning",label:(0,l.__)("Degraded","gloty")},{tone:"error",label:(0,l.__)("Disconnected","gloty")}],ze=[{key:"welcome",label:(0,l.__)("Welcome","gloty")},{key:"connection",label:(0,l.__)("Connection","gloty")},{key:"languages",label:(0,l.__)("Languages","gloty")},{key:"scan",label:(0,l.__)("Content scan","gloty")},{key:"done",label:(0,l.__)("Ready","gloty")}];function Fe(e){const[s,t]=(0,n.useState)("");return(0,n.useEffect)(()=>{if("undefined"==typeof window)return;const s=window.getComputedStyle(document.documentElement).getPropertyValue(e).trim();t(s)},[e]),s}function Ve({name:e}){const s=Fe(e);return(0,_.jsxs)("div",{className:"wpshelf-ds-swatch",children:[(0,_.jsx)("div",{className:"wpshelf-ds-swatch__chip",style:{background:`var(${e})`}}),(0,_.jsx)("code",{className:"wpshelf-ds-swatch__name",children:e}),(0,_.jsx)("span",{className:"wpshelf-ds-swatch__value",children:s||"—"})]})}function Ue({name:e}){const s=Fe(e);return(0,_.jsxs)("div",{className:"wpshelf-ds-type-row",children:[(0,_.jsx)("span",{style:{fontSize:`var(${e})`,lineHeight:1.1},children:(0,l.__)("The quick brown fox","gloty")}),(0,_.jsxs)("span",{className:"wpshelf-ds-type-row__meta",children:[(0,_.jsx)("code",{children:e})," · ",s||"—"]})]})}function qe({name:e}){const s=Fe(e);return(0,_.jsxs)("div",{className:"wpshelf-ds-space-row",children:[(0,_.jsx)("span",{className:"wpshelf-ds-space-row__bar",style:{width:`var(${e})`}}),(0,_.jsx)("code",{children:e}),(0,_.jsx)("span",{className:"wpshelf-ds-swatch__value",children:s||"—"})]})}function We(){const e=Me(),[s,t]=(0,n.useState)(!1),[a,i]=(0,n.useState)(!1);return(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-ds",role:"region","aria-label":(0,l.__)("Design system preview","gloty"),children:[(0,_.jsx)(se,{title:(0,l.__)("Design system","gloty"),subtitle:(0,l.__)("Live catalog of every token and shared primitive. Source of truth: docs/design-system/. This screen is developer-facing and hidden from customers.","gloty")}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Color tokens","gloty")}),De.map(e=>(0,_.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,_.jsx)("div",{className:"wpshelf-ds-group__label",children:e.label}),(0,_.jsx)("div",{className:"wpshelf-ds-swatch-grid",children:e.tokens.map(e=>(0,_.jsx)(Ve,{name:e},e))})]},e.label)),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Type scale","gloty")}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsx)(f.CardBody,{children:Re.map(e=>(0,_.jsx)(Ue,{name:e},e))})}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Spacing scale","gloty")}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsx)(f.CardBody,{children:Oe.map(e=>(0,_.jsx)(qe,{name:e},e))})}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Radius & elevation","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,_.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Radius","gloty")}),(0,_.jsx)("div",{className:"wpshelf-ds-cluster",children:Pe.map(e=>(0,_.jsxs)("div",{className:"wpshelf-ds-radius-box",children:[(0,_.jsx)("div",{className:"wpshelf-ds-radius-box__shape",style:{borderRadius:`var(${e})`}}),(0,_.jsx)("code",{children:e})]},e))})]}),(0,_.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,_.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Shadow","gloty")}),(0,_.jsx)("div",{className:"wpshelf-ds-cluster",children:$e.map(e=>(0,_.jsxs)("div",{className:"wpshelf-ds-shadow-box",children:[(0,_.jsx)("div",{className:"wpshelf-ds-shadow-box__shape",style:{boxShadow:`var(${e})`}}),(0,_.jsx)("code",{children:e})]},e))})]}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Status vocabulary","gloty")}),(0,_.jsxs)(f.Card,{className:"wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Translation statuses","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-ds-cluster wpshelf-mb",children:Ie.map(e=>(0,_.jsx)(Q,{status:e},e))}),(0,_.jsx)(ee,{statuses:Ie})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Job / scan statuses","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)("div",{className:"wpshelf-ds-cluster",children:He.map(e=>(0,_.jsx)(Q,{status:e},e))})})]}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Stat cards","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--translated",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Translated","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:"128"}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("of 240 source strings","gloty")})]})}),(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--pending",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Pending","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:"12"}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("awaiting dispatch","gloty")})]})}),(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--stale",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Stale","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:"4"}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("source content changed","gloty")})]})})]}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Progress bar","gloty")}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted wpshelf-mb",children:(0,l.__)('scale="usage" — a full bar is bad (quota, rate limit).',"gloty")}),(0,_.jsx)(_e,{value:3,max:240,label:"3 of 240"}),(0,_.jsx)(_e,{value:180,max:240,label:"180 of 240 (warn ≥75%)"}),(0,_.jsx)(_e,{value:232,max:240,label:"232 of 240 (danger ≥90%)"}),(0,_.jsx)(_e,{value:240,max:240,tone:"success",label:"Complete"})]})}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted wpshelf-mb",children:(0,l.__)('scale="completion" — a full bar is good (translation coverage). The inverse of the scale above, which is why the meaning is declared at the call site rather than inferred from the number.',"gloty")}),(0,_.jsx)(_e,{value:18,max:240,scale:"completion",label:"8% (danger <34%)"}),(0,_.jsx)(_e,{value:120,max:240,scale:"completion",label:"50% (warn ≥34%)"}),(0,_.jsx)(_e,{value:228,max:240,scale:"completion",label:"95% (success ≥67%)"})]})}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Feedback states","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-ds-states",children:[(0,_.jsxs)(f.Card,{children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Loading","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)(ce,{text:(0,l.__)("Loading translations…","gloty")})})]}),(0,_.jsxs)(f.Card,{children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Empty","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)(ie,{icon:"🌐",title:(0,l.__)("No target languages","gloty"),hint:(0,l.__)("Enable at least one language to start translating your site.","gloty")})})]}),(0,_.jsxs)(f.Card,{children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Error","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,children:(0,l.__)("Could not connect to the translator service. Check that your API key is valid in Settings → Connection.","gloty")})})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-mt wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Table skeleton","gloty")})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)(de,{rows:3,headers:[(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Updated","gloty")]})})]}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Navigation","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-ds-group",children:[(0,_.jsx)("div",{className:"wpshelf-ds-group__label",children:(0,l.__)("Health pill","gloty")}),(0,_.jsx)("div",{className:"wpshelf-ds-cluster",children:Ge.map(e=>(0,_.jsxs)("span",{className:`wpshelf-health-pill wpshelf-health-pill--${e.tone}`,children:[(0,_.jsx)("span",{className:"wpshelf-health-pill__dot","aria-hidden":"true"}),(0,_.jsx)("span",{className:"wpshelf-health-pill__label",children:e.label})]},e.tone))})]}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)(pe,{steps:ze,current:2}),(0,_.jsx)(me,{items:[{key:"connection",title:(0,l.__)("Site connected to Gloty","gloty"),done:!0},{key:"languages",title:(0,l.__)("Target languages enabled","gloty"),done:!0},{key:"scan",title:(0,l.__)("Initial content scan started","gloty"),done:!1}]})]})}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Chips & buttons","gloty")}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsxs)("div",{className:"wpshelf-ds-cluster wpshelf-mb",children:[(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success",children:"success"}),(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--warn",children:"warn"}),(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--error",children:"error"}),(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--info",children:"info"}),(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--muted",children:"muted"}),(0,_.jsx)("span",{className:"wpshelf-chip",children:"neutral"})]}),(0,_.jsxs)("div",{className:"wpshelf-ds-cluster",children:[(0,_.jsx)(f.Button,{variant:"primary",children:(0,l.__)("Primary","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",children:(0,l.__)("Secondary","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",children:(0,l.__)("Tertiary","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",isDestructive:!0,children:(0,l.__)("Destructive","gloty")}),(0,_.jsx)(f.Button,{variant:"link",children:(0,l.__)("Link","gloty")})]})]})}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Overlays","gloty")}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsx)(f.CardBody,{children:(0,_.jsxs)("div",{className:"wpshelf-ds-cluster",children:[(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>e.success((0,l.__)("Settings saved.","gloty")),children:(0,l.__)("Success toast","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>e.error((0,l.__)("Could not save changes.","gloty")),children:(0,l.__)("Error toast","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>e.info((0,l.__)("Scan started in background.","gloty")),children:(0,l.__)("Info toast","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>t(!0),children:(0,l.__)("Open confirm modal","gloty")})]})})}),s&&(0,_.jsx)(re,{title:(0,l.__)("Delete translations","gloty"),message:(0,l.__)("Delete 3 cached translations? They may be regenerated later.","gloty"),confirmLabel:(0,l.__)("Delete","gloty"),busy:a,onConfirm:()=>{i(!0),window.setTimeout(()=>{i(!1),t(!1),e.success((0,l.__)("Deleted 3 translations.","gloty"))},900)},onCancel:()=>t(!1)})]})}function Xe({boot:e,onNavigate:s}){const t=e?.firstTranslation||{},a=e?.siteUrl||window?.location?.origin||"",i=e?.routing?.url_structure||"subdirectory",[r,o]=(0,n.useState)(!!t.dismissedAt),[c,d]=(0,n.useState)(!1);if(!(0,n.useMemo)(()=>!r&&!!t.at&&function(e){if(!e)return 1/0;const s=String(e).replace(" ","T")+"Z",t=Date.parse(s);return Number.isNaN(t)?1/0:(Date.now()-t)/36e5}(t.at)<48,[r,t.at]))return null;const h=t.lang||"",g=h?h.toUpperCase():"",u=(()=>{if(!h)return a||"/";if("parameter"===i){const e=a.includes("?")?"&":"?";return`${a}${e}lang=${encodeURIComponent(h)}`}return`${a.replace(/\/$/,"")}/${encodeURIComponent(h)}/`})();return(0,_.jsx)(f.Card,{className:"wpshelf-first-translation wpshelf-mb",role:"region","aria-label":(0,l.__)("First translation welcome","gloty"),children:(0,_.jsx)(f.CardBody,{children:(0,_.jsxs)("div",{className:"wpshelf-first-translation__body",children:[(0,_.jsxs)("div",{className:"wpshelf-first-translation__text",children:[(0,_.jsx)("h2",{className:"wpshelf-first-translation__title",children:g?(0,l.sprintf)(/* translators: %s: language code, e.g. FR */ /* translators: %s: language code, e.g. FR */ 19 (0,l.__)("🎉 Your first %s translation is live","gloty"),g):(0,l.__)("🎉 Your first translation is live","gloty")}),(0,_.jsx)("p",{className:"wpshelf-first-translation__hint wpshelf-muted",children:(0,l.__)("Open the front end in the target language to see it in place. Share the preview link with your team so they can review.","gloty")})]}),(0,_.jsxs)("div",{className:"wpshelf-first-translation__actions",children:[(0,_.jsx)(f.Button,{variant:"primary",href:u,target:"_blank",rel:"noreferrer",children:g?(0,l.sprintf)(/* translators: %s: language code */ /* translators: %s: language code */ 20 (0,l.__)("View site in %s","gloty"),g):(0,l.__)("View translated site","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:async()=>{try{await navigator.clipboard.writeText(u),d(!0),window.setTimeout(()=>d(!1),2e3)}catch{window.prompt((0,l.__)("Copy this link:","gloty"),u)}},children:c?(0,l.__)("Copied!","gloty"):(0,l.__)("Share with your team","gloty")}),s&&(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>s("translations"),children:(0,l.__)("Review translations","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",onClick:async()=>{o(!0);try{await y()({path:"/gloty/v1/first-translation/dismiss",method:"POST"})}catch{}},"aria-label":(0,l.__)("Dismiss welcome","gloty"),children:(0,l.__)("Dismiss","gloty")})]})]})})})}function Ye({position:e,total:s,step:t,onNavigate:a}){let n="wpshelf-gs__step--todo";return t.done?n="wpshelf-gs__step--done":t.active&&(n="wpshelf-gs__step--active"),(0,_.jsxs)("li",{className:`wpshelf-gs__step ${n}`,children:[(0,_.jsx)("span",{className:"wpshelf-gs__marker","aria-hidden":"true",children:t.done?"✓":e}),(0,_.jsxs)("div",{className:"wpshelf-gs__body",children:[(0,_.jsxs)("div",{className:"wpshelf-gs__title",children:[t.title,t.done&&(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success wpshelf-gs__badge",children:(0,l.__)("Done","gloty")})]}),(0,_.jsx)("p",{className:"wpshelf-gs__desc wpshelf-muted",children:t.description})]}),!t.done&&t.action&&a&&(0,_.jsx)("div",{className:"wpshelf-gs__action",children:(0,_.jsx)(f.Button,{variant:t.active?"primary":"secondary",onClick:()=>a(t.action.tab),children:t.action.label})}),e<s&&(0,_.jsx)("span",{className:"wpshelf-gs__connector","aria-hidden":"true"})]})}function Ze({hasLanguages:e,hasSource:s,hasTranslated:t,pendingCount:a=0,onNavigate:n}){if(t)return null;const i=[{key:"languages",done:e,title:(0,l.__)("Choose your languages","gloty"),description:(0,l.__)("Pick the languages you want your site translated into.","gloty"),action:{tab:"languages",label:e?(0,l.__)("Manage languages","gloty"):(0,l.__)("Add a language","gloty")}},{key:"scan",done:s,title:(0,l.__)("Scan your content","gloty"),description:(0,l.__)("Gloty collects every translatable piece of text on your site.","gloty"),action:{tab:"sync",label:s?(0,l.__)("Open Sync","gloty"):(0,l.__)("Run a scan","gloty")}},{key:"translate",done:t,title:(0,l.__)("Translate","gloty"),description:a>0?(0,l.sprintf)(/* translators: %s: number of pending strings */ /* translators: %s: number of pending strings */ 21 (0,l.__)("%s strings are ready — send them to your AI provider to translate.","gloty"),Number(a).toLocaleString()):(0,l.__)("Send collected strings to your AI provider to translate.","gloty"),action:{tab:"sync",label:(0,l.__)("Translate now","gloty")}}],r=i.findIndex(e=>!e.done);return i.forEach((e,s)=>{e.active=s===r}),(0,_.jsxs)(f.Card,{className:"wpshelf-getting-started wpshelf-mb",role:"region","aria-label":(0,l.__)("Getting started","gloty"),children:[(0,_.jsxs)(f.CardHeader,{children:[(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Get started with Gloty","gloty")}),(0,_.jsxs)("span",{className:"wpshelf-gs__flow wpshelf-muted","aria-hidden":"true",children:[(0,l.__)("Scan","gloty")," ","→"," ",(0,l.__)("Translate","gloty")," ","→"," ",(0,l.__)("Serve","gloty")]})]}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)("ol",{className:"wpshelf-gs__steps",children:i.map((e,s)=>(0,_.jsx)(Ye,{position:s+1,total:i.length,step:e,onNavigate:n},e.key))})})]})}const Je=[{code:"en",name:"English",native_name:"English"},{code:"es",name:"Spanish",native_name:"Español"},{code:"fr",name:"French",native_name:"Français"},{code:"de",name:"German",native_name:"Deutsch"},{code:"it",name:"Italian",native_name:"Italiano"},{code:"pt",name:"Portuguese",native_name:"Português"},{code:"nl",name:"Dutch",native_name:"Nederlands"},{code:"pl",name:"Polish",native_name:"Polski"},{code:"ru",name:"Russian",native_name:"Русский"},{code:"uk",name:"Ukrainian",native_name:"Українська"},{code:"cs",name:"Czech",native_name:"Čeština"},{code:"sk",name:"Slovak",native_name:"Slovenčina"},{code:"sl",name:"Slovenian",native_name:"Slovenščina"},{code:"hu",name:"Hungarian",native_name:"Magyar"},{code:"ro",name:"Romanian",native_name:"Română"},{code:"bg",name:"Bulgarian",native_name:"Български"},{code:"hr",name:"Croatian",native_name:"Hrvatski"},{code:"sr",name:"Serbian",native_name:"Српски"},{code:"bs",name:"Bosnian",native_name:"Bosanski"},{code:"mk",name:"Macedonian",native_name:"Македонски"},{code:"sq",name:"Albanian",native_name:"Shqip"},{code:"el",name:"Greek",native_name:"Ελληνικά"},{code:"tr",name:"Turkish",native_name:"Türkçe"},{code:"sv",name:"Swedish",native_name:"Svenska"},{code:"no",name:"Norwegian",native_name:"Norsk"},{code:"nb",name:"Norwegian Bokmål",native_name:"Norsk bokmål"},{code:"nn",name:"Norwegian Nynorsk",native_name:"Norsk nynorsk"},{code:"da",name:"Danish",native_name:"Dansk"},{code:"fi",name:"Finnish",native_name:"Suomi"},{code:"is",name:"Icelandic",native_name:"Íslenska"},{code:"et",name:"Estonian",native_name:"Eesti"},{code:"lv",name:"Latvian",native_name:"Latviešu"},{code:"lt",name:"Lithuanian",native_name:"Lietuvių"},{code:"ga",name:"Irish",native_name:"Gaeilge"},{code:"cy",name:"Welsh",native_name:"Cymraeg"},{code:"eu",name:"Basque",native_name:"Euskara"},{code:"ca",name:"Catalan",native_name:"Català"},{code:"gl",name:"Galician",native_name:"Galego"},{code:"mt",name:"Maltese",native_name:"Malti"},{code:"ja",name:"Japanese",native_name:"日本語"},{code:"ko",name:"Korean",native_name:"한국어"},{code:"zh",name:"Chinese",native_name:"中文"},{code:"vi",name:"Vietnamese",native_name:"Tiếng Việt"},{code:"th",name:"Thai",native_name:"ไทย"},{code:"lo",name:"Lao",native_name:"ລາວ"},{code:"km",name:"Khmer",native_name:"ខ្មែរ"},{code:"my",name:"Burmese",native_name:"မြန်မာ"},{code:"id",name:"Indonesian",native_name:"Bahasa Indonesia"},{code:"ms",name:"Malay",native_name:"Bahasa Melayu"},{code:"tl",name:"Tagalog",native_name:"Tagalog"},{code:"fil",name:"Filipino",native_name:"Filipino"},{code:"hi",name:"Hindi",native_name:"हिन्दी"},{code:"bn",name:"Bengali",native_name:"বাংলা"},{code:"ta",name:"Tamil",native_name:"தமிழ்"},{code:"te",name:"Telugu",native_name:"తెలుగు"},{code:"ml",name:"Malayalam",native_name:"മലയാളം"},{code:"kn",name:"Kannada",native_name:"ಕನ್ನಡ"},{code:"mr",name:"Marathi",native_name:"मराठी"},{code:"gu",name:"Gujarati",native_name:"ગુજરાતી"},{code:"pa",name:"Punjabi",native_name:"ਪੰਜਾਬੀ"},{code:"or",name:"Odia",native_name:"ଓଡ଼ିଆ"},{code:"as",name:"Assamese",native_name:"অসমীয়া"},{code:"ne",name:"Nepali",native_name:"नेपाली"},{code:"si",name:"Sinhala",native_name:"සිංහල"},{code:"ur",name:"Urdu",native_name:"اردو",is_rtl:!0},{code:"ar",name:"Arabic",native_name:"العربية",is_rtl:!0},{code:"he",name:"Hebrew",native_name:"עברית",is_rtl:!0},{code:"fa",name:"Persian",native_name:"فارسی",is_rtl:!0},{code:"ps",name:"Pashto",native_name:"پښتو",is_rtl:!0},{code:"ku",name:"Kurdish",native_name:"Kurdî"},{code:"az",name:"Azerbaijani",native_name:"Azərbaycanca"},{code:"hy",name:"Armenian",native_name:"Հայերեն"},{code:"ka",name:"Georgian",native_name:"ქართული"},{code:"kk",name:"Kazakh",native_name:"Қазақша"},{code:"uz",name:"Uzbek",native_name:"Oʻzbekcha"},{code:"ky",name:"Kyrgyz",native_name:"Кыргызча"},{code:"tg",name:"Tajik",native_name:"Тоҷикӣ"},{code:"tk",name:"Turkmen",native_name:"Türkmençe"},{code:"mn",name:"Mongolian",native_name:"Монгол"},{code:"sw",name:"Swahili",native_name:"Kiswahili"},{code:"am",name:"Amharic",native_name:"አማርኛ"},{code:"yo",name:"Yoruba",native_name:"Yorùbá"},{code:"ig",name:"Igbo",native_name:"Igbo"},{code:"ha",name:"Hausa",native_name:"Hausa"},{code:"zu",name:"Zulu",native_name:"isiZulu"},{code:"xh",name:"Xhosa",native_name:"isiXhosa"},{code:"af",name:"Afrikaans",native_name:"Afrikaans"},{code:"so",name:"Somali",native_name:"Soomaali"},{code:"eo",name:"Esperanto",native_name:"Esperanto"},{code:"en-GB",name:"English (United Kingdom)",native_name:"English (UK)"},{code:"en-US",name:"English (United States)",native_name:"English (US)"},{code:"en-AU",name:"English (Australia)",native_name:"English (AU)"},{code:"en-CA",name:"English (Canada)",native_name:"English (CA)"},{code:"en-IE",name:"English (Ireland)",native_name:"English (IE)"},{code:"en-IN",name:"English (India)",native_name:"English (IN)"},{code:"en-NZ",name:"English (New Zealand)",native_name:"English (NZ)"},{code:"en-ZA",name:"English (South Africa)",native_name:"English (ZA)"},{code:"es-ES",name:"Spanish (Spain)",native_name:"Español (España)"},{code:"es-MX",name:"Spanish (Mexico)",native_name:"Español (México)"},{code:"es-AR",name:"Spanish (Argentina)",native_name:"Español (Argentina)"},{code:"es-CL",name:"Spanish (Chile)",native_name:"Español (Chile)"},{code:"es-CO",name:"Spanish (Colombia)",native_name:"Español (Colombia)"},{code:"es-419",name:"Spanish (Latin America)",native_name:"Español (Latinoamérica)"},{code:"pt-BR",name:"Portuguese (Brazil)",native_name:"Português (Brasil)"},{code:"pt-PT",name:"Portuguese (Portugal)",native_name:"Português (Portugal)"},{code:"fr-FR",name:"French (France)",native_name:"Français (France)"},{code:"fr-CA",name:"French (Canada)",native_name:"Français (Canada)"},{code:"fr-BE",name:"French (Belgium)",native_name:"Français (Belgique)"},{code:"fr-CH",name:"French (Switzerland)",native_name:"Français (Suisse)"},{code:"de-DE",name:"German (Germany)",native_name:"Deutsch (Deutschland)"},{code:"de-AT",name:"German (Austria)",native_name:"Deutsch (Österreich)"},{code:"de-CH",name:"German (Switzerland)",native_name:"Deutsch (Schweiz)"},{code:"it-IT",name:"Italian (Italy)",native_name:"Italiano (Italia)"},{code:"it-CH",name:"Italian (Switzerland)",native_name:"Italiano (Svizzera)"},{code:"nl-NL",name:"Dutch (Netherlands)",native_name:"Nederlands (Nederland)"},{code:"nl-BE",name:"Dutch (Belgium)",native_name:"Nederlands (België)"},{code:"zh-CN",name:"Chinese (Simplified)",native_name:"中文 (简体)"},{code:"zh-TW",name:"Chinese (Traditional)",native_name:"中文 (繁體)"},{code:"zh-HK",name:"Chinese (Hong Kong)",native_name:"中文 (香港)"},{code:"zh-SG",name:"Chinese (Singapore)",native_name:"中文 (新加坡)"},{code:"ar-SA",name:"Arabic (Saudi Arabia)",native_name:"العربية (السعودية)",is_rtl:!0},{code:"ar-EG",name:"Arabic (Egypt)",native_name:"العربية (مصر)",is_rtl:!0},{code:"ar-AE",name:"Arabic (UAE)",native_name:"العربية (الإمارات)",is_rtl:!0},{code:"sr-Latn",name:"Serbian (Latin)",native_name:"Srpski"}],Ke=new Set(["en","es","fr","de","it","pt","nl","pl","ru","uk","cs","sk","sl","hu","ro","bg","hr","sr","el","tr","sv","no","da","fi","et","lv","lt","ja","ko","zh","vi","th","id","hi","bn","ar","he","sw"]),Qe=Je.filter(e=>function(e){const s=String(e||"").toLowerCase();return!s.includes("-")&&Ke.has(s)}(e.code));function es(e){if(!e)return null;const s=String(e).toLowerCase();return Je.find(e=>e.code.toLowerCase()===s)||null}const ss={pt:{kind:"ambiguous",variants:["pt-BR","pt-PT"]},zh:{kind:"ambiguous",variants:["zh-CN","zh-TW"]}},ts={id:null,source_term:"",rule_type:"never_translate",case_sensitive:!1,notes:"",translations:{}};function as({boot:e}){const s=Me(),t=String(e?.language?.default||"en").toLowerCase(),a=(0,n.useMemo)(()=>Array.isArray(e?.language?.active)?e.language.active:[],[e]),i=(0,n.useMemo)(()=>a.map(e=>String(e).toLowerCase()).filter(e=>e&&e!==t),[a,t]),[r,o]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[h,g]=(0,n.useState)(null),[u,m]=(0,n.useState)(!1),[w,v]=(0,n.useState)(null),[j,b]=(0,n.useState)(!1),[N,C]=(0,n.useState)(null),S=(0,n.useCallback)(async()=>{d(null);try{const e=await y()({path:"/gloty/v1/glossary",parse:!0});o(Array.isArray(e?.terms)?e.terms:[])}catch(e){o([]),d({status:"error",message:e?.message||(0,l.__)("Could not load the glossary.","gloty")})}},[]);(0,n.useEffect)(()=>{S()},[S]);const k=(0,n.useCallback)(e=>{const s=es(e);return s?`${s.name} (${e.toUpperCase()})`:e.toUpperCase()},[]),T=(e,s)=>g(t=>({...t,[e]:s})),E=e=>{if("translate_as"!==e.rule_type)return(0,l.__)("Kept exactly as written","gloty");const s=i.map(s=>{const t=e.translations?.[s];return t?`${s.toUpperCase()}: ${t}`:null}).filter(Boolean);return s.length?s.join(" · "):(0,l.__)("No per-language values set yet","gloty")},L=null===r;return(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-glossary-screen",children:[(0,_.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Keep your brand and product names exactly right in every language. Add a term to stop it being translated, or set exactly how it should appear per language.","gloty")}),c&&(0,_.jsx)(f.Notice,{status:c.status,isDismissible:!0,onDismiss:()=>d(null),className:"wpshelf-mb",children:c.message}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card",children:[(0,_.jsxs)(f.CardHeader,{size:"small",children:[(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Glossary terms","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>g({...ts,translations:{}}),disabled:L,children:(0,l.__)("Add term","gloty")})]}),(0,_.jsxs)(f.CardBody,{children:[L&&(0,_.jsx)(de,{rows:4,headers:[(0,l.__)("Term","gloty"),(0,l.__)("Behavior","gloty"),(0,l.__)("Rendering","gloty"),(0,l.__)("Active","gloty"),""]}),!L&&0===r.length&&(0,_.jsx)(ie,{icon:(0,_.jsx)(x,{icon:B}),title:(0,l.__)("No glossary terms yet","gloty"),hint:(0,l.__)("Add a brand or product name to protect it from translation across your whole site.","gloty")}),!L&&r.length>0&&(0,_.jsxs)(p,{className:"wp-list-table widefat striped wpshelf-table",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Term","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Behavior","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Rendering","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Active","gloty")}),(0,_.jsx)("th",{scope:"col"})]})}),(0,_.jsx)("tbody",{children:r.map(e=>(0,_.jsxs)("tr",{children:[(0,_.jsxs)("td",{children:[(0,_.jsx)("strong",{children:e.source_term}),!!e.case_sensitive&&(0,_.jsxs)("span",{className:"wpshelf-muted",children:[" ","·"," ",(0,l.__)("case-sensitive","gloty")]}),e.notes&&(0,_.jsx)("div",{className:"wpshelf-muted",children:e.notes})]}),(0,_.jsx)("td",{children:"translate_as"===e.rule_type?(0,l.__)("Translate as…","gloty"):(0,l.__)("Never translate","gloty")}),(0,_.jsx)("td",{className:"wpshelf-muted",children:E(e)}),(0,_.jsx)("td",{children:(0,_.jsx)(f.ToggleControl,{__nextHasNoMarginBottom:!0,checked:!!e.is_active,disabled:N===e.id,onChange:t=>(async(e,t)=>{if(N!==e.id){C(e.id),o(s=>s.map(s=>s.id===e.id?{...s,is_active:t?1:0}:s));try{await y()({path:`/gloty/v1/glossary/${e.id}`,method:"PUT",data:{is_active:t?1:0}})}catch(e){s.error(e?.message||(0,l.__)("Could not update the term.","gloty")),await S()}finally{C(null)}}})(e,t),label:""})}),(0,_.jsxs)("td",{children:[(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>(e=>g({id:e.id,source_term:e.source_term||"",rule_type:"translate_as"===e.rule_type?"translate_as":"never_translate",case_sensitive:!!e.case_sensitive,notes:e.notes||"",translations:e.translations&&"object"==typeof e.translations?{...e.translations}:{}}))(e),children:(0,l.__)("Edit","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",isDestructive:!0,onClick:()=>v(e),children:(0,l.__)("Delete","gloty")})]})]},e.id))})]})]})]}),h&&(0,_.jsxs)(f.Modal,{title:h.id?(0,l.__)("Edit glossary term","gloty"):(0,l.__)("Add glossary term","gloty"),onRequestClose:()=>g(null),className:"wpshelf-glossary-modal",children:[(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Term","gloty"),value:h.source_term,onChange:e=>T("source_term",e),placeholder:(0,l.__)("e.g. Chanel N°5","gloty"),help:(0,l.__)("The exact brand or product name as it appears on your site.","gloty")})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.SelectControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Behavior","gloty"),value:h.rule_type,options:[{label:(0,l.__)("Never translate — keep it verbatim","gloty"),value:"never_translate"},{label:(0,l.__)("Translate as… — set it per language","gloty"),value:"translate_as"}],onChange:e=>T("rule_type",e)})}),"translate_as"===h.rule_type&&(0,_.jsx)("div",{className:"wpshelf-settings-field",children:0===i.length?(0,_.jsx)(f.Notice,{status:"info",isDismissible:!1,children:(0,l.__)("Add a target language first to set per-language values. Until then the term is kept verbatim.","gloty")}):i.map(e=>(0,_.jsx)(f.TextControl,{__nextHasNoMarginBottom:!0,label:k(e),value:h.translations?.[e]||"",onChange:s=>((e,s)=>g(t=>({...t,translations:{...t.translations,[e]:s}})))(e,s),placeholder:(0,l.__)("Leave blank to keep verbatim","gloty")},e))}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Case-sensitive match","gloty"),help:(0,l.__)("Only match the exact capitalization above. Leave off for most brands.","gloty"),checked:h.case_sensitive,onChange:e=>T("case_sensitive",e)})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextControl,{__nextHasNoMarginBottom:!0,label:(0,l.__)("Note (optional)","gloty"),value:h.notes,onChange:e=>T("notes",e)})}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:8,marginTop:16,justifyContent:"flex-end"},children:[(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>g(null),children:(0,l.__)("Cancel","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{if(!h)return;const e=(h.source_term||"").trim();if(!e)return void s.error((0,l.__)("Enter a term first.","gloty"));const t={source_term:e,rule_type:h.rule_type,case_sensitive:h.case_sensitive?1:0,notes:h.notes||"",translations:"translate_as"===h.rule_type?h.translations:{}};m(!0);try{h.id?(await y()({path:`/gloty/v1/glossary/${h.id}`,method:"PUT",data:t}),s.success((0,l.__)("Term updated.","gloty"))):(await y()({path:"/gloty/v1/glossary",method:"POST",data:t}),s.success((0,l.__)("Term added.","gloty"))),g(null),await S()}catch(e){s.error(e?.message||(0,l.__)("Could not save the term.","gloty"))}finally{m(!1)}},isBusy:u,disabled:u,children:h.id?(0,l.__)("Save changes","gloty"):(0,l.__)("Add term","gloty")})]})]}),w&&(0,_.jsx)(re,{title:(0,l.__)("Remove glossary term","gloty"),message:(M=w.source_term,(0,l.__)("This term will be translated normally again on future syncs.","gloty").concat(M?` (“${M}”)`:"")),confirmLabel:(0,l.__)("Remove term","gloty"),busy:j,onConfirm:async()=>{if(w){b(!0);try{await y()({path:`/gloty/v1/glossary/${w.id}`,method:"DELETE"}),s.success((0,l.__)("Term removed.","gloty")),v(null),await S()}catch(e){s.error(e?.message||(0,l.__)("Could not remove the term.","gloty"))}finally{b(!1)}}},onCancel:()=>v(null)})]});var M}function ls(e){if(!e)return"";const s=(Date.now()-e)/1e3;return s<60?(0,l.__)("just now","gloty"):s<3600?Math.floor(s/60)+(0,l.__)("m ago","gloty"):s<86400?Math.floor(s/3600)+(0,l.__)("h ago","gloty"):Math.floor(s/86400)+(0,l.__)("d ago","gloty")}function ns({onNavigate:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(null),r=(0,n.useRef)(!0),o=(0,n.useCallback)(async()=>{try{const e=await y()({path:"/gloty/v1/issues",parse:!0});r.current&&(t(e?.count||{error:0,warning:0,info:0}),i(Date.now()))}catch{}},[]);(0,n.useEffect)(()=>{r.current=!0,o();const e=window.setInterval(o,6e4),s=()=>{"visible"===document.visibilityState&&o()};return document.addEventListener("visibilitychange",s),window.addEventListener("gloty-license-refresh",o),()=>{r.current=!1,window.clearInterval(e),document.removeEventListener("visibilitychange",s),window.removeEventListener("gloty-license-refresh",o)}},[o]);const[,c]=(0,n.useReducer)(e=>e+1,0);(0,n.useEffect)(()=>{const e=window.setInterval(c,3e4);return()=>window.clearInterval(e)},[]);const d=function(e){return e?(e.error||0)>0?{tone:"error",label:(0,l.__)("Disconnected","gloty")}:(e.warning||0)>0?{tone:"warning",label:(0,l.__)("Degraded","gloty")}:{tone:"ok",label:(0,l.__)("Connected","gloty")}:{tone:"loading",label:(0,l.__)("Checking…","gloty")}}(s),h=s&&"ok"!==d.tone&&"loading"!==d.tone?` (${(s.error||0)+(s.warning||0)})`:"";return(0,_.jsxs)("button",{type:"button",className:`wpshelf-health-pill wpshelf-health-pill--${d.tone}`,onClick:()=>e&&e("dashboard"),"aria-label":(0,l.__)("Connection health — click to view details","gloty"),title:(0,l.__)("Connection health. Click to jump to the Overview tab.","gloty"),children:[(0,_.jsx)("span",{className:"wpshelf-health-pill__dot","aria-hidden":"true"}),(0,_.jsxs)("span",{className:"wpshelf-health-pill__label",children:[d.label,h]}),a&&(0,_.jsx)("span",{className:"wpshelf-health-pill__time",children:ls(a)})]})}const is={error:"⚠",warning:"⚠",info:"ℹ"},rs={error:(0,l.__)("Critical","gloty"),warning:(0,l.__)("Warning","gloty"),info:(0,l.__)("Info","gloty")};function os({issue:e,onNavigate:s}){const t=e.severity||"info";return(0,_.jsxs)("li",{className:`wpshelf-issue wpshelf-issue--${t}`,children:[(0,_.jsx)("span",{className:"wpshelf-issue__icon","aria-hidden":"true",children:is[t]}),(0,_.jsxs)("div",{className:"wpshelf-issue__body",children:[(0,_.jsxs)("div",{className:"wpshelf-issue__title",children:[(0,_.jsxs)("span",{className:"screen-reader-text",children:[rs[t],":"]}),e.title]}),e.detail&&(0,_.jsx)("div",{className:"wpshelf-issue__detail wpshelf-muted",children:e.detail})]}),e.action&&s&&(0,_.jsx)(f.Button,{variant:"error"===t?"primary":"secondary",isSmall:!0,onClick:()=>s(e.action.view,e.action.filters||null),children:e.action.label})]})}function cs({onNavigate:e}){const[s,t]=(0,n.useState)(null),[a,i]=(0,n.useState)(!0),[r,o]=(0,n.useState)(null),c=(0,n.useCallback)(async()=>{i(!0),o(null);try{const e=await y()({path:"/gloty/v1/issues",parse:!0});t(e)}catch(e){o(e?.message||(0,l.__)("Could not load issues.","gloty"))}finally{i(!1)}},[]);if((0,n.useEffect)(()=>{c()},[c]),a&&!s)return null;if(r)return null;const d=s?.count||{error:0,warning:0,info:0},h=d.error+d.warning+d.info,g=s?.issues||[];let u=(0,l.__)("Needs attention","gloty");return 0===h?u=(0,l.__)("All clear","gloty"):d.error>0?u=(0,l.sprintf)(/* translators: %d: number of critical issues */ /* translators: %d: number of critical issues */ 22 (0,l._n)("Needs attention · %d critical issue","Needs attention · %d critical issues",d.error,"gloty"),d.error):d.warning>0&&(u=(0,l.sprintf)(/* translators: %d: number of warnings */ /* translators: %d: number of warnings */ 23 (0,l._n)("Needs attention · %d warning","Needs attention · %d warnings",d.warning,"gloty"),d.warning)),(0,_.jsxs)(f.Card,{className:"wpshelf-issues-card wpshelf-mb "+(d.error>0?"wpshelf-issues-card--error":d.warning>0?"wpshelf-issues-card--warning":""),role:"region","aria-label":(0,l.__)("System health","gloty"),children:[(0,_.jsxs)(f.CardHeader,{children:[(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:u}),(0,_.jsx)(f.Button,{variant:"tertiary",size:"small",onClick:c,disabled:a,isBusy:a,"aria-live":"polite",children:a?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]}),(0,_.jsx)(f.CardBody,{children:0===h?(0,_.jsx)("p",{className:"wpshelf-muted",style:{margin:0},children:(0,l.__)("No issues detected. Translator service is reachable and your license is in good standing.","gloty")}):(0,_.jsx)("ul",{className:"wpshelf-issues",children:g.map(s=>(0,_.jsx)(os,{issue:s,onNavigate:e},s.id))})})]})}function ds(e){return es(e)?.name||e}function hs({code:e}){const s=function(e,s=ss){const t=String(e||"").toLowerCase();if(!t)return null;const a=Object.keys(s).find(e=>e.toLowerCase()===t);return a?{code:a,kind:s[a].kind,variants:s[a].variants||[]}:null}(e);if(!s)return null;const t=function(e){const s=ds(e.code);if("ambiguous"===e.kind){const t=e.variants.map(e=>`${ds(e)} (${e})`);return(0,l.sprintf)(/* translators: 1: language name, 2: code, 3: one regional variant, 4: another */ /* translators: 1: language name, 2: code, 3: one regional variant, 4: another */ 24 24 (0,l.__)("%1$s (%2$s) covers more than one regional variant. Which one the translation engine writes is its choice, not a setting — %3$s and %4$s differ in vocabulary and idiom, not only spelling. Review the first translated pages before you make this language public.","gloty"),s,e.code,t[0]||"",t[1]||"")}return"unverified"===e.kind?(0,l.sprintf)(/* translators: 1: language name, 2: BCP 47 code */ /* translators: 1: language name, 2: BCP 47 code */ 25 (0,l.__)("Translation quality for %1$s (%2$s) is unverified. It is offered because a vendor lists it or somebody asked for it, not because anyone has read the output — review the first translated pages before you make this language public.","gloty"),s,e.code):""}(s);return t?(0, u.jsx)(y.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mb",politeness:"polite",children:t}):null}const hs=[{label:(0,l.__)("Dropdown","gloty"),value:"dropdown"},{label:(0,l.__)("Inline Links","gloty"),value:"inline"},{label:(0,l.__)("Flags Only","gloty"),value:"flags"}],gs=[{label:(0,l.__)("Automatic (let the engine decide)","gloty"),value:""},{label:(0,l.__)("Formal","gloty"),value:"formal"},{label:(0,l.__)("Informal","gloty"),value:"informal"}],us=[{label:(0,l.__)("Top Left","gloty"),value:"top_left"},{label:(0,l.__)("Top Right","gloty"),value:"top_right"},{label:(0,l.__)("Bottom Left","gloty"),value:"bottom_left"},{label:(0,l.__)("Bottom Right","gloty"),value:"bottom_right"},{label:(0,l.__)("Footer bar","gloty"),value:"footer"},{label:(0,l.__)("Manual (shortcode / widget only)","gloty"),value:"manual"}];function _s(e){const s=e?new Date(e).getTime():NaN;if(Number.isNaN(s))return"";const t=Math.max(0,Math.round((Date.now()-s)/1e3));if(t<60)return(0,l.__)("just now","gloty");const a=Math.round(t/60);if(a<60)25 (0,l.__)("Translation quality for %1$s (%2$s) is unverified. It is offered because a vendor lists it or somebody asked for it, not because anyone has read the output — review the first translated pages before you make this language public.","gloty"),s,e.code):""}(s);return t?(0,_.jsx)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mb",politeness:"polite",children:t}):null}const gs=[{label:(0,l.__)("Dropdown","gloty"),value:"dropdown"},{label:(0,l.__)("Inline Links","gloty"),value:"inline"},{label:(0,l.__)("Flags Only","gloty"),value:"flags"}],us=[{label:(0,l.__)("Automatic (let the engine decide)","gloty"),value:""},{label:(0,l.__)("Formal","gloty"),value:"formal"},{label:(0,l.__)("Informal","gloty"),value:"informal"}],_s=[{label:(0,l.__)("Top Left","gloty"),value:"top_left"},{label:(0,l.__)("Top Right","gloty"),value:"top_right"},{label:(0,l.__)("Bottom Left","gloty"),value:"bottom_left"},{label:(0,l.__)("Bottom Right","gloty"),value:"bottom_right"},{label:(0,l.__)("Footer bar","gloty"),value:"footer"},{label:(0,l.__)("Manual (shortcode / widget only)","gloty"),value:"manual"}];function ps(e){const s=e?new Date(e).getTime():NaN;if(Number.isNaN(s))return"";const t=Math.max(0,Math.round((Date.now()-s)/1e3));if(t<60)return(0,l.__)("just now","gloty");const a=Math.round(t/60);if(a<60) 26 26 // translators: %d is a number of minutes. 27 27 return(0,l.sprintf)((0,l._n)("%d minute ago","%d minutes ago",a,"gloty"),a);const n=Math.round(a/60);if(n<24) … … 29 29 return(0,l.sprintf)((0,l._n)("%d hour ago","%d hours ago",n,"gloty"),n);const i=Math.round(n/24); 30 30 // translators: %d is a number of days. 31 return(0,l.sprintf)((0,l._n)("%d day ago","%d days ago",i,"gloty"),i)}function ps(){const e=Le(),[s,t]=(0,n.useState)([]),[a,i]=(0,n.useState)([]),[r,o]=(0,n.useState)(""),[c,d]=(0,n.useState)(!0),[h,g]=(0,n.useState)(!1);(0,n.useEffect)(()=>{let e=!1;return m()({path:"/gloty/v1/settings/translators"}).then(s=>{if(e)return;const a=s?.roles||[];t(s?.available||[]),i(a),o(JSON.stringify([...a].sort()))}).catch(()=>{}).finally(()=>!e&&d(!1)),()=>{e=!0}},[]);const _=JSON.stringify([...a].sort())!==r;return(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Who may correct translations","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("People in these roles can open Gloty and correct translations. They cannot change settings, spend your plan, or delete anything. Administrators always can.","gloty")}),c?(0,u.jsx)(y.Spinner,{}):(0,u.jsxs)(u.Fragment,{children:[s.map(e=>(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.CheckboxControl,{label:e.name,checked:a.includes(e.slug),onChange:s=>{return t=e.slug,a=s,i(e=>a?[...e,t]:e.filter(e=>e!==t));var t,a},__nextHasNoMarginBottom:!0})},e.slug)),(0,u.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("A role also needs to be able to edit posts. To limit someone to particular languages, edit their user profile.","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:async()=>{g(!0);try{const s=await m()({path:"/gloty/v1/settings/translators",method:"POST",data:{roles:a}}),t=s?.roles||[];i(t),o(JSON.stringify([...t].sort())),e.success((0,l.__)("Translator roles saved.","gloty"))}catch(s){e.error(s?.message||(0,l.__)("Failed to save translator roles.","gloty"))}finally{g(!1)}},isBusy:h,disabled:h||!_,children:h?(0,l.__)("Saving…","gloty"):(0,l.__)("Save roles","gloty")})]})]})]})}function ms({boot:e}){const s=Le(),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)({}),[o,c]=(0,n.useState)(!0),[d,h]=(0,n.useState)(!1),[g,_]=(0,n.useState)(null),p=(0,n.useCallback)(async()=>{c(!0),_(null);try{const e=await m()({path:"/gloty/v1/settings/plugin",parse:!0});a(e),r(e)}catch(e){_({status:"error",message:e?.message||(0,l.__)("Failed to load settings.","gloty")})}finally{c(!1)}},[]);(0,n.useEffect)(()=>{p()},[p]);const f=(0,n.useCallback)((e,s)=>{r(t=>({...t,[e]:s}))},[]),w=(0,n.useMemo)(()=>!!t&&JSON.stringify(i)!==JSON.stringify(t),[i,t]),x=async()=>{h(!0),_(null);try{await m()({path:"/gloty/v1/settings/plugin",method:"POST",data:i}),_({status:"success",message:(0,l.__)("Settings saved.","gloty")}),s.success((0,l.__)("Settings saved.","gloty")),await p()}catch(e){const t=e?.message||(0,l.__)("Failed to save settings.","gloty");_({status:"error",message:t}),s.error(t)}finally{h(!1)}};if(o)return(0,u.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,u.jsx)(y.Spinner,{}),(0,u.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading settings…","gloty")})]});const v=e?.sync?.lastDispatchAt||"",j=!!e?.sync?.cronStalled;return(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-settings-screen",children:[(0,u.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Control how translations are generated and customise the language switcher appearance.","gloty")}),g&&(0,u.jsx)(y.Notice,{status:g.status,isDismissible:!0,onDismiss:()=>_(null),className:"wpshelf-mb",children:g.message}),(0,u.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:x,isBusy:d,disabled:d||!w,children:d?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),w&&(0,u.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Translation","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Control how and when translations are created.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Formality","gloty"),value:i.translation_formality||"",options:gs,onChange:e=>f("translation_formality",e),help:(0,l.__)('How your site addresses visitors — for example "Sie" or "du" in German. Applies to translations created from now on; content already translated keeps its current wording.',"gloty"),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextareaControl,{label:(0,l.__)("Brand voice","gloty"),value:i.translation_tone||"",onChange:e=>f("translation_tone",e),rows:2,maxLength:300,help:(0,l.__)('Optional. A short note on how your brand should sound, e.g. "warm and plain-spoken, no exclamation marks". Sent with every translation request.',"gloty"),__nextHasNoMarginBottom:!0})}),(0,u.jsxs)("div",{className:"wpshelf-settings-field",children:[(0,u.jsx)(y.TextControl,{label:(0,l.__)("Dispatch batch size","gloty"),value:String(i.batch_size||40),onChange:e=>f("batch_size",Math.max(1,Math.min(500,parseInt(e,10)||1))),type:"number",min:1,max:500,help:(0,l.__)("Strings sent to the translator per background run (1–500). The background job runs about once a minute when WordPress cron is healthy, so a higher value clears a backlog faster — 100–250 suits a large initial translation.","gloty"),__nextHasNoMarginBottom:!0}),(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:8,marginBottom:0},children:v?(0,l.sprintf)(31 return(0,l.sprintf)((0,l._n)("%d day ago","%d days ago",i,"gloty"),i)}function ms(){const e=Me(),[s,t]=(0,n.useState)([]),[a,i]=(0,n.useState)([]),[r,o]=(0,n.useState)(""),[c,d]=(0,n.useState)(!0),[h,g]=(0,n.useState)(!1);(0,n.useEffect)(()=>{let e=!1;return y()({path:"/gloty/v1/settings/translators"}).then(s=>{if(e)return;const a=s?.roles||[];t(s?.available||[]),i(a),o(JSON.stringify([...a].sort()))}).catch(()=>{}).finally(()=>!e&&d(!1)),()=>{e=!0}},[]);const u=JSON.stringify([...a].sort())!==r;return(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Who may correct translations","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("People in these roles can open Gloty and correct translations. They cannot change settings, spend your plan, or delete anything. Administrators always can.","gloty")}),c?(0,_.jsx)(f.Spinner,{}):(0,_.jsxs)(_.Fragment,{children:[s.map(e=>(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.CheckboxControl,{label:e.name,checked:a.includes(e.slug),onChange:s=>{return t=e.slug,a=s,i(e=>a?[...e,t]:e.filter(e=>e!==t));var t,a},__nextHasNoMarginBottom:!0})},e.slug)),(0,_.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("A role also needs to be able to edit posts. To limit someone to particular languages, edit their user profile.","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:async()=>{g(!0);try{const s=await y()({path:"/gloty/v1/settings/translators",method:"POST",data:{roles:a}}),t=s?.roles||[];i(t),o(JSON.stringify([...t].sort())),e.success((0,l.__)("Translator roles saved.","gloty"))}catch(s){e.error(s?.message||(0,l.__)("Failed to save translator roles.","gloty"))}finally{g(!1)}},isBusy:h,disabled:h||!u,children:h?(0,l.__)("Saving…","gloty"):(0,l.__)("Save roles","gloty")})]})]})]})}function ys({boot:e}){const s=Me(),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)({}),[o,c]=(0,n.useState)(!0),[d,h]=(0,n.useState)(!1),[g,u]=(0,n.useState)(null),p=(0,n.useCallback)(async()=>{c(!0),u(null);try{const e=await y()({path:"/gloty/v1/settings/plugin",parse:!0});a(e),r(e)}catch(e){u({status:"error",message:e?.message||(0,l.__)("Failed to load settings.","gloty")})}finally{c(!1)}},[]);(0,n.useEffect)(()=>{p()},[p]);const m=(0,n.useCallback)((e,s)=>{r(t=>({...t,[e]:s}))},[]),w=(0,n.useMemo)(()=>!!t&&JSON.stringify(i)!==JSON.stringify(t),[i,t]),x=async()=>{h(!0),u(null);try{await y()({path:"/gloty/v1/settings/plugin",method:"POST",data:i}),u({status:"success",message:(0,l.__)("Settings saved.","gloty")}),s.success((0,l.__)("Settings saved.","gloty")),await p()}catch(e){const t=e?.message||(0,l.__)("Failed to save settings.","gloty");u({status:"error",message:t}),s.error(t)}finally{h(!1)}};if(o)return(0,_.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,_.jsx)(f.Spinner,{}),(0,_.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading settings…","gloty")})]});const v=e?.sync?.lastDispatchAt||"",j=!!e?.sync?.cronStalled;return(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-settings-screen",children:[(0,_.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Control how translations are generated and customise the language switcher appearance.","gloty")}),g&&(0,_.jsx)(f.Notice,{status:g.status,isDismissible:!0,onDismiss:()=>u(null),className:"wpshelf-mb",children:g.message}),(0,_.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:x,isBusy:d,disabled:d||!w,children:d?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),w&&(0,_.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Translation","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Control how and when translations are created.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Formality","gloty"),value:i.translation_formality||"",options:us,onChange:e=>m("translation_formality",e),help:(0,l.__)('How your site addresses visitors — for example "Sie" or "du" in German. Applies to translations created from now on; content already translated keeps its current wording.',"gloty"),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextareaControl,{label:(0,l.__)("Brand voice","gloty"),value:i.translation_tone||"",onChange:e=>m("translation_tone",e),rows:2,maxLength:300,help:(0,l.__)('Optional. A short note on how your brand should sound, e.g. "warm and plain-spoken, no exclamation marks". Sent with every translation request.',"gloty"),__nextHasNoMarginBottom:!0})}),(0,_.jsxs)("div",{className:"wpshelf-settings-field",children:[(0,_.jsx)(f.TextControl,{label:(0,l.__)("Dispatch batch size","gloty"),value:String(i.batch_size||40),onChange:e=>m("batch_size",Math.max(1,Math.min(500,parseInt(e,10)||1))),type:"number",min:1,max:500,help:(0,l.__)("Strings sent to the translator per background run (1–500). The background job runs about once a minute when WordPress cron is healthy, so a higher value clears a backlog faster — 100–250 suits a large initial translation.","gloty"),__nextHasNoMarginBottom:!0}),(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:8,marginBottom:0},children:v?(0,l.sprintf)( 32 32 // translators: %s is a relative time, e.g. "2 minutes ago". 33 33 // translators: %s is a relative time, e.g. "2 minutes ago". 34 (0,l.__)("Background dispatch last ran %s.","gloty"), _s(v)):(0,l.__)("Background dispatch has not run yet.","gloty")}),j&&(0,u.jsx)("div",{style:{marginTop:8},children:(0,u.jsx)(y.Notice,{status:"warning",isDismissible:!1,children:(0,l.__)("Translations dispatch on WordPress cron, which only fires when your site gets traffic — so on a quiet site they trickle out slowly. For steady throughput, point a real cron (or a 1-minute uptime ping) at wp-cron.php. The translator itself is fast; it just needs to be fed.","gloty")})})]}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Cache translations","gloty"),help:(0,l.__)("Reuse stored translations for identical text instead of re-sending it to the translator. Recommended — leave on unless you are debugging translation output.","gloty"),checked:void 0===i.translation_cache||!!i.translation_cache,onChange:e=>f("translation_cache",e),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextareaControl,{label:(0,l.__)("Exclusion selectors","gloty"),value:i.exclude_selectors||"",onChange:e=>f("exclude_selectors",e),placeholder:".no-translate, #site-credit, code",help:(0,l.__)("Comma-separated CSS selectors for elements to leave untranslated — e.g. brand names, code samples, author credits. Example: .no-translate, #site-credit, code. Leave blank to translate everything.","gloty"),rows:3,__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Translate page addresses","gloty"),help:(0,l.__)("Give each translated page an address in its own language — /de/ueber-uns/ instead of /de/about-us/. The address is worked out from the translated title, so it costs no extra translation. Your existing addresses keep working, so nothing you have shared or that Google has indexed will break.","gloty"),checked:!!i.translate_slugs,onChange:e=>f("translate_slugs",e),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextareaControl,{label:(0,l.__)("Pages to leave untranslated","gloty"),value:i.exclude_paths||"",onChange:e=>f("exclude_paths",e),placeholder:"/checkout/*\n/terms-and-conditions",help:(0,l.__)("One path per line. Use * as a wildcard — /checkout/* covers everything below /checkout/. Write the path without a language prefix and it applies in every language. These pages render in your site language and cost no quota.","gloty"),rows:3,__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.TextareaControl,{label:(0,l.__)("Content loaded after the page","gloty"),value:i.ajax_actions||"",onChange:e=>f("ajax_actions",e),placeholder:"load_more_posts\nfilter_products",help:(0,l.__)("One AJAX action name per line. If your theme loads more posts, filters a product grid or opens a search panel without reloading the page, that content skips translation — naming the action here fixes it. Leave empty unless you have that problem: your theme or plugin documentation, or the browser network tab, will tell you the action name. WooCommerce’s own cart and checkout are already handled.","gloty"),rows:2,__nextHasNoMarginBottom:!0})})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Visitor redirection","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Automatically greet international visitors in the version of your site that matches their browser language.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Auto-redirect by browser language","gloty"),help:(0,l.__)("On their first visit, send visitors to their preferred language when you offer it. Applied once per visitor — a manual choice from the switcher is always respected afterwards, and search engine crawlers are never redirected.","gloty"),checked:!!i.auto_redirect,onChange:e=>f("auto_redirect",e),__nextHasNoMarginBottom:!0})})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Analytics","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Gloty counts views per language so you can see which languages are worth translating. Counting is local either way — no visitor data is stored and nothing is sent off your site.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Count views from the browser","gloty"),help:(0,l.__)("Turn this on if you run a page cache (WP Rocket, LiteSpeed, Cloudflare). Cached pages are served without starting PHP, so Gloty cannot see those views and your per-language split is both low and uneven. With this on, a small script counts the view from the browser instead, sending only the language of the page — no IP address, no page address, no referrer, no identifier of any kind. Server-side counting switches off at the same time, so each view is still counted once. The cost: a visitor with JavaScript disabled is not counted, and if a plugin combines your site’s JavaScript, exclude the “gloty-page-view-beacon” handle from it.","gloty"),checked:!!i.analytics_beacon,onChange:e=>f("analytics_beacon",e),__nextHasNoMarginBottom:!0})})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Language Switcher","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Customise the appearance and placement of the language switcher on your site.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Style","gloty"),value:i.switcher_style||"dropdown",options:hs,onChange:e=>f("switcher_style",e),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Position","gloty"),value:i.switcher_position||"bottom_right",options:us,help:(0,l.__)("The four corners float the switcher over the page. Footer bar puts it in a strip at the end of the page instead, in the style chosen above.","gloty"),onChange:e=>f("switcher_position",e),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Show flags","gloty"),help:(0,l.__)("Display country flags next to language names in the switcher.","gloty"),checked:void 0===i.show_flags||!!i.show_flags,onChange:e=>f("show_flags",e),__nextHasNoMarginBottom:!0})})]})]}),(0,u.jsx)(ps,{}),(0,u.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:x,isBusy:d,disabled:d||!w,children:d?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),w&&(0,u.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]})]})}const ys="gloty_quota_80_dismissed";function fs({license:e,hideOnboarding:s=!1}){const[t,a]=(0,n.useState)(!1),[i,r]=(0,n.useState)([]),[o,c]=(0,n.useState)(null),[d,h]=(0,n.useState)(()=>{if("undefined"==typeof window)return!1;try{return"1"===window.sessionStorage.getItem(ys)}catch{return!1}}),g=e?.status,_=g?.characters_used??0,p=g?.characters_limit??0,f=p>0?Math.round(_/p*100):0;(0,n.useEffect)(()=>{let e=!0;return ye().then(s=>{e&&r(s)}),()=>{e=!1}},[]);const w=fe(g,i)[0]||null,x=(0,n.useCallback)(async()=>{if(w){a(!0),c(null);try{const e=await m()({path:"/gloty/v1/license/checkout",method:"POST",data:{plan_slug:w.slug}});c(e?.url?je(e.url):ve(e?.message))}catch(e){c(ve(e?.message))}finally{a(!1)}}},[w]);if(s||!e?.hasKey||!g||f<80)return null;const v=f>=100;if(!v&&d)return null;const j=v?(0,l.__)("Translation quota exceeded. New translations are paused until the next billing period.","gloty"):(0,l.__)("You have used over 80% of your translation quota this period.","gloty");return(0,u.jsxs)(y.Notice,{status:v?"error":"warning",spokenMessage:j,isDismissible:!v,onDismiss:v?void 0:()=>{try{window.sessionStorage.setItem(ys,"1")}catch{}h(!0)},className:"wpshelf-mb",children:[(0,u.jsxs)("span",{children:[j," ",(0,u.jsxs)("strong",{children:[_.toLocaleString()," / ",p.toLocaleString()," ",(0,l.__)("characters","gloty")," (",f,"%)"]})]}),w&&(0,u.jsx)(y.Button,{variant:"link",onClick:x,isBusy:t,disabled:t,style:{marginLeft:8},children:(0,l.sprintf)(/* translators: %s: plan name, e.g. Starter */ /* translators: %s: plan name, e.g. Starter */35 (0,l.__)("Upgrade to %s","gloty"),w.name)}),o&&(0, u.jsx)("p",{className:"wpshelf-quota-notice__problem",children:o.message})]})}const ws=[{key:"hreflang",label:(0,l.__)("Output hreflang tags","gloty"),help:(0,l.__)("Tell search engines which language and regional URL to serve. Each page declares every active language plus an x-default — the single most important multilingual SEO signal.","gloty")},{key:"meta",label:(0,l.__)("Translate metadata & Open Graph","gloty"),help:(0,l.__)("Emit a translated meta description plus Open Graph and Twitter Card tags so shared links and search snippets appear in the visitor’s language.","gloty")},{key:"sitemap",label:(0,l.__)("Publish a sitemap of your translated pages","gloty"),help:(0,l.__)("A sitemap listing every translated URL, so search engines can find them. Separate from your main sitemap on purpose: Yoast, Rank Math, AIOSEO and SEOPress each replace the WordPress one with their own, and none of them know about translations.","gloty")},{key:"schema",label:(0,l.__)("Output language schema (JSON-LD)","gloty"),help:(0,l.__)("Declare the page language in structured data (schema.org WebSite inLanguage) for richer search results.","gloty")}];function xs({boot:e}){const s=Le(),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)(()=>({hreflang:e?.seo?.hreflang??!0,meta:e?.seo?.meta??!0,sitemap:e?.seo?.sitemap??!0,schema:e?.seo?.schema??!0})),[o,c]=(0,n.useState)(""),[d,h]=(0,n.useState)(!!e?.seo?.seoPluginActive),[g,_]=(0,n.useState)(!0),[p,f]=(0,n.useState)(!1),[w,x]=(0,n.useState)(null),v=(0,n.useCallback)(async()=>{_(!0),x(null);try{const e=await m()({path:"/gloty/v1/settings/seo",parse:!0}),s={hreflang:!!e.hreflang,meta:!!e.meta,sitemap:!!e.sitemap,schema:!!e.schema};a(s),r(s),h(!!e.seo_plugin_active),c(e.language_sitemap_url||"")}catch(e){x({status:"error",message:e?.message||(0,l.__)("Failed to load SEO settings.","gloty")})}finally{_(!1)}},[]);(0,n.useEffect)(()=>{v()},[v]);const j=(0,n.useCallback)((e,s)=>{r(t=>({...t,[e]:s}))},[]),b=(0,n.useMemo)(()=>!!t&&JSON.stringify(i)!==JSON.stringify(t),[i,t]);if(g)return(0,u.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,u.jsx)(y.Spinner,{}),(0,u.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading SEO settings…","gloty")})]});const N=(0,u.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{f(!0),x(null);try{await m()({path:"/gloty/v1/settings/seo",method:"POST",data:i}),a(i),x({status:"success",message:(0,l.__)("SEO settings saved.","gloty")}),s.success((0,l.__)("SEO settings saved.","gloty"))}catch(e){const t=e?.message||(0,l.__)("Failed to save SEO settings.","gloty");x({status:"error",message:t}),s.error(t)}finally{f(!1)}},isBusy:p,disabled:p||!b,children:p?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),b&&(0,u.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]});return(0,u.jsxs)("div",{className:"wpshelf-screen wpshelf-seo-screen",children:[(0,u.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Make every translated page discoverable. Gloty follows Google’s multilingual SEO guidance — declaring language alternates, translating metadata, and keeping the right URL canonical for each language.","gloty")}),w&&(0,u.jsx)(y.Notice,{status:w.status,isDismissible:!0,onDismiss:()=>x(null),className:"wpshelf-mb",children:w.message}),N,(0,u.jsxs)(y.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Search engine optimization","gloty")})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("These run automatically on the front end. Translated titles, descriptions, and canonical URLs stay in sync with your translations — no per-page setup.","gloty")}),d&&(0,u.jsx)(y.Notice,{status:"info",isDismissible:!1,className:"wpshelf-mb",children:(0,l.__)("A dedicated SEO plugin (e.g. Yoast or Rank Math) is active, so Gloty translates its meta tags instead of emitting its own. The “Translate metadata & Open Graph” toggle only affects Gloty’s native tags, which stand down while that plugin is active.","gloty")}),i.sitemap&&o&&(0,u.jsxs)(y.Notice,{status:"info",isDismissible:!1,className:"wpshelf-mb",children:[(0,l.__)("Your translated-pages sitemap is at:","gloty")," ",(0,u.jsx)("a",{href:o,children:o}),(0,u.jsx)("br",{}),(0,l.__)("Gloty adds this to robots.txt, but an SEO plugin that manages robots.txt will replace that line with its own. If yours does, submit the address above to Google Search Console once and it is done.","gloty")]}),ws.map(e=>(0,u.jsx)("div",{className:"wpshelf-settings-field",children:(0,u.jsx)(y.ToggleControl,{label:e.label,help:e.help,checked:!!i[e.key],onChange:s=>j(e.key,s),__nextHasNoMarginBottom:!0})},e.key))]})]}),N]})}function vs({boot:e,onNavigate:s}={}){const t=e?.connection?.connected??!(!e?.connection?.serviceUrl||!e?.connection?.remoteSiteId),[a,i]=(0,n.useState)(null),[r,o]=(0,n.useState)(!1),[c,d]=(0,n.useState)("full"),[h,g]=(0,n.useState)(!0),[p,f]=(0,n.useState)(!1),[w,x]=(0,n.useState)(!1),[v,j]=(0,n.useState)(null),[b,N]=(0,n.useState)(null),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(null),[B,E]=(0,n.useState)(!1),[L,M]=(0,n.useState)(null),[A,D]=(0,n.useState)(!1),[R,O]=(0,n.useState)(null),[P,$]=(0,n.useState)([]),[I,H]=(0,n.useState)(null),[G,z]=(0,n.useState)([]),[F,V]=(0,n.useState)(""),[U,q]=(0,n.useState)(!1),[W,X]=(0,n.useState)(!0),[Y,Z]=(0,n.useState)(null),J=(0,n.useCallback)(async()=>{Z(null);try{const e=F?`/gloty/v1/activity?type=${encodeURIComponent(F)}`:"/gloty/v1/activity",[s,t,a,l]=await Promise.all([m()({path:"/gloty/v1/dashboard",parse:!0}),m()({path:"/gloty/v1/scan/status",parse:!0}),m()({path:"/gloty/v1/jobs",parse:!0}),m()({path:e,parse:!0})]),n=s?.overview||{};j(n.pending_count??0),N(n.processing_count??0),S(n.source_count??0),T(n.needs_sync_sources??0),i(t),$(a?.jobs||[]),z(l?.events||[])}catch(e){Z(e?.message||(0,l.__)("Failed to load sync data","gloty"))}finally{X(!1)}},[F]);(0,n.useEffect)(()=>{J()},[J]);const[Q,ae]=(0,n.useState)(!1),le=(0,n.useCallback)(async()=>{ae(!0);try{await J()}finally{ae(!1)}},[J]),re=(0,n.useCallback)(async()=>{try{const[e,s]=await Promise.all([m()({path:"/gloty/v1/jobs",parse:!0}),m()({path:"/gloty/v1/dashboard",parse:!0})]);$(e?.jobs||[]);const t=s?.overview||{};j(t.pending_count??0),N(t.processing_count??0)}catch{}},[]),oe=(0,n.useMemo)(()=>P.some(e=>"queued"===e.status||"processing"===e.status),[P]);(0,n.useEffect)(()=>{if(!oe)return;const e=window.setInterval(re,3e3);return()=>window.clearInterval(e)},[oe,re]);const[de,he]=(0,n.useState)(!1);(0,n.useEffect)(()=>{de&&!oe&&J(),he(oe)},[oe,J,de]);const ge=async()=>{o(!0),Z(null);try{await m()({path:"/gloty/v1/scan/start",method:"POST",data:{batch_size:20,mode:c}}),g(!0),await J()}catch(e){Z(e?.message||(0,l.__)("Scan failed","gloty"))}finally{o(!1)}},ue=(0,n.useCallback)(async()=>{o(!0),Z(null);try{await m()({path:"/gloty/v1/scan/step",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Scan step failed","gloty"))}finally{o(!1)}},[J]),_e=async(e,s)=>{H(e.id),Z(null);try{await m()({path:`/gloty/v1/jobs/${e.id}/${s}`,method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Job action failed","gloty"))}finally{H(null)}},pe=a?.cursor||{},me=a?.stats||{},ye="running"===pe.status||"processing"===pe.status,fe="paused"===pe.status,we="complete"===pe.status,xe=pe.mode||me.mode||c,ve=Number(me.processed||0),je=Number(me.queued||0),be=Number(me.last_batch||0),Ne=Number(me.failure_count||0),Ce=Number(me.phase_processed??pe.offset??0),Se=Number(me.phase_total||0),ke=Number(me.total_entities||0),Te=ke>0?Math.min(Math.round(ve/ke*100),100):0,Be=Se>0?Math.min(Math.round(Ce/Se*100),100):0,Ee=ye?(0,l.__)("Scanning now","gloty"):fe?(0,l.__)("Paused by operator","gloty"):we?(0,l.__)("Completed","gloty"):(0,l.__)("Waiting to start","gloty");(0,n.useEffect)(()=>{if(!h||!ye||r)return;const e=window.setTimeout(()=>{ue()},2500);return()=>window.clearTimeout(e)},[h,ye,r,ue]);let Le=(0,u.jsx)(y.Button,{variant:"primary",onClick:ge,isBusy:r,disabled:r,children:(0,l.__)("Scan content","gloty")});ye?Le=(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:ue,isBusy:r,disabled:r,children:(0,l.__)("Continue scan","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>x(!0),disabled:r,children:(0,l.__)("Restart","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",onClick:async()=>{o(!0),Z(null);try{await m()({path:"/gloty/v1/scan/pause",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Could not pause scan","gloty"))}finally{o(!1)}},disabled:r,children:(0,l.__)("Pause","gloty")})]}):fe?Le=(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{o(!0),Z(null);try{await m()({path:"/gloty/v1/scan/resume",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Could not resume scan","gloty"))}finally{o(!1)}},isBusy:r,disabled:r,children:(0,l.__)("Resume scan","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>x(!0),disabled:r,children:(0,l.__)("Restart","gloty")})]}):we&&(Le=(0,u.jsx)(y.Button,{variant:"secondary",onClick:ge,disabled:r,children:(0,l.__)("Run again","gloty")}));const Me=(0,n.useMemo)(()=>{const e={queued:0,processing:0,completed:0,failed:0};return P.forEach(s=>{void 0!==e[s.status]&&e[s.status]++}),e},[P]),Ae=e=>e?.payload?.job_id?`job #${e.payload.job_id}`:e?.payload?.remote_job_id?`remote ${e.payload.remote_job_id}`:e?.payload?.correlation?`corr ${e.payload.correlation}`:"—";return W?(0,u.jsx)("div",{className:"wpshelf-screen",children:(0,u.jsx)(ce,{cols:5,rows:4,headers:[(0,l.__)("Job","gloty"),(0,l.__)("Language","gloty"),(0,l.__)("Segments","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Created","gloty")]})}):(0,u.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Sync workspace","gloty"),children:[(0,u.jsx)(ee,{title:(0,l.__)("Sync workspace","gloty"),subtitle:(0,l.__)("Run scan and dispatch actions, then inspect jobs and events in one place.","gloty")}),Y&&(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:Y}),(0,u.jsx)("div",{"aria-live":"polite","aria-atomic":"true",className:"screen-reader-text",children:L||""}),(0,u.jsxs)("div",{className:"wpshelf-sync-actions",children:[(0,u.jsxs)(y.Card,{className:"wpshelf-sync-card wpshelf-sync-card--scan",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsxs)("div",{className:"wpshelf-sync-card__heading",children:[(0,u.jsx)("span",{className:"wpshelf-sync-card__step",children:(0,l.__)("Step 1","gloty")}),(0,u.jsx)("h3",{className:"wpshelf-sync-card__title",children:(0,l.__)("Scan content","gloty")})]})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-sync-card__desc",children:(0,l.__)("Discover posts, pages, and other content that needs translation.","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-sync-card__status",children:[(0,u.jsx)(K,{status:pe.status||"idle"}),(0,u.jsx)("span",{className:"wpshelf-sync-card__statetext","aria-live":"polite",children:ye?(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(y.Spinner,{}),(0,l.__)("Scanning your content…","gloty")]}):Ee})]}),(0,u.jsxs)("p",{className:"wpshelf-sync-card__summary wpshelf-muted",children:[(0,l.sprintf)(/* translators: %s: number of translatable strings found */ /* translators: %s: number of translatable strings found */34 (0,l.__)("Background dispatch last ran %s.","gloty"),ps(v)):(0,l.__)("Background dispatch has not run yet.","gloty")}),j&&(0,_.jsx)("div",{style:{marginTop:8},children:(0,_.jsx)(f.Notice,{status:"warning",isDismissible:!1,children:(0,l.__)("Translations dispatch on WordPress cron, which only fires when your site gets traffic — so on a quiet site they trickle out slowly. For steady throughput, point a real cron (or a 1-minute uptime ping) at wp-cron.php. The translator itself is fast; it just needs to be fed.","gloty")})})]}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Cache translations","gloty"),help:(0,l.__)("Reuse stored translations for identical text instead of re-sending it to the translator. Recommended — leave on unless you are debugging translation output.","gloty"),checked:void 0===i.translation_cache||!!i.translation_cache,onChange:e=>m("translation_cache",e),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextareaControl,{label:(0,l.__)("Exclusion selectors","gloty"),value:i.exclude_selectors||"",onChange:e=>m("exclude_selectors",e),placeholder:".no-translate, #site-credit, code",help:(0,l.__)("Comma-separated CSS selectors for elements to leave untranslated — e.g. brand names, code samples, author credits. Example: .no-translate, #site-credit, code. Leave blank to translate everything.","gloty"),rows:3,__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Translate page addresses","gloty"),help:(0,l.__)("Give each translated page an address in its own language — /de/ueber-uns/ instead of /de/about-us/. The address is worked out from the translated title, so it costs no extra translation. Your existing addresses keep working, so nothing you have shared or that Google has indexed will break.","gloty"),checked:!!i.translate_slugs,onChange:e=>m("translate_slugs",e),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextareaControl,{label:(0,l.__)("Pages to leave untranslated","gloty"),value:i.exclude_paths||"",onChange:e=>m("exclude_paths",e),placeholder:"/checkout/*\n/terms-and-conditions",help:(0,l.__)("One path per line. Use * as a wildcard — /checkout/* covers everything below /checkout/. Write the path without a language prefix and it applies in every language. These pages render in your site language and cost no quota.","gloty"),rows:3,__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.TextareaControl,{label:(0,l.__)("Content loaded after the page","gloty"),value:i.ajax_actions||"",onChange:e=>m("ajax_actions",e),placeholder:"load_more_posts\nfilter_products",help:(0,l.__)("One AJAX action name per line. If your theme loads more posts, filters a product grid or opens a search panel without reloading the page, that content skips translation — naming the action here fixes it. Leave empty unless you have that problem: your theme or plugin documentation, or the browser network tab, will tell you the action name. WooCommerce’s own cart and checkout are already handled.","gloty"),rows:2,__nextHasNoMarginBottom:!0})})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Visitor redirection","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Automatically greet international visitors in the version of your site that matches their browser language.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Auto-redirect by browser language","gloty"),help:(0,l.__)("On their first visit, send visitors to their preferred language when you offer it. Applied once per visitor — a manual choice from the switcher is always respected afterwards, and search engine crawlers are never redirected.","gloty"),checked:!!i.auto_redirect,onChange:e=>m("auto_redirect",e),__nextHasNoMarginBottom:!0})})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Analytics","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Gloty counts views per language so you can see which languages are worth translating. Counting is local either way — no visitor data is stored and nothing is sent off your site.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Count views from the browser","gloty"),help:(0,l.__)("Turn this on if you run a page cache (WP Rocket, LiteSpeed, Cloudflare). Cached pages are served without starting PHP, so Gloty cannot see those views and your per-language split is both low and uneven. With this on, a small script counts the view from the browser instead, sending only the language of the page — no IP address, no page address, no referrer, no identifier of any kind. Server-side counting switches off at the same time, so each view is still counted once. The cost: a visitor with JavaScript disabled is not counted, and if a plugin combines your site’s JavaScript, exclude the “gloty-page-view-beacon” handle from it.","gloty"),checked:!!i.analytics_beacon,onChange:e=>m("analytics_beacon",e),__nextHasNoMarginBottom:!0})})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Language Switcher","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Customise the appearance and placement of the language switcher on your site.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Style","gloty"),value:i.switcher_style||"dropdown",options:gs,onChange:e=>m("switcher_style",e),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Position","gloty"),value:i.switcher_position||"bottom_right",options:_s,help:(0,l.__)("The four corners float the switcher over the page. Footer bar puts it in a strip at the end of the page instead, in the style chosen above.","gloty"),onChange:e=>m("switcher_position",e),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Show flags","gloty"),help:(0,l.__)("Display country flags next to language names in the switcher.","gloty"),checked:void 0===i.show_flags||!!i.show_flags,onChange:e=>m("show_flags",e),__nextHasNoMarginBottom:!0})})]})]}),(0,_.jsx)(ms,{}),(0,_.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:x,isBusy:d,disabled:d||!w,children:d?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),w&&(0,_.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]})]})}const fs="gloty_quota_80_dismissed";function ws({license:e,hideOnboarding:s=!1}){const[t,a]=(0,n.useState)(!1),[i,r]=(0,n.useState)([]),[o,c]=(0,n.useState)(null),[d,h]=(0,n.useState)(()=>{if("undefined"==typeof window)return!1;try{return"1"===window.sessionStorage.getItem(fs)}catch{return!1}}),g=e?.status,u=g?.characters_used??0,p=g?.characters_limit??0,m=p>0?Math.round(u/p*100):0;(0,n.useEffect)(()=>{let e=!0;return fe().then(s=>{e&&r(s)}),()=>{e=!1}},[]);const w=we(g,i)[0]||null,x=(0,n.useCallback)(async()=>{if(w){a(!0),c(null);try{const e=await y()({path:"/gloty/v1/license/checkout",method:"POST",data:{plan_slug:w.slug}});c(e?.url?be(e.url):je(e?.message))}catch(e){c(je(e?.message))}finally{a(!1)}}},[w]);if(s||!e?.hasKey||!g||m<80)return null;const v=m>=100;if(!v&&d)return null;const j=v?(0,l.__)("Translation quota exceeded. New translations are paused until the next billing period.","gloty"):(0,l.__)("You have used over 80% of your translation quota this period.","gloty");return(0,_.jsxs)(f.Notice,{status:v?"error":"warning",spokenMessage:j,isDismissible:!v,onDismiss:v?void 0:()=>{try{window.sessionStorage.setItem(fs,"1")}catch{}h(!0)},className:"wpshelf-mb",children:[(0,_.jsxs)("span",{children:[j," ",(0,_.jsxs)("strong",{children:[u.toLocaleString()," / ",p.toLocaleString()," ",(0,l.__)("characters","gloty")," (",m,"%)"]})]}),w&&(0,_.jsx)(f.Button,{variant:"link",onClick:x,isBusy:t,disabled:t,style:{marginLeft:8},children:(0,l.sprintf)(/* translators: %s: plan name, e.g. Starter */ /* translators: %s: plan name, e.g. Starter */ 35 (0,l.__)("Upgrade to %s","gloty"),w.name)}),o&&(0,_.jsx)("p",{className:"wpshelf-quota-notice__problem",children:o.message})]})}const xs=[{key:"hreflang",label:(0,l.__)("Output hreflang tags","gloty"),help:(0,l.__)("Tell search engines which language and regional URL to serve. Each page declares every active language plus an x-default — the single most important multilingual SEO signal.","gloty")},{key:"meta",label:(0,l.__)("Translate metadata & Open Graph","gloty"),help:(0,l.__)("Emit a translated meta description plus Open Graph and Twitter Card tags so shared links and search snippets appear in the visitor’s language.","gloty")},{key:"sitemap",label:(0,l.__)("Publish a sitemap of your translated pages","gloty"),help:(0,l.__)("A sitemap listing every translated URL, so search engines can find them. Separate from your main sitemap on purpose: Yoast, Rank Math, AIOSEO and SEOPress each replace the WordPress one with their own, and none of them know about translations.","gloty")},{key:"schema",label:(0,l.__)("Output language schema (JSON-LD)","gloty"),help:(0,l.__)("Declare the page language in structured data (schema.org WebSite inLanguage) for richer search results.","gloty")}];function vs({boot:e}){const s=Me(),[t,a]=(0,n.useState)(null),[i,r]=(0,n.useState)(()=>({hreflang:e?.seo?.hreflang??!0,meta:e?.seo?.meta??!0,sitemap:e?.seo?.sitemap??!0,schema:e?.seo?.schema??!0})),[o,c]=(0,n.useState)(""),[d,h]=(0,n.useState)(!!e?.seo?.seoPluginActive),[g,u]=(0,n.useState)(!0),[p,m]=(0,n.useState)(!1),[w,x]=(0,n.useState)(null),v=(0,n.useCallback)(async()=>{u(!0),x(null);try{const e=await y()({path:"/gloty/v1/settings/seo",parse:!0}),s={hreflang:!!e.hreflang,meta:!!e.meta,sitemap:!!e.sitemap,schema:!!e.schema};a(s),r(s),h(!!e.seo_plugin_active),c(e.language_sitemap_url||"")}catch(e){x({status:"error",message:e?.message||(0,l.__)("Failed to load SEO settings.","gloty")})}finally{u(!1)}},[]);(0,n.useEffect)(()=>{v()},[v]);const j=(0,n.useCallback)((e,s)=>{r(t=>({...t,[e]:s}))},[]),b=(0,n.useMemo)(()=>!!t&&JSON.stringify(i)!==JSON.stringify(t),[i,t]);if(g)return(0,_.jsxs)("div",{className:"wpshelf-skeleton",children:[(0,_.jsx)(f.Spinner,{}),(0,_.jsx)("span",{className:"wpshelf-skeleton__text",children:(0,l.__)("Loading SEO settings…","gloty")})]});const N=(0,_.jsxs)("div",{className:"wpshelf-settings-save",children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{m(!0),x(null);try{await y()({path:"/gloty/v1/settings/seo",method:"POST",data:i}),a(i),x({status:"success",message:(0,l.__)("SEO settings saved.","gloty")}),s.success((0,l.__)("SEO settings saved.","gloty"))}catch(e){const t=e?.message||(0,l.__)("Failed to save SEO settings.","gloty");x({status:"error",message:t}),s.error(t)}finally{m(!1)}},isBusy:p,disabled:p||!b,children:p?(0,l.__)("Saving…","gloty"):(0,l.__)("Save settings","gloty")}),b&&(0,_.jsx)("span",{className:"wpshelf-settings-save__hint",children:(0,l.__)("You have unsaved changes.","gloty")})]});return(0,_.jsxs)("div",{className:"wpshelf-screen wpshelf-seo-screen",children:[(0,_.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Make every translated page discoverable. Gloty follows Google’s multilingual SEO guidance — declaring language alternates, translating metadata, and keeping the right URL canonical for each language.","gloty")}),w&&(0,_.jsx)(f.Notice,{status:w.status,isDismissible:!0,onDismiss:()=>x(null),className:"wpshelf-mb",children:w.message}),N,(0,_.jsxs)(f.Card,{className:"wpshelf-settings-card wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsx)("h3",{className:"wpshelf-settings-card__title",children:(0,l.__)("Search engine optimization","gloty")})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("These run automatically on the front end. Translated titles, descriptions, and canonical URLs stay in sync with your translations — no per-page setup.","gloty")}),d&&(0,_.jsx)(f.Notice,{status:"info",isDismissible:!1,className:"wpshelf-mb",children:(0,l.__)("A dedicated SEO plugin (e.g. Yoast or Rank Math) is active, so Gloty translates its meta tags instead of emitting its own. The “Translate metadata & Open Graph” toggle only affects Gloty’s native tags, which stand down while that plugin is active.","gloty")}),i.sitemap&&o&&(0,_.jsxs)(f.Notice,{status:"info",isDismissible:!1,className:"wpshelf-mb",children:[(0,l.__)("Your translated-pages sitemap is at:","gloty")," ",(0,_.jsx)("a",{href:o,children:o}),(0,_.jsx)("br",{}),(0,l.__)("Gloty adds this to robots.txt, but an SEO plugin that manages robots.txt will replace that line with its own. If yours does, submit the address above to Google Search Console once and it is done.","gloty")]}),xs.map(e=>(0,_.jsx)("div",{className:"wpshelf-settings-field",children:(0,_.jsx)(f.ToggleControl,{label:e.label,help:e.help,checked:!!i[e.key],onChange:s=>j(e.key,s),__nextHasNoMarginBottom:!0})},e.key))]})]}),N]})}function js({boot:e,onNavigate:s}={}){const t=e?.connection?.connected??!(!e?.connection?.serviceUrl||!e?.connection?.remoteSiteId),[a,i]=(0,n.useState)(null),[r,o]=(0,n.useState)(!1),[c,d]=(0,n.useState)("full"),[h,g]=(0,n.useState)(!0),[u,m]=(0,n.useState)(!1),[w,x]=(0,n.useState)(!1),[v,j]=(0,n.useState)(null),[b,N]=(0,n.useState)(null),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(null),[B,E]=(0,n.useState)(!1),[L,M]=(0,n.useState)(null),[A,D]=(0,n.useState)(!1),[R,O]=(0,n.useState)(null),[P,$]=(0,n.useState)([]),[I,H]=(0,n.useState)(null),[G,z]=(0,n.useState)([]),[F,V]=(0,n.useState)(""),[U,q]=(0,n.useState)(!1),[W,X]=(0,n.useState)(!0),[Y,Z]=(0,n.useState)(null),J=(0,n.useCallback)(async()=>{Z(null);try{const e=F?`/gloty/v1/activity?type=${encodeURIComponent(F)}`:"/gloty/v1/activity",[s,t,a,l]=await Promise.all([y()({path:"/gloty/v1/dashboard",parse:!0}),y()({path:"/gloty/v1/scan/status",parse:!0}),y()({path:"/gloty/v1/jobs",parse:!0}),y()({path:e,parse:!0})]),n=s?.overview||{};j(n.pending_count??0),N(n.processing_count??0),S(n.source_count??0),T(n.needs_sync_sources??0),i(t),$(a?.jobs||[]),z(l?.events||[])}catch(e){Z(e?.message||(0,l.__)("Failed to load sync data","gloty"))}finally{X(!1)}},[F]);(0,n.useEffect)(()=>{J()},[J]);const[K,ee]=(0,n.useState)(!1),le=(0,n.useCallback)(async()=>{ee(!0);try{await J()}finally{ee(!1)}},[J]),ne=(0,n.useCallback)(async()=>{try{const[e,s]=await Promise.all([y()({path:"/gloty/v1/jobs",parse:!0}),y()({path:"/gloty/v1/dashboard",parse:!0})]);$(e?.jobs||[]);const t=s?.overview||{};j(t.pending_count??0),N(t.processing_count??0)}catch{}},[]),oe=(0,n.useMemo)(()=>P.some(e=>"queued"===e.status||"processing"===e.status),[P]);(0,n.useEffect)(()=>{if(!oe)return;const e=window.setInterval(ne,3e3);return()=>window.clearInterval(e)},[oe,ne]);const[ce,he]=(0,n.useState)(!1);(0,n.useEffect)(()=>{ce&&!oe&&J(),he(oe)},[oe,J,ce]);const ge=async()=>{o(!0),Z(null);try{await y()({path:"/gloty/v1/scan/start",method:"POST",data:{batch_size:20,mode:c}}),g(!0),await J()}catch(e){Z(e?.message||(0,l.__)("Scan failed","gloty"))}finally{o(!1)}},ue=(0,n.useCallback)(async()=>{o(!0),Z(null);try{await y()({path:"/gloty/v1/scan/step",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Scan step failed","gloty"))}finally{o(!1)}},[J]),_e=async(e,s)=>{H(e.id),Z(null);try{await y()({path:`/gloty/v1/jobs/${e.id}/${s}`,method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Job action failed","gloty"))}finally{H(null)}},pe=a?.cursor||{},me=a?.stats||{},ye="running"===pe.status||"processing"===pe.status,fe="paused"===pe.status,we="complete"===pe.status,xe=pe.mode||me.mode||c,ve=Number(me.processed||0),je=Number(me.queued||0),be=Number(me.last_batch||0),Ne=Number(me.failure_count||0),Ce=Number(me.phase_processed??pe.offset??0),Se=Number(me.phase_total||0),ke=Number(me.total_entities||0),Te=ke>0?Math.min(Math.round(ve/ke*100),100):0,Be=Se>0?Math.min(Math.round(Ce/Se*100),100):0,Ee=ye?(0,l.__)("Scanning now","gloty"):fe?(0,l.__)("Paused by operator","gloty"):we?(0,l.__)("Completed","gloty"):(0,l.__)("Waiting to start","gloty");(0,n.useEffect)(()=>{if(!h||!ye||r)return;const e=window.setTimeout(()=>{ue()},2500);return()=>window.clearTimeout(e)},[h,ye,r,ue]);let Le=(0,_.jsx)(f.Button,{variant:"primary",onClick:ge,isBusy:r,disabled:r,children:(0,l.__)("Scan content","gloty")});ye?Le=(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:ue,isBusy:r,disabled:r,children:(0,l.__)("Continue scan","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>x(!0),disabled:r,children:(0,l.__)("Restart","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",onClick:async()=>{o(!0),Z(null);try{await y()({path:"/gloty/v1/scan/pause",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Could not pause scan","gloty"))}finally{o(!1)}},disabled:r,children:(0,l.__)("Pause","gloty")})]}):fe?Le=(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{o(!0),Z(null);try{await y()({path:"/gloty/v1/scan/resume",method:"POST"}),await J()}catch(e){Z(e?.message||(0,l.__)("Could not resume scan","gloty"))}finally{o(!1)}},isBusy:r,disabled:r,children:(0,l.__)("Resume scan","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>x(!0),disabled:r,children:(0,l.__)("Restart","gloty")})]}):we&&(Le=(0,_.jsx)(f.Button,{variant:"secondary",onClick:ge,disabled:r,children:(0,l.__)("Run again","gloty")}));const Me=(0,n.useMemo)(()=>{const e={queued:0,processing:0,completed:0,failed:0};return P.forEach(s=>{void 0!==e[s.status]&&e[s.status]++}),e},[P]),Ae=e=>e?.payload?.job_id?`job #${e.payload.job_id}`:e?.payload?.remote_job_id?`remote ${e.payload.remote_job_id}`:e?.payload?.correlation?`corr ${e.payload.correlation}`:"—";return W?(0,_.jsx)("div",{className:"wpshelf-screen",children:(0,_.jsx)(de,{cols:5,rows:4,headers:[(0,l.__)("Job","gloty"),(0,l.__)("Language","gloty"),(0,l.__)("Segments","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Created","gloty")]})}):(0,_.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Sync workspace","gloty"),children:[(0,_.jsx)(se,{title:(0,l.__)("Sync workspace","gloty"),subtitle:(0,l.__)("Run scan and dispatch actions, then inspect jobs and events in one place.","gloty")}),Y&&(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:Y}),(0,_.jsx)("div",{"aria-live":"polite","aria-atomic":"true",className:"screen-reader-text",children:L||""}),(0,_.jsxs)("div",{className:"wpshelf-sync-actions",children:[(0,_.jsxs)(f.Card,{className:"wpshelf-sync-card wpshelf-sync-card--scan",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsxs)("div",{className:"wpshelf-sync-card__heading",children:[(0,_.jsx)("span",{className:"wpshelf-sync-card__step",children:(0,l.__)("Step 1","gloty")}),(0,_.jsx)("h3",{className:"wpshelf-sync-card__title",children:(0,l.__)("Scan content","gloty")})]})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-sync-card__desc",children:(0,l.__)("Discover posts, pages, and other content that needs translation.","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-sync-card__status",children:[(0,_.jsx)(Q,{status:pe.status||"idle"}),(0,_.jsx)("span",{className:"wpshelf-sync-card__statetext","aria-live":"polite",children:ye?(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(f.Spinner,{}),(0,l.__)("Scanning your content…","gloty")]}):Ee})]}),(0,_.jsxs)("p",{className:"wpshelf-sync-card__summary wpshelf-muted",children:[(0,l.sprintf)(/* translators: %s: number of translatable strings found */ /* translators: %s: number of translatable strings found */ 36 36 (0,l.__)("%s translatable strings found so far.","gloty"),Number(C??0).toLocaleString()),(k??0)>0&&" "+(0,l.sprintf)(/* translators: %s: number of strings not yet sent */ /* translators: %s: number of strings not yet sent */ 37 (0,l.__)("%s not yet sent for translation.","gloty"),Number(k).toLocaleString())]}),(0, u.jsxs)("div",{className:"wpshelf-sync-progress",children:[(0,u.jsxs)("div",{className:"wpshelf-sync-progress__row",children:[(0,u.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Run progress","gloty")}),(0,u.jsxs)("strong",{children:[se(ve),"/",ke?se(ke):"—"," ","(",Te,"%)"]})]}),(0,u.jsx)("div",{className:"wpshelf-sync-progress__bar"+(ye?" wpshelf-sync-progress__bar--active":""),role:"progressbar","aria-label":(0,l.__)("Scan run progress","gloty"),"aria-valuenow":Math.round(Te),"aria-valuemin":0,"aria-valuemax":100,"aria-valuetext":`${ve} of ${ke||0}`,children:(0,u.jsx)("div",{className:"wpshelf-sync-progress__fill",style:{width:`${Te}%`}})}),(0,u.jsxs)("div",{className:"wpshelf-sync-progress__row",children:[(0,u.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Current phase progress","gloty")}),(0,u.jsxs)("strong",{children:[se(Ce),"/",Se?se(Se):"—"," ","(",Be,"%)"]})]})]}),(0,u.jsx)("div",{style:{maxWidth:220,marginTop:10},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Scan mode","gloty"),value:c,options:[{label:(0,l.__)("Quick scan","gloty"),value:"quick"},{label:(0,l.__)("Full backfill","gloty"),value:"full"},{label:(0,l.__)("Incremental rescan","gloty"),value:"incremental"}],onChange:d,disabled:ye||fe||r,__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{marginTop:10},children:(0,u.jsx)(y.ToggleControl,{label:(0,l.__)("Auto-advance scan batches (recommended)","gloty"),help:(0,l.__)("Recommended. Runs the next scan batch automatically every few seconds so the scan finishes on its own. Turn off only if you want to step through batches manually.","gloty"),checked:h,disabled:!ye||r,onChange:g,__nextHasNoMarginBottom:!0})}),be>0&&(0,u.jsxs)("p",{className:"wpshelf-muted",style:{marginTop:10},children:[`Last batch: ${be} item(s)`,Ne>0?` • failures: ${Ne}`:""]}),(0,u.jsx)("div",{className:"wpshelf-row",style:{marginTop:12},children:Le}),(0,u.jsxs)("button",{type:"button",className:"wpshelf-collapsible-header wpshelf-collapsible-header--sm",onClick:()=>f(e=>!e),"aria-expanded":p,"aria-controls":"gloty-scan-details",children:[(0,u.jsx)("span",{className:"wpshelf-collapsible-header__arrow",children:p?"▾":"▸"}),(0,u.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Technical details","gloty")})]}),p&&(0,u.jsxs)("dl",{id:"gloty-scan-details",className:"wpshelf-sync-detail-grid",children:[(0,u.jsx)("dt",{children:(0,l.__)("Mode","gloty")}),(0,u.jsx)("dd",{children:xe}),(0,u.jsx)("dt",{children:(0,l.__)("Phase","gloty")}),(0,u.jsx)("dd",{children:pe.phase||(0,l.__)("posts","gloty")}),(0,u.jsx)("dt",{children:(0,l.__)("Checkpoint","gloty")}),(0,u.jsx)("dd",{children:pe.offset??0}),(0,u.jsx)("dt",{children:(0,l.__)("This run — discovered","gloty")}),(0,u.jsx)("dd",{children:ve}),(0,u.jsx)("dt",{children:(0,l.__)("This run — queued","gloty")}),(0,u.jsx)("dd",{children:je}),(0,u.jsx)("dt",{children:(0,l.__)("Registry sources","gloty")}),(0,u.jsx)("dd",{children:C??0})]})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-sync-card wpshelf-sync-card--translate",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsxs)("div",{className:"wpshelf-sync-card__heading",children:[(0,u.jsx)("span",{className:"wpshelf-sync-card__step",children:(0,l.__)("Step 2","gloty")}),(0,u.jsx)("h3",{className:"wpshelf-sync-card__title",children:(0,l.__)("Generate translations","gloty")})]})}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-sync-card__desc",children:(0,l.__)("Send pending strings to your translation provider for processing.","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-sync-card__meta",children:[(0,u.jsxs)("span",{children:[(0,u.jsx)("strong",{children:Number(v??0).toLocaleString()})," ",(0,l.__)("translations queued to send","gloty")]}),0===(v??0)&&(k??0)>0&&(0,u.jsxs)("span",{className:"wpshelf-muted",style:{display:"block",marginTop:6},children:[(0,u.jsx)("strong",{children:se(k)})," ",(0,l.__)("source item(s) discovered and waiting to be sent","gloty")]}),(b??0)>0&&(0,u.jsxs)("span",{className:"wpshelf-muted",style:{display:"block",marginTop:6},children:[(0,u.jsx)("strong",{children:se(b)})," ",(0,l.__)("currently being translated by the provider","gloty")]})]}),(v??0)>0&&(0,u.jsx)("p",{className:"wpshelf-sync-card__hint wpshelf-muted",children:(0,l.__)("These are sent to your AI provider and count toward your monthly character quota. Translations usually appear within a minute or two — track progress in Recent jobs below.","gloty")}),L&&(0,u.jsx)(y.Notice,{status:A?"error":"success",isDismissible:!1,className:"wpshelf-mt",children:L}),R&&R.dispatched>0&&(0,u.jsxs)("p",{className:"wpshelf-muted wpshelf-mt",children:[`${R.dispatched} batch(es) dispatched`,R.remaining>0?` • ${R.remaining} string(s) still processing`:" • backlog cleared"]}),t?(0,u.jsxs)(u.Fragment,{children:[0===(v??0)&&0===(k??0)&&(0,u.jsx)("p",{className:"wpshelf-sync-card__hint wpshelf-muted",children:(0,l.__)("Nothing pending yet — run a scan in Step 1 to discover translatable content first.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-row",style:{marginTop:12},children:(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{E(!0),M(null),D(!1),O(null);let e=0;try{for(let s=0;s<100;s++){const s=await m()({path:"/gloty/v1/jobs/dispatch",method:"POST",parse:!0});if(!1===s?.ok){D(!0),M(s?.error||s?.message||(0,l.__)("Failed to dispatch translation jobs.","gloty"));break}const t=Number(s?.dispatched||0),a=Number(s?.remaining||0);if(e+=t,M(s?.message||(0,l.__)("Dispatching translation jobs…","gloty")),O({dispatched:e,remaining:a,stage:s?.stage||""}),await J(),0===a||!1===s?.quota_ok||0===t)break;await new Promise(e=>setTimeout(e,2e3))}}catch(e){M(e?.message||(0,l.__)("Failed to start translations","gloty")),D(!0)}finally{E(!1)}},isBusy:B,disabled:B||0===(v??0)&&0===(k??0),children:(0,l.__)("Translate now","gloty")})})]}):(0,u.jsxs)(y.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",spokenMessage:(0,l.__)("Translator service not connected. Translations can’t be sent until this site is connected to the Gloty service.","gloty"),children:[(0,u.jsx)("strong",{children:(0,l.__)("Translator service not connected.","gloty")})," ",(0,l.__)("Translations can’t be sent until this site is connected to the Gloty service.","gloty"),s&&(0,u.jsx)("div",{className:"wpshelf-row",style:{marginTop:10},children:(0,u.jsx)(y.Button,{variant:"primary",onClick:()=>s("onboarding"),children:(0,l.__)("Connect now","gloty")})})]})]})]})]}),(0,u.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",children:[(0,u.jsx)("h3",{className:"wpshelf-section-heading",style:{margin:0,border:0,padding:0},children:(0,l.__)("Recent jobs","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",onClick:le,isSmall:!0,isBusy:Q,disabled:Q,"aria-live":"polite",children:Q?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]}),P.length>0&&(0,u.jsx)("div",{className:"wpshelf-row",style:{gap:16,margin:"8px 0 12px"},children:Object.entries(Me).filter(([,e])=>e>0).map(([e,s])=>(0,u.jsxs)("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[(0,u.jsx)(K,{status:e}),(0,u.jsx)("strong",{children:s})]},e))}),0===P.length?(0,u.jsx)(ne,{title:(0,l.__)("No jobs yet","gloty"),hint:(0,l.__)('Jobs appear here after you click "Translate now".',"gloty")}):(0,u.jsxs)(_,{className:"wp-list-table widefat striped",style:{marginBottom:24},children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Status","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Segments","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Correlation","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Created","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Updated","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Diagnostics","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Actions","gloty")})]})}),(0,u.jsx)("tbody",{children:P.map(e=>(0,u.jsxs)("tr",{children:[(0,u.jsx)("td",{children:(0,u.jsx)(K,{status:e.status})}),(0,u.jsx)("td",{children:se(e.segment_count||0)}),(0,u.jsx)("td",{children:(0,u.jsx)("code",{children:e.correlation_id||"—"})}),(0,u.jsx)("td",{className:"wpshelf-muted",children:te(e.created_at)}),(0,u.jsx)("td",{className:"wpshelf-muted",children:te(e.updated_at)}),(0,u.jsx)("td",{children:e.error_message?(0,u.jsx)("span",{className:"wpshelf-sync-diagnostic wpshelf-sync-diagnostic--error",children:e.error_message}):(0,u.jsx)("span",{className:"wpshelf-muted",children:e.remote_job_id?`remote: ${e.remote_job_id}`:(0,l.__)("No errors","gloty")})}),(0,u.jsx)("td",{children:(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:["failed"===e.status&&(0,u.jsx)(y.Button,{variant:"secondary",isSmall:!0,onClick:()=>_e(e,"retry"),disabled:null!==I,isBusy:I===e.id,children:(0,l.__)("Retry","gloty")}),("queued"===e.status||"processing"===e.status)&&(0,u.jsx)(y.Button,{variant:"tertiary",isSmall:!0,onClick:()=>_e(e,"cancel"),disabled:null!==I,isBusy:I===e.id,children:(0,l.__)("Cancel","gloty")})]})})]},e.id))})]}),(0,u.jsxs)("button",{type:"button",className:"wpshelf-collapsible-header",onClick:()=>q(!U),"aria-expanded":U,"aria-controls":"gloty-event-log",children:[(0,u.jsx)("span",{className:"wpshelf-collapsible-header__arrow",children:U?"▾":"▸"}),(0,u.jsx)("h3",{className:"wpshelf-section-heading",style:{margin:0,border:0,padding:0},children:(0,l.__)("Event log","gloty")})]}),U&&(0,u.jsxs)("div",{id:"gloty-event-log",children:[(0,u.jsx)("div",{style:{maxWidth:280,margin:"12px 0"},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Filter by type","gloty"),value:F,options:[{label:(0,l.__)("All types","gloty"),value:""},{label:(0,l.__)("Sync","gloty"),value:"sync.dispatch"},{label:(0,l.__)("Webhook","gloty"),value:"sync.webhook"},{label:(0,l.__)("Translation","gloty"),value:"translation.update"},{label:(0,l.__)("Scan","gloty"),value:"scan.progress"}],onChange:V,__nextHasNoMarginBottom:!0})}),0===G.length?(0,u.jsx)(ne,{title:(0,l.__)("No events yet","gloty"),hint:(0,l.__)("Events appear after scans, syncs, and translation updates.","gloty")}):(0,u.jsxs)(_,{className:"wp-list-table widefat striped",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{scope:"col",children:(0,l.__)("When","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Type","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Message","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Context","gloty")})]})}),(0,u.jsx)("tbody",{children:G.map(e=>(0,u.jsxs)("tr",{children:[(0,u.jsx)("td",{className:"wpshelf-muted",children:te(e.created_at)}),(0,u.jsx)("td",{children:(0,u.jsx)("code",{children:e.type})}),(0,u.jsx)("td",{children:e.message}),(0,u.jsx)("td",{className:"wpshelf-muted",children:Ae(e)})]},e.id))})]})]}),w&&(0,u.jsx)(ie,{title:(0,l.__)("Restart scan?","gloty"),message:(0,l.__)("This starts the scan over from the beginning. Already-discovered strings stay saved — nothing is deleted — but the current run’s progress resets to zero.","gloty"),confirmLabel:(0,l.__)("Restart scan","gloty"),isDestructive:!1,busy:r,onConfirm:()=>{x(!1),ge()},onCancel:()=>x(!1)})]})}var js=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})}),bs=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})}),Ns=(0,u.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,u.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z"})});function Cs(e){const s=ae(e?.original_text),t=ae(e?.translated_text),a=function(e,s,t){return""===e?(0,l.__)("This row has no plain text to use as a term.","gloty"):""===s?(0,l.__)("Translate this row first — there is nothing to promote yet.","gloty"):""===t?(0,l.__)("This row has no target language.","gloty"):e.length>191?(0,l.sprintf)(/* translators: %d: maximum number of characters a glossary term may have. */ /* translators: %d: maximum number of characters a glossary term may have. */38 (0,l.__)("Glossary terms are brand and product names, up to %d characters. This row is longer than that.","gloty"),191):""}(s,t,String(e?.target_language||"").trim().toLowerCase());return{eligible:""===a,reason:a,term:s,translated:t,verbatim:""!==s&&s===t}}function Ss(e,s=80){return e?e.length>s?e.slice(0,s)+"…":e:"—"}function ks(e){const s=String(e||"");if(!s)return{label:"—",title:""};const t=s.split(":");if("gloty"===t[0]&&"e"===t[1]){const e=t[2];if("post"===e||"term"===e){const a=t[3],n="post"===e?(0,l.__)("Post","gloty"):(0,l.__)("Term","gloty");let i=t.slice(4).join(":");const r=i.match(/^content:s(\d+)$/);r&&(i=(0,l.sprintf)(/* translators: %s: segment number within a post body */ /* translators: %s: segment number within a post body */37 (0,l.__)("%s not yet sent for translation.","gloty"),Number(k).toLocaleString())]}),(0,_.jsxs)("div",{className:"wpshelf-sync-progress",children:[(0,_.jsxs)("div",{className:"wpshelf-sync-progress__row",children:[(0,_.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Run progress","gloty")}),(0,_.jsxs)("strong",{children:[te(ve),"/",ke?te(ke):"—"," ","(",Te,"%)"]})]}),(0,_.jsx)("div",{className:"wpshelf-sync-progress__bar"+(ye?" wpshelf-sync-progress__bar--active":""),role:"progressbar","aria-label":(0,l.__)("Scan run progress","gloty"),"aria-valuenow":Math.round(Te),"aria-valuemin":0,"aria-valuemax":100,"aria-valuetext":`${ve} of ${ke||0}`,children:(0,_.jsx)("div",{className:"wpshelf-sync-progress__fill",style:{width:`${Te}%`}})}),(0,_.jsxs)("div",{className:"wpshelf-sync-progress__row",children:[(0,_.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Current phase progress","gloty")}),(0,_.jsxs)("strong",{children:[te(Ce),"/",Se?te(Se):"—"," ","(",Be,"%)"]})]})]}),(0,_.jsx)("div",{style:{maxWidth:220,marginTop:10},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Scan mode","gloty"),value:c,options:[{label:(0,l.__)("Quick scan","gloty"),value:"quick"},{label:(0,l.__)("Full backfill","gloty"),value:"full"},{label:(0,l.__)("Incremental rescan","gloty"),value:"incremental"}],onChange:d,disabled:ye||fe||r,__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{marginTop:10},children:(0,_.jsx)(f.ToggleControl,{label:(0,l.__)("Auto-advance scan batches (recommended)","gloty"),help:(0,l.__)("Recommended. Runs the next scan batch automatically every few seconds so the scan finishes on its own. Turn off only if you want to step through batches manually.","gloty"),checked:h,disabled:!ye||r,onChange:g,__nextHasNoMarginBottom:!0})}),be>0&&(0,_.jsxs)("p",{className:"wpshelf-muted",style:{marginTop:10},children:[`Last batch: ${be} item(s)`,Ne>0?` • failures: ${Ne}`:""]}),(0,_.jsx)("div",{className:"wpshelf-row",style:{marginTop:12},children:Le}),(0,_.jsxs)("button",{type:"button",className:"wpshelf-collapsible-header wpshelf-collapsible-header--sm",onClick:()=>m(e=>!e),"aria-expanded":u,"aria-controls":"gloty-scan-details",children:[(0,_.jsx)("span",{className:"wpshelf-collapsible-header__arrow",children:u?"▾":"▸"}),(0,_.jsx)("span",{className:"wpshelf-muted",children:(0,l.__)("Technical details","gloty")})]}),u&&(0,_.jsxs)("dl",{id:"gloty-scan-details",className:"wpshelf-sync-detail-grid",children:[(0,_.jsx)("dt",{children:(0,l.__)("Mode","gloty")}),(0,_.jsx)("dd",{children:xe}),(0,_.jsx)("dt",{children:(0,l.__)("Phase","gloty")}),(0,_.jsx)("dd",{children:pe.phase||(0,l.__)("posts","gloty")}),(0,_.jsx)("dt",{children:(0,l.__)("Checkpoint","gloty")}),(0,_.jsx)("dd",{children:pe.offset??0}),(0,_.jsx)("dt",{children:(0,l.__)("This run — discovered","gloty")}),(0,_.jsx)("dd",{children:ve}),(0,_.jsx)("dt",{children:(0,l.__)("This run — queued","gloty")}),(0,_.jsx)("dd",{children:je}),(0,_.jsx)("dt",{children:(0,l.__)("Registry sources","gloty")}),(0,_.jsx)("dd",{children:C??0})]})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-sync-card wpshelf-sync-card--translate",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsxs)("div",{className:"wpshelf-sync-card__heading",children:[(0,_.jsx)("span",{className:"wpshelf-sync-card__step",children:(0,l.__)("Step 2","gloty")}),(0,_.jsx)("h3",{className:"wpshelf-sync-card__title",children:(0,l.__)("Generate translations","gloty")})]})}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-sync-card__desc",children:(0,l.__)("Send pending strings to your translation provider for processing.","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-sync-card__meta",children:[(0,_.jsxs)("span",{children:[(0,_.jsx)("strong",{children:Number(v??0).toLocaleString()})," ",(0,l.__)("translations queued to send","gloty")]}),0===(v??0)&&(k??0)>0&&(0,_.jsxs)("span",{className:"wpshelf-muted",style:{display:"block",marginTop:6},children:[(0,_.jsx)("strong",{children:te(k)})," ",(0,l.__)("source item(s) discovered and waiting to be sent","gloty")]}),(b??0)>0&&(0,_.jsxs)("span",{className:"wpshelf-muted",style:{display:"block",marginTop:6},children:[(0,_.jsx)("strong",{children:te(b)})," ",(0,l.__)("currently being translated by the provider","gloty")]})]}),(v??0)>0&&(0,_.jsx)("p",{className:"wpshelf-sync-card__hint wpshelf-muted",children:(0,l.__)("These are sent to your AI provider and count toward your monthly character quota. Translations usually appear within a minute or two — track progress in Recent jobs below.","gloty")}),L&&(0,_.jsx)(f.Notice,{status:A?"error":"success",isDismissible:!1,className:"wpshelf-mt",children:L}),R&&R.dispatched>0&&(0,_.jsxs)("p",{className:"wpshelf-muted wpshelf-mt",children:[`${R.dispatched} batch(es) dispatched`,R.remaining>0?` • ${R.remaining} string(s) still processing`:" • backlog cleared"]}),t?(0,_.jsxs)(_.Fragment,{children:[0===(v??0)&&0===(k??0)&&(0,_.jsx)("p",{className:"wpshelf-sync-card__hint wpshelf-muted",children:(0,l.__)("Nothing pending yet — run a scan in Step 1 to discover translatable content first.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-row",style:{marginTop:12},children:(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{E(!0),M(null),D(!1),O(null);let e=0;try{for(let s=0;s<100;s++){const s=await y()({path:"/gloty/v1/jobs/dispatch",method:"POST",parse:!0});if(!1===s?.ok){D(!0),M(s?.error||s?.message||(0,l.__)("Failed to dispatch translation jobs.","gloty"));break}const t=Number(s?.dispatched||0),a=Number(s?.remaining||0);if(e+=t,M(s?.message||(0,l.__)("Dispatching translation jobs…","gloty")),O({dispatched:e,remaining:a,stage:s?.stage||""}),await J(),0===a||!1===s?.quota_ok||0===t)break;await new Promise(e=>setTimeout(e,2e3))}}catch(e){M(e?.message||(0,l.__)("Failed to start translations","gloty")),D(!0)}finally{E(!1)}},isBusy:B,disabled:B||0===(v??0)&&0===(k??0),children:(0,l.__)("Translate now","gloty")})})]}):(0,_.jsxs)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",spokenMessage:(0,l.__)("Translator service not connected. Translations can’t be sent until this site is connected to the Gloty service.","gloty"),children:[(0,_.jsx)("strong",{children:(0,l.__)("Translator service not connected.","gloty")})," ",(0,l.__)("Translations can’t be sent until this site is connected to the Gloty service.","gloty"),s&&(0,_.jsx)("div",{className:"wpshelf-row",style:{marginTop:10},children:(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>s("onboarding"),children:(0,l.__)("Connect now","gloty")})})]})]})]})]}),(0,_.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",children:[(0,_.jsx)("h3",{className:"wpshelf-section-heading",style:{margin:0,border:0,padding:0},children:(0,l.__)("Recent jobs","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",onClick:le,isSmall:!0,isBusy:K,disabled:K,"aria-live":"polite",children:K?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]}),P.length>0&&(0,_.jsx)("div",{className:"wpshelf-row",style:{gap:16,margin:"8px 0 12px"},children:Object.entries(Me).filter(([,e])=>e>0).map(([e,s])=>(0,_.jsxs)("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[(0,_.jsx)(Q,{status:e}),(0,_.jsx)("strong",{children:s})]},e))}),0===P.length?(0,_.jsx)(ie,{title:(0,l.__)("No jobs yet","gloty"),hint:(0,l.__)('Jobs appear here after you click "Translate now".',"gloty")}):(0,_.jsxs)(p,{className:"wp-list-table widefat striped",style:{marginBottom:24},children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Status","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Segments","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Correlation","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Created","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Updated","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Diagnostics","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Actions","gloty")})]})}),(0,_.jsx)("tbody",{children:P.map(e=>(0,_.jsxs)("tr",{children:[(0,_.jsx)("td",{children:(0,_.jsx)(Q,{status:e.status})}),(0,_.jsx)("td",{children:te(e.segment_count||0)}),(0,_.jsx)("td",{children:(0,_.jsx)("code",{children:e.correlation_id||"—"})}),(0,_.jsx)("td",{className:"wpshelf-muted",children:ae(e.created_at)}),(0,_.jsx)("td",{className:"wpshelf-muted",children:ae(e.updated_at)}),(0,_.jsx)("td",{children:e.error_message?(0,_.jsx)("span",{className:"wpshelf-sync-diagnostic wpshelf-sync-diagnostic--error",children:e.error_message}):(0,_.jsx)("span",{className:"wpshelf-muted",children:e.remote_job_id?`remote: ${e.remote_job_id}`:(0,l.__)("No errors","gloty")})}),(0,_.jsx)("td",{children:(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:["failed"===e.status&&(0,_.jsx)(f.Button,{variant:"secondary",isSmall:!0,onClick:()=>_e(e,"retry"),disabled:null!==I,isBusy:I===e.id,children:(0,l.__)("Retry","gloty")}),("queued"===e.status||"processing"===e.status)&&(0,_.jsx)(f.Button,{variant:"tertiary",isSmall:!0,onClick:()=>_e(e,"cancel"),disabled:null!==I,isBusy:I===e.id,children:(0,l.__)("Cancel","gloty")})]})})]},e.id))})]}),(0,_.jsxs)("button",{type:"button",className:"wpshelf-collapsible-header",onClick:()=>q(!U),"aria-expanded":U,"aria-controls":"gloty-event-log",children:[(0,_.jsx)("span",{className:"wpshelf-collapsible-header__arrow",children:U?"▾":"▸"}),(0,_.jsx)("h3",{className:"wpshelf-section-heading",style:{margin:0,border:0,padding:0},children:(0,l.__)("Event log","gloty")})]}),U&&(0,_.jsxs)("div",{id:"gloty-event-log",children:[(0,_.jsx)("div",{style:{maxWidth:280,margin:"12px 0"},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Filter by type","gloty"),value:F,options:[{label:(0,l.__)("All types","gloty"),value:""},{label:(0,l.__)("Sync","gloty"),value:"sync.dispatch"},{label:(0,l.__)("Webhook","gloty"),value:"sync.webhook"},{label:(0,l.__)("Translation","gloty"),value:"translation.update"},{label:(0,l.__)("Scan","gloty"),value:"scan.progress"}],onChange:V,__nextHasNoMarginBottom:!0})}),0===G.length?(0,_.jsx)(ie,{title:(0,l.__)("No events yet","gloty"),hint:(0,l.__)("Events appear after scans, syncs, and translation updates.","gloty")}):(0,_.jsxs)(p,{className:"wp-list-table widefat striped",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{scope:"col",children:(0,l.__)("When","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Type","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Message","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Context","gloty")})]})}),(0,_.jsx)("tbody",{children:G.map(e=>(0,_.jsxs)("tr",{children:[(0,_.jsx)("td",{className:"wpshelf-muted",children:ae(e.created_at)}),(0,_.jsx)("td",{children:(0,_.jsx)("code",{children:e.type})}),(0,_.jsx)("td",{children:e.message}),(0,_.jsx)("td",{className:"wpshelf-muted",children:Ae(e)})]},e.id))})]})]}),w&&(0,_.jsx)(re,{title:(0,l.__)("Restart scan?","gloty"),message:(0,l.__)("This starts the scan over from the beginning. Already-discovered strings stay saved — nothing is deleted — but the current run’s progress resets to zero.","gloty"),confirmLabel:(0,l.__)("Restart scan","gloty"),isDestructive:!1,busy:r,onConfirm:()=>{x(!1),ge()},onCancel:()=>x(!1)})]})}var bs=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})}),Ns=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})}),Cs=(0,_.jsx)(v.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,_.jsx)(v.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z"})});function Ss(e){const s=le(e?.original_text),t=le(e?.translated_text),a=function(e,s,t){return""===e?(0,l.__)("This row has no plain text to use as a term.","gloty"):""===s?(0,l.__)("Translate this row first — there is nothing to promote yet.","gloty"):""===t?(0,l.__)("This row has no target language.","gloty"):e.length>191?(0,l.sprintf)(/* translators: %d: maximum number of characters a glossary term may have. */ /* translators: %d: maximum number of characters a glossary term may have. */ 38 (0,l.__)("Glossary terms are brand and product names, up to %d characters. This row is longer than that.","gloty"),191):""}(s,t,String(e?.target_language||"").trim().toLowerCase());return{eligible:""===a,reason:a,term:s,translated:t,verbatim:""!==s&&s===t}}function ks(e,s=80){return e?e.length>s?e.slice(0,s)+"…":e:"—"}function Ts(e){const s=String(e||"");if(!s)return{label:"—",title:""};const t=s.split(":");if("gloty"===t[0]&&"e"===t[1]){const e=t[2];if("post"===e||"term"===e){const a=t[3],n="post"===e?(0,l.__)("Post","gloty"):(0,l.__)("Term","gloty");let i=t.slice(4).join(":");const r=i.match(/^content:s(\d+)$/);r&&(i=(0,l.sprintf)(/* translators: %s: segment number within a post body */ /* translators: %s: segment number within a post body */ 39 39 (0,l.__)("content, part %s","gloty"),r[1]));let o=a?`${n} #${a}`:n;return i&&(o+=` · ${i}`),{label:o,title:s}}if("option"===e)return{label:(0,l.sprintf)(/* translators: %s: WordPress option name */ /* translators: %s: WordPress option name */ 40 (0,l.__)("Site option: %s","gloty"),t.slice(3).join(":")),title:s}}return"gloty"===t[0]?{label:(0,l.__)("Theme / UI string","gloty"),title:s}:{label:s,title:s}}function Ts({boot:e,filters:s=null}){const t=Le(),[a,i]=(0,n.useState)([]),[r,o]=(0,n.useState)(0),[c,d]=(0,n.useState)(1),[h,g]=(0,n.useState)(1),[p,f]=(0,n.useState)(!0),[w,x]=(0,n.useState)(null),[v,j]=(0,n.useState)(()=>s?.target_language||""),[b,N]=(0,n.useState)(()=>s?.status||""),[S,k]=(0,n.useState)(()=>s?.stale||""),[B,E]=(0,n.useState)(()=>s?.echoed||""),[L,M]=(0,n.useState)(""),[A,D]=(0,n.useState)(""),[R,O]=(0,n.useState)(null),[P,$]=(0,n.useState)(null),[I,H]=(0,n.useState)(""),[G,z]=(0,n.useState)(!1),[F,V]=(0,n.useState)(()=>new Set),[U,q]=(0,n.useState)(!1),[W,X]=(0,n.useState)(null),[Y,Z]=(0,n.useState)(null),[J,Q]=(0,n.useState)(""),[oe,de]=(0,n.useState)(!1),he=(0,n.useRef)(null),ge=(0,n.useMemo)(()=>{const s=e?.language?.active||[],t=e?.language?.default||"en";return s.filter(e=>e!==t)},[e]),ue=(0,n.useMemo)(()=>[{label:(0,l.__)("All languages","gloty"),value:""},...ge.map(e=>{const s=Qe(e);return{label:s?.native_name?`${s.native_name} (${e})`:e,value:e}})],[ge]),_e=(0,n.useCallback)(async()=>{f(!0),x(null),V(new Set);try{const e=function({page:e,perPage:s,langFilter:t="",statusFilter:a="",staleFilter:l="",searchQuery:n="",echoedFilter:i=""}){const r=new URLSearchParams({page:String(e),per_page:String(s)});return t&&r.set("target_language",t),"1"===i?(r.set("echoed","1"),r):(a&&r.set("status",a),l&&r.set("stale",l),n&&r.set("search",n),r)}({page:h,perPage:25,langFilter:v,statusFilter:b,staleFilter:S,searchQuery:L,echoedFilter:B}),s=await m()({path:`/gloty/v1/translations?${e}`,parse:!0});i(s.items||[]),o(s.total||0),d(s.total_pages||1)}catch(e){x(e?.message||(0,l.__)("Failed to load translations.","gloty"))}finally{f(!1)}},[h,v,b,S,L,B]);(0,n.useEffect)(()=>{_e()},[_e]),(0,n.useEffect)(()=>{s&&(j(s.target_language||""),N(s.status||""),k(s.stale||""),E(s.echoed||""),D(""),M(""),g(1))},[s]),(0,n.useEffect)(()=>{!p&&0===a.length&&h>1&&h>c&&g(Math.max(1,c))},[p,a.length,h,c]),(0,n.useEffect)(()=>{if(A===L)return;const e=window.setTimeout(()=>{M(A),g(1)},400);return()=>window.clearTimeout(e)},[A,L]);const pe=(0,n.useMemo)(()=>a.map(e=>Number(e.id)),[a]),ye=pe.length>0&&pe.every(e=>F.has(e)),fe=!ye&&pe.some(e=>F.has(e)),we=()=>V(new Set),xe=e=>{Z(Number(e.id)),Q(e.translated_text||""),window.requestAnimationFrame(()=>{he.current&&he.current.focus()})},ve=async()=>{if(!Y)return;const e=a.find(e=>Number(e.id)===Y);if(e&&J===(e.translated_text||""))Z(null);else if(""!==J){if(!oe){de(!0);try{await m()({path:`/gloty/v1/translations/${Y}`,method:"POST",data:{translated_text:J}}),t.success((0,l.__)("Translation saved.","gloty")),Z(null),await _e()}catch(e){t.error(e?.message||(0,l.__)("Failed to save.","gloty"))}finally{de(!1)}}}else je()},je=()=>{Z(null),Q("")};return p&&0===a.length?(0,u.jsx)("div",{className:"wpshelf-screen",children:(0,u.jsx)(ce,{cols:6,rows:6,headers:["",(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Lang","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Actions","gloty")]})}):(0,u.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Translations workspace","gloty"),children:[(0,u.jsx)(ee,{title:(0,l.__)("Translations workspace","gloty"),subtitle:(0,l.__)("Filter, inspect, and curate cached translations. Manual edits are protected from machine overwrite.","gloty")}),w&&(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:w}),"1"===B&&(0,u.jsxs)(y.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mb",children:[(0,l.sprintf)(/* translators: %s: number of rows */ /* translators: %s: number of rows */41 (0,l._n)('Showing the %s row the "identical to its source" warning counts.','Showing the %s rows the "identical to its source" warning counts.',r,"gloty"), se(r))," ",(0,l.__)("These are the rows behind that number, read from the same scan it was counted with — product names, codes and text already written in the target language are already left out. Deleting a row asks for that text to be translated again, which spends your allowance, so read the list before removing anything. Status, staleness and search do not narrow this view.","gloty")]}),(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsx)(y.CardBody,{children:(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:12,flexWrap:"wrap"},children:[(0,u.jsx)("div",{style:{minWidth:240,flex:"1 1 240px",maxWidth:360},children:(0,u.jsx)(y.SearchControl,{label:(0,l.__)("Search translations","gloty"),value:A,disabled:"1"===B,onChange:D,onKeyDown:e=>{"Enter"===e.key&&(M(A),g(1))},onClose:A?()=>{D(""),M(""),g(1)}:void 0,placeholder:(0,l.__)("Search source or translated text…","gloty"),__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{minWidth:160},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Target language","gloty"),value:v,options:ue,onChange:e=>{j(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{minWidth:160},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Status","gloty"),value:b,options:[{label:(0,l.__)("All statuses","gloty"),value:""},{label:(0,l.__)("Translated (synced or edited)","gloty"),value:"translated"},{label:(0,l.__)("Synced","gloty"),value:"auto"},{label:(0,l.__)("Manually edited","gloty"),value:"manual"},{label:(0,l.__)("Pending","gloty"),value:"pending"},{label:(0,l.__)("Processing","gloty"),value:"processing"}],disabled:"1"===B,onChange:e=>{N(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{minWidth:160},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Stale","gloty"),value:S,options:[{label:(0,l.__)("All","gloty"),value:""},{label:(0,l.__)("Stale only","gloty"),value:"1"},{label:(0,l.__)("Fresh only","gloty"),value:"0"}],disabled:"1"===B,onChange:e=>{k(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{minWidth:200},children:(0,u.jsx)(y.SelectControl,{label:(0,l.__)("Flagged","gloty"),value:B,help:"1"===B?(0,l.__)("The rows the Overview warning counts.","gloty"):void 0,options:[{label:(0,l.__)("Not filtered","gloty"),value:""},{label:(0,l.__)("Identical to its source","gloty"),value:"1"}],onChange:e=>{E(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,u.jsx)("div",{style:{display:"flex",alignItems:"flex-end",marginLeft:"auto"},children:(0,u.jsxs)("span",{className:"wpshelf-muted",children:[se(r)," ",(0,l.__)("rows","gloty")]})})]})})}),F.size>0&&(0,u.jsx)(y.Card,{className:"wpshelf-mb",children:(0,u.jsx)(y.CardBody,{children:(0,u.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{alignItems:"center"},children:[(0,u.jsx)("span",{children:(0,l.sprintf)(/* translators: %d: number of rows currently selected */ /* translators: %d: number of rows currently selected */42 (0,l.__)("%d selected","gloty"),F.size)}),(0, u.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:[(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{const e=Array.from(F);if(0!==e.length){q(!0);try{const s=await m()({path:"/gloty/v1/translations/dispatch-selected",method:"POST",data:{ids:e,mode:"dispatch"}}),a=s?.dispatch?.stage||null,n=!!s?.dispatch?.created;let i;i="not_connected"===a?(0,l.__)("Re-queued — but the translator service is not connected yet.","gloty"):"quota_exceeded"===a?(0,l.__)("Re-queued — but your character quota is exhausted. Upgrade your plan to dispatch.","gloty"):n?(0,l.sprintf)(/* translators: %d: number of translation rows re-queued */ /* translators: %d: number of translation rows re-queued */40 (0,l.__)("Site option: %s","gloty"),t.slice(3).join(":")),title:s}}return"gloty"===t[0]?{label:(0,l.__)("Theme / UI string","gloty"),title:s}:{label:s,title:s}}function Bs({boot:e,filters:s=null}){const t=Me(),[a,i]=(0,n.useState)([]),[r,o]=(0,n.useState)(0),[c,d]=(0,n.useState)(1),[h,g]=(0,n.useState)(1),[u,m]=(0,n.useState)(!0),[w,x]=(0,n.useState)(null),[v,j]=(0,n.useState)(()=>s?.target_language||""),[b,N]=(0,n.useState)(()=>s?.status||""),[C,k]=(0,n.useState)(()=>s?.stale||""),[T,E]=(0,n.useState)(()=>s?.echoed||""),[L,M]=(0,n.useState)(""),[A,D]=(0,n.useState)(""),[R,O]=(0,n.useState)(null),[P,$]=(0,n.useState)(null),[I,H]=(0,n.useState)(""),[G,z]=(0,n.useState)(!1),[F,V]=(0,n.useState)(()=>new Set),[U,q]=(0,n.useState)(!1),[W,X]=(0,n.useState)(null),[Y,Z]=(0,n.useState)(null),[J,K]=(0,n.useState)(""),[ee,ce]=(0,n.useState)(!1),he=(0,n.useRef)(null),ge=(0,n.useMemo)(()=>{const s=e?.language?.active||[],t=e?.language?.default||"en";return s.filter(e=>e!==t)},[e]),ue=(0,n.useMemo)(()=>[{label:(0,l.__)("All languages","gloty"),value:""},...ge.map(e=>{const s=es(e);return{label:s?.native_name?`${s.native_name} (${e})`:e,value:e}})],[ge]),_e=(0,n.useCallback)(async()=>{m(!0),x(null),V(new Set);try{const e=function({page:e,perPage:s,langFilter:t="",statusFilter:a="",staleFilter:l="",searchQuery:n="",echoedFilter:i=""}){const r=new URLSearchParams({page:String(e),per_page:String(s)});return t&&r.set("target_language",t),"1"===i?(r.set("echoed","1"),r):(a&&r.set("status",a),l&&r.set("stale",l),n&&r.set("search",n),r)}({page:h,perPage:25,langFilter:v,statusFilter:b,staleFilter:C,searchQuery:L,echoedFilter:T}),s=await y()({path:`/gloty/v1/translations?${e}`,parse:!0});i(s.items||[]),o(s.total||0),d(s.total_pages||1)}catch(e){x(e?.message||(0,l.__)("Failed to load translations.","gloty"))}finally{m(!1)}},[h,v,b,C,L,T]);(0,n.useEffect)(()=>{_e()},[_e]),(0,n.useEffect)(()=>{s&&(j(s.target_language||""),N(s.status||""),k(s.stale||""),E(s.echoed||""),D(""),M(""),g(1))},[s]),(0,n.useEffect)(()=>{!u&&0===a.length&&h>1&&h>c&&g(Math.max(1,c))},[u,a.length,h,c]),(0,n.useEffect)(()=>{if(A===L)return;const e=window.setTimeout(()=>{M(A),g(1)},400);return()=>window.clearTimeout(e)},[A,L]);const pe=(0,n.useMemo)(()=>a.map(e=>Number(e.id)),[a]),me=pe.length>0&&pe.every(e=>F.has(e)),fe=!me&&pe.some(e=>F.has(e)),we=()=>V(new Set),xe=e=>{Z(Number(e.id)),K(e.translated_text||""),window.requestAnimationFrame(()=>{he.current&&he.current.focus()})},ve=async()=>{if(!Y)return;const e=a.find(e=>Number(e.id)===Y);if(e&&J===(e.translated_text||""))Z(null);else if(""!==J){if(!ee){ce(!0);try{await y()({path:`/gloty/v1/translations/${Y}`,method:"POST",data:{translated_text:J}}),t.success((0,l.__)("Translation saved.","gloty")),Z(null),await _e()}catch(e){t.error(e?.message||(0,l.__)("Failed to save.","gloty"))}finally{ce(!1)}}}else je()},je=()=>{Z(null),K("")};return u&&0===a.length?(0,_.jsx)("div",{className:"wpshelf-screen",children:(0,_.jsx)(de,{cols:6,rows:6,headers:["",(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Lang","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Actions","gloty")]})}):(0,_.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Translations workspace","gloty"),children:[(0,_.jsx)(se,{title:(0,l.__)("Translations workspace","gloty"),subtitle:(0,l.__)("Filter, inspect, and curate cached translations. Manual edits are protected from machine overwrite.","gloty")}),w&&(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mb",children:w}),"1"===T&&(0,_.jsxs)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mb",children:[(0,l.sprintf)(/* translators: %s: number of rows */ /* translators: %s: number of rows */ 41 (0,l._n)('Showing the %s row the "identical to its source" warning counts.','Showing the %s rows the "identical to its source" warning counts.',r,"gloty"),te(r))," ",(0,l.__)("These are the rows behind that number, read from the same scan it was counted with — product names, codes and text already written in the target language are already left out. Deleting a row asks for that text to be translated again, which spends your allowance, so read the list before removing anything. Status, staleness and search do not narrow this view.","gloty")]}),(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsx)(f.CardBody,{children:(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:12,flexWrap:"wrap"},children:[(0,_.jsx)("div",{style:{minWidth:240,flex:"1 1 240px",maxWidth:360},children:(0,_.jsx)(f.SearchControl,{label:(0,l.__)("Search translations","gloty"),value:A,disabled:"1"===T,onChange:D,onKeyDown:e=>{"Enter"===e.key&&(M(A),g(1))},onClose:A?()=>{D(""),M(""),g(1)}:void 0,placeholder:(0,l.__)("Search source or translated text…","gloty"),__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{minWidth:160},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Target language","gloty"),value:v,options:ue,onChange:e=>{j(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{minWidth:160},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Status","gloty"),value:b,options:[{label:(0,l.__)("All statuses","gloty"),value:""},{label:(0,l.__)("Translated (synced or edited)","gloty"),value:"translated"},{label:(0,l.__)("Synced","gloty"),value:"auto"},{label:(0,l.__)("Manually edited","gloty"),value:"manual"},{label:(0,l.__)("Pending","gloty"),value:"pending"},{label:(0,l.__)("Processing","gloty"),value:"processing"}],disabled:"1"===T,onChange:e=>{N(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{minWidth:160},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Stale","gloty"),value:C,options:[{label:(0,l.__)("All","gloty"),value:""},{label:(0,l.__)("Stale only","gloty"),value:"1"},{label:(0,l.__)("Fresh only","gloty"),value:"0"}],disabled:"1"===T,onChange:e=>{k(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{minWidth:200},children:(0,_.jsx)(f.SelectControl,{label:(0,l.__)("Flagged","gloty"),value:T,help:"1"===T?(0,l.__)("The rows the Overview warning counts.","gloty"):void 0,options:[{label:(0,l.__)("Not filtered","gloty"),value:""},{label:(0,l.__)("Identical to its source","gloty"),value:"1"}],onChange:e=>{E(e),g(1)},__nextHasNoMarginBottom:!0})}),(0,_.jsx)("div",{style:{display:"flex",alignItems:"flex-end",marginLeft:"auto"},children:(0,_.jsxs)("span",{className:"wpshelf-muted",children:[te(r)," ",(0,l.__)("rows","gloty")]})})]})})}),F.size>0&&(0,_.jsx)(f.Card,{className:"wpshelf-mb",children:(0,_.jsx)(f.CardBody,{children:(0,_.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{alignItems:"center"},children:[(0,_.jsx)("span",{children:(0,l.sprintf)(/* translators: %d: number of rows currently selected */ /* translators: %d: number of rows currently selected */ 42 (0,l.__)("%d selected","gloty"),F.size)}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:[(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{const e=Array.from(F);if(0!==e.length){q(!0);try{const s=await y()({path:"/gloty/v1/translations/dispatch-selected",method:"POST",data:{ids:e,mode:"dispatch"}}),a=s?.dispatch?.stage||null,n=!!s?.dispatch?.created;let i;i="not_connected"===a?(0,l.__)("Re-queued — but the translator service is not connected yet.","gloty"):"quota_exceeded"===a?(0,l.__)("Re-queued — but your character quota is exhausted. Upgrade your plan to dispatch.","gloty"):n?(0,l.sprintf)(/* translators: %d: number of translation rows re-queued */ /* translators: %d: number of translation rows re-queued */ 43 43 (0,l.__)("%d translation(s) re-queued and dispatched.","gloty"),s?.queued||e.length):(0,l.sprintf)(/* translators: %d: number of translation rows re-queued */ /* translators: %d: number of translation rows re-queued */ 44 (0,l.__)("%d translation(s) re-queued. Dispatch will pick them up on the next run.","gloty"),s?.queued||e.length),"not_connected"===a||"quota_exceeded"===a?t.info(i):t.success(i),we(),await _e()}catch(e){t.error(e?.message||(0,l.__)("Bulk translate failed.","gloty"))}finally{q(!1)}}},isBusy:U,disabled:U,children:(0,l.__)("Translate selected","gloty")}),(0, u.jsx)(y.Button,{variant:"secondary",isDestructive:!0,onClick:()=>X({type:"bulk",ids:Array.from(F)}),disabled:U,children:(0,l.__)("Delete selected","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",onClick:we,disabled:U,children:(0,l.__)("Clear","gloty")})]})]})})}),0===a.length?(0,u.jsx)(ne,{title:"1"===B?(0,l.__)("Nothing is flagged as identical to its source. The warning has cleared.","gloty"):(0,l.__)("No translations match these filters.","gloty")}):(0,u.jsxs)(u.Fragment,{children:[0===F.size&&(0,u.jsx)("p",{className:"wpshelf-table-hint wpshelf-muted",children:(0,l.__)("Tip: tick the checkboxes to translate or delete rows in bulk.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-table-wrap",children:(0,u.jsxs)(_,{className:"wp-list-table widefat striped",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("td",{className:"manage-column column-cb check-column",style:{width:32},children:(0,u.jsx)(y.CheckboxControl,{__nextHasNoMarginBottom:!0,checked:ye,indeterminate:fe,onChange:()=>{V(e=>{const s=new Set(e);return ye?pe.forEach(e=>s.delete(e)):pe.forEach(e=>s.add(e)),s})},"aria-label":(0,l.__)("Select all rows on this page","gloty")})}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Pair","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Status","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Original","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Translation","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Context","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Updated","gloty")}),(0,u.jsx)("th",{scope:"col",children:(0,l.__)("Actions","gloty")})]})}),(0,u.jsx)("tbody",{children:a.map(e=>{const s=Number(e.id),a=Cs(e);return(0,u.jsxs)("tr",{className:F.has(s)?"is-selected":void 0,children:[(0,u.jsx)("th",{scope:"row",className:"check-column",children:(0,u.jsx)(y.CheckboxControl,{__nextHasNoMarginBottom:!0,checked:F.has(s),onChange:()=>{return e=s,void V(s=>{const t=new Set(s);return t.has(e)?t.delete(e):t.add(e),t});var e},"aria-label":(0,l.sprintf)(/* translators: %d: translation row id */ /* translators: %d: translation row id */45 (0,l.__)("Select translation row %d","gloty"),s)})}),(0, u.jsx)("td",{children:(0,u.jsxs)("code",{children:[e.source_language,"→",e.target_language]})}),(0,u.jsxs)("td",{children:[(0,u.jsx)(K,{status:e.status}),1===Number(e.stale)&&(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--warn",style:{marginLeft:4},children:(0,l.__)("Stale","gloty")})]}),(0,u.jsx)("td",{title:ae(e.original_text)||e.original_text||void 0,children:ae(e.original_text)?Ss(ae(e.original_text),60):(0,u.jsx)("em",{className:"wpshelf-muted",title:(0,l.__)("Structured block content — its source text is captured when this row is sent for translation.","gloty"),children:(0,l.__)("Block content","gloty")})}),(0,u.jsx)("td",{className:"wpshelf-inline-edit-cell",title:Y===s?void 0:le(e.translated_text)||void 0,children:Y===s?(0,u.jsxs)(u.Fragment,{children:[oe&&(0,u.jsx)(re,{label:(0,l.__)("Saving…","gloty")}),(0,u.jsx)("textarea",{ref:he,className:"wpshelf-inline-edit",value:J,readOnly:oe,onChange:e=>Q(e.target.value),onBlur:ve,onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),ve()),"Escape"===e.key&&je()},rows:2})]}):(0,u.jsx)("span",{className:"wpshelf-inline-edit-trigger",onClick:()=>xe(e),role:"button",tabIndex:0,onKeyDown:s=>{"Enter"!==s.key&&" "!==s.key||(s.preventDefault(),xe(e))},children:le(e.translated_text)?Ss(le(e.translated_text),60):(0,u.jsx)("span",{className:"wpshelf-inline-placeholder",children:"pending"===e.status||"processing"===e.status?(0,l.__)("Not translated yet","gloty"):(0,l.__)("Add translation…","gloty")})})}),(0,u.jsx)("td",{title:ks(e.context).title,children:(0,u.jsx)("span",{className:"wpshelf-context-label",children:ks(e.context).label})}),(0,u.jsx)("td",{className:"wpshelf-muted",children:te(e.updated_at)}),(0,u.jsx)("td",{className:"wpshelf-actions-cell",children:(0,u.jsx)("div",{className:"wpshelf-row wpshelf-row-actions",children:(0,u.jsx)(y.DropdownMenu,{icon:js,label:(0,l.__)("Row actions","gloty"),popoverProps:{placement:"bottom-end"},toggleProps:{isSmall:!0,isBusy:R===s,disabled:null!==R||U,"aria-label":(0,l.sprintf)(/* translators: %s: the source text the row holds */ /* translators: %s: the source text the row holds */46 (0,l.__)("Actions for “%s”","gloty"), Ss(ae(e.original_text),40))},children:({onClose:n})=>(0,u.jsxs)(y.MenuGroup,{children:[(0,u.jsx)(y.MenuItem,{icon:bs,onClick:()=>{n(),(e=>{$(e),H(e.translated_text||"")})(e)},children:(0,l.__)("Edit","gloty")}),(0,u.jsx)(y.MenuItem,{icon:C,onClick:()=>{n(),(async e=>{O(e);try{const s=await m()({path:"/gloty/v1/translations/dispatch-selected",method:"POST",data:{ids:[e],mode:"dispatch"}}),a=s?.dispatch?.stage||null,n=!!s?.dispatch?.created;let i;i="not_connected"===a?(0,l.__)("Re-queued — but the translator service is not connected yet.","gloty"):"quota_exceeded"===a?(0,l.__)("Re-queued — but your character quota is exhausted. Upgrade your plan to dispatch.","gloty"):n?(0,l.__)("Re-queued and dispatched. Watch the jobs table for progress.","gloty"):(0,l.__)("Re-queued. It will be dispatched on the next sync run.","gloty"),"not_connected"===a||"quota_exceeded"===a?t.info(i):t.success(i),await _e()}catch(e){t.error(e?.message||(0,l.__)("Translate failed.","gloty"))}finally{O(null)}})(s)},children:(0,l.__)("Translate now","gloty")}),(0,u.jsx)(y.MenuItem,{icon:T,disabled:!a.eligible,info:a.eligible?void 0:a.reason,onClick:()=>{n(),(async e=>{const s=Cs(e);if(!s.eligible)return void t.info(s.reason);const a=Number(e.id);O(a);try{const e=await m()({path:"/gloty/v1/glossary/from-translation",method:"POST",data:{translation_id:a}}),n=e?.promoted?.term||s.term,i=String(e?.promoted?.language||"").toUpperCase();"created"===e?.outcome?t.success(s.verbatim?(0,l.sprintf)(/* translators: %s: the term added to the glossary */ /* translators: %s: the term added to the glossary */44 (0,l.__)("%d translation(s) re-queued. Dispatch will pick them up on the next run.","gloty"),s?.queued||e.length),"not_connected"===a||"quota_exceeded"===a?t.info(i):t.success(i),we(),await _e()}catch(e){t.error(e?.message||(0,l.__)("Bulk translate failed.","gloty"))}finally{q(!1)}}},isBusy:U,disabled:U,children:(0,l.__)("Translate selected","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",isDestructive:!0,onClick:()=>X({type:"bulk",ids:Array.from(F)}),disabled:U,children:(0,l.__)("Delete selected","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",onClick:we,disabled:U,children:(0,l.__)("Clear","gloty")})]})]})})}),0===a.length?(0,_.jsx)(ie,{title:"1"===T?(0,l.__)("Nothing is flagged as identical to its source. The warning has cleared.","gloty"):(0,l.__)("No translations match these filters.","gloty")}):(0,_.jsxs)(_.Fragment,{children:[0===F.size&&(0,_.jsx)("p",{className:"wpshelf-table-hint wpshelf-muted",children:(0,l.__)("Tip: tick the checkboxes to translate or delete rows in bulk.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-table-wrap",children:(0,_.jsxs)(p,{className:"wp-list-table widefat striped",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("td",{className:"manage-column column-cb check-column",style:{width:32},children:(0,_.jsx)(f.CheckboxControl,{__nextHasNoMarginBottom:!0,checked:me,indeterminate:fe,onChange:()=>{V(e=>{const s=new Set(e);return me?pe.forEach(e=>s.delete(e)):pe.forEach(e=>s.add(e)),s})},"aria-label":(0,l.__)("Select all rows on this page","gloty")})}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Pair","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Status","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Original","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Translation","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Context","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Updated","gloty")}),(0,_.jsx)("th",{scope:"col",children:(0,l.__)("Actions","gloty")})]})}),(0,_.jsx)("tbody",{children:a.map(e=>{const s=Number(e.id),a=Ss(e);return(0,_.jsxs)("tr",{className:F.has(s)?"is-selected":void 0,children:[(0,_.jsx)("th",{scope:"row",className:"check-column",children:(0,_.jsx)(f.CheckboxControl,{__nextHasNoMarginBottom:!0,checked:F.has(s),onChange:()=>{return e=s,void V(s=>{const t=new Set(s);return t.has(e)?t.delete(e):t.add(e),t});var e},"aria-label":(0,l.sprintf)(/* translators: %d: translation row id */ /* translators: %d: translation row id */ 45 (0,l.__)("Select translation row %d","gloty"),s)})}),(0,_.jsx)("td",{children:(0,_.jsxs)("code",{children:[e.source_language,"→",e.target_language]})}),(0,_.jsxs)("td",{children:[(0,_.jsx)(Q,{status:e.status}),1===Number(e.stale)&&(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--warn",style:{marginLeft:4},children:(0,l.__)("Stale","gloty")})]}),(0,_.jsx)("td",{title:le(e.original_text)||e.original_text||void 0,children:le(e.original_text)?ks(le(e.original_text),60):(0,_.jsx)("em",{className:"wpshelf-muted",title:(0,l.__)("Structured block content — its source text is captured when this row is sent for translation.","gloty"),children:(0,l.__)("Block content","gloty")})}),(0,_.jsx)("td",{className:"wpshelf-inline-edit-cell",title:Y===s?void 0:ne(e.translated_text)||void 0,children:Y===s?(0,_.jsxs)(_.Fragment,{children:[ee&&(0,_.jsx)(oe,{label:(0,l.__)("Saving…","gloty")}),(0,_.jsx)("textarea",{ref:he,className:"wpshelf-inline-edit",value:J,readOnly:ee,onChange:e=>K(e.target.value),onBlur:ve,onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),ve()),"Escape"===e.key&&je()},rows:2})]}):(0,_.jsx)("span",{className:"wpshelf-inline-edit-trigger",onClick:()=>xe(e),role:"button",tabIndex:0,onKeyDown:s=>{"Enter"!==s.key&&" "!==s.key||(s.preventDefault(),xe(e))},children:ne(e.translated_text)?ks(ne(e.translated_text),60):(0,_.jsx)("span",{className:"wpshelf-inline-placeholder",children:"pending"===e.status||"processing"===e.status?(0,l.__)("Not translated yet","gloty"):(0,l.__)("Add translation…","gloty")})})}),(0,_.jsx)("td",{title:Ts(e.context).title,children:(0,_.jsx)("span",{className:"wpshelf-context-label",children:Ts(e.context).label})}),(0,_.jsx)("td",{className:"wpshelf-muted",children:ae(e.updated_at)}),(0,_.jsx)("td",{className:"wpshelf-actions-cell",children:(0,_.jsx)("div",{className:"wpshelf-row wpshelf-row-actions",children:(0,_.jsx)(f.DropdownMenu,{icon:bs,label:(0,l.__)("Row actions","gloty"),popoverProps:{placement:"bottom-end"},toggleProps:{isSmall:!0,isBusy:R===s,disabled:null!==R||U,"aria-label":(0,l.sprintf)(/* translators: %s: the source text the row holds */ /* translators: %s: the source text the row holds */ 46 (0,l.__)("Actions for “%s”","gloty"),ks(le(e.original_text),40))},children:({onClose:n})=>(0,_.jsxs)(f.MenuGroup,{children:[(0,_.jsx)(f.MenuItem,{icon:Ns,onClick:()=>{n(),(e=>{$(e),H(e.translated_text||"")})(e)},children:(0,l.__)("Edit","gloty")}),(0,_.jsx)(f.MenuItem,{icon:S,onClick:()=>{n(),(async e=>{O(e);try{const s=await y()({path:"/gloty/v1/translations/dispatch-selected",method:"POST",data:{ids:[e],mode:"dispatch"}}),a=s?.dispatch?.stage||null,n=!!s?.dispatch?.created;let i;i="not_connected"===a?(0,l.__)("Re-queued — but the translator service is not connected yet.","gloty"):"quota_exceeded"===a?(0,l.__)("Re-queued — but your character quota is exhausted. Upgrade your plan to dispatch.","gloty"):n?(0,l.__)("Re-queued and dispatched. Watch the jobs table for progress.","gloty"):(0,l.__)("Re-queued. It will be dispatched on the next sync run.","gloty"),"not_connected"===a||"quota_exceeded"===a?t.info(i):t.success(i),await _e()}catch(e){t.error(e?.message||(0,l.__)("Translate failed.","gloty"))}finally{O(null)}})(s)},children:(0,l.__)("Translate now","gloty")}),(0,_.jsx)(f.MenuItem,{icon:B,disabled:!a.eligible,info:a.eligible?void 0:a.reason,onClick:()=>{n(),(async e=>{const s=Ss(e);if(!s.eligible)return void t.info(s.reason);const a=Number(e.id);O(a);try{const e=await y()({path:"/gloty/v1/glossary/from-translation",method:"POST",data:{translation_id:a}}),n=e?.promoted?.term||s.term,i=String(e?.promoted?.language||"").toUpperCase();"created"===e?.outcome?t.success(s.verbatim?(0,l.sprintf)(/* translators: %s: the term added to the glossary */ /* translators: %s: the term added to the glossary */ 47 47 (0,l.__)("“%s” added to the glossary — it will be left as written in every language.","gloty"),n):(0,l.sprintf)(/* translators: 1: the term added to the glossary, 2: uppercased language code */ /* translators: 1: the term added to the glossary, 2: uppercased language code */ 48 48 (0,l.__)("“%1$s” added to the glossary, fixed to this translation for %2$s.","gloty"),n,i)):"merged"===e?.outcome?t.success((0,l.sprintf)(/* translators: 1: uppercased language code, 2: the glossary term */ /* translators: 1: uppercased language code, 2: the glossary term */ 49 49 (0,l.__)("%1$s added to the glossary term “%2$s”.","gloty"),i,n)):"conflict"===e?.outcome?t.info((0,l.sprintf)(/* translators: 1: the glossary term, 2: uppercased language code, 3: the value the glossary already holds */ /* translators: 1: the glossary term, 2: uppercased language code, 3: the value the glossary already holds */ 50 50 (0,l.__)("“%1$s” is already in the glossary with a different %2$s value (“%3$s”). Open Glossary to change it.","gloty"),n,i,e?.promoted?.existing||"")):t.info((0,l.sprintf)(/* translators: %s: the glossary term */ /* translators: %s: the glossary term */ 51 (0,l.__)("The glossary already covers “%s” for this language.","gloty"),n))}catch(e){t.error(e?.message||(0,l.__)("Could not add this to the glossary.","gloty"))}finally{O(null)}})(e)},children:(0,l.__)("Add to glossary","gloty")}),(0, u.jsx)(y.MenuItem,{icon:Ns,isDestructive:!0,onClick:()=>{n(),X({type:"single",id:s})},children:(0,l.__)("Delete","gloty")})]})})})})]},s)})})]})}),c>1&&(0,u.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{marginTop:12},children:[(0,u.jsxs)("span",{className:"wpshelf-muted",children:[(0,l.__)("Page","gloty")," ",h," / ",c]}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:4},children:[(0,u.jsxs)(y.Button,{variant:"secondary",isSmall:!0,disabled:h<=1||p,onClick:()=>g(e=>e-1),children:["« ",(0,l.__)("Prev","gloty")]}),(0,u.jsxs)(y.Button,{variant:"secondary",isSmall:!0,disabled:h>=c||p,onClick:()=>g(e=>e+1),children:[(0,l.__)("Next","gloty")," »"]})]})]})]}),P&&(0,u.jsx)(y.Modal,{title:(0,l.__)("Edit translation","gloty"),onRequestClose:()=>$(null),className:"wpshelf-edit-modal",children:(0,u.jsxs)("div",{className:"wpshelf-edit-modal__body",children:[(0,u.jsxs)(y.Card,{className:"wpshelf-mb",children:[(0,u.jsx)(y.CardHeader,{size:"small",children:(0,u.jsxs)("strong",{children:[(0,l.__)("Original","gloty")," (",P.source_language,")"]})}),(0,u.jsx)(y.CardBody,{children:(0,u.jsx)("pre",{className:"wpshelf-pre",children:P.original_text})})]}),(0,u.jsx)(y.TextareaControl,{label:(0,l.__)("Translation","gloty")+` (${P.target_language})`,value:I,onChange:H,rows:5,__nextHasNoMarginBottom:!0}),I!==(P.translated_text||"")&&(0,u.jsxs)("div",{className:"wpshelf-diff",children:[(0,u.jsx)("span",{className:"wpshelf-diff__label",children:(0,l.__)("Changes","gloty")}),(0,u.jsx)(me,{oldText:P.translated_text||"",newText:I})]}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16,justifyContent:"flex-end"},children:[(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>$(null),children:(0,l.__)("Cancel","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{if(P){z(!0);try{await m()({path:`/gloty/v1/translations/${P.id}`,method:"POST",data:{translated_text:I}}),t.success((0,l.__)("Translation saved.","gloty")),$(null),await _e()}catch(e){t.error(e?.message||(0,l.__)("Failed to save translation.","gloty"))}finally{z(!1)}}},isBusy:G,disabled:G||""===I,children:(0,l.__)("Save","gloty")})]})]})}),W&&(0,u.jsx)(ie,{title:(0,l.__)("Delete translations","gloty"),message:"bulk"===W.type?(0,l.sprintf)(/* translators: %d: number of rows */ /* translators: %d: number of rows */52 (0,l.__)("Delete %d cached translation(s)? They may be regenerated later.","gloty"),W.ids.length):(0,l.__)("Delete this cached translation? It may be generated again later.","gloty"),busy:"bulk"===W.type?U:null!==R,onConfirm:()=>"bulk"===W.type?(async()=>{const e=W?.ids||Array.from(F);if(0!==e.length){q(!0);try{const s=await m()({path:"/gloty/v1/translations/delete-selected",method:"POST",data:{ids:e}});t.success((0,l.sprintf)(/* translators: %d: number of translation rows deleted */ /* translators: %d: number of translation rows deleted */53 (0,l.__)("%d translation(s) deleted.","gloty"),s?.deleted||e.length)),we(),await _e()}catch(e){t.error(e?.message||(0,l.__)("Bulk delete failed.","gloty"))}finally{q(!1),X(null)}}})():(async e=>{O(e);try{await m()({path:`/gloty/v1/translations/${e}`,method:"DELETE"}),t.success((0,l.__)("Translation deleted.","gloty")),await _e()}catch(e){t.error(e?.message||(0,l.__)("Could not delete translation.","gloty"))}finally{O(null),X(null)}})(W.id),onCancel:()=>X(null)})]})}const Bs={dashboard:null,dashboardLoading:!1,dashboardError:null,jobs:null,jobsLoading:!1,languages:null,languagesLoading:!1,routing:null,activity:null,activityLoading:!1,scan:null,onboardingStep:0,pluginSettings:null,pluginSettingsLoading:!1,pluginSettingsError:null},Es=(0,f.createReduxStore)("gloty/admin",{reducer:function(e=Bs,s){switch(s.type){case"RECEIVE_DASHBOARD":return{...e,dashboard:s.payload,dashboardLoading:!1,dashboardError:null};case"DASHBOARD_ERROR":return{...e,dashboardLoading:!1,dashboardError:s.payload};case"DASHBOARD_LOADING":return{...e,dashboardLoading:!0,dashboardError:null};case"RECEIVE_JOBS":return{...e,jobs:s.payload,jobsLoading:!1};case"JOBS_LOADING":return{...e,jobsLoading:!0};case"RECEIVE_LANGUAGES":return{...e,languages:s.payload,languagesLoading:!1};case"LANGUAGES_LOADING":return{...e,languagesLoading:!0};case"RECEIVE_ROUTING":return{...e,routing:s.payload};case"RECEIVE_ACTIVITY":return{...e,activity:s.payload,activityLoading:!1};case"ACTIVITY_LOADING":return{...e,activityLoading:!0};case"RECEIVE_SCAN":return{...e,scan:s.payload};case"SET_ONBOARDING_STEP":return{...e,onboardingStep:s.payload};case"PLUGIN_SETTINGS_LOADING":return{...e,pluginSettingsLoading:!0,pluginSettingsError:null};case"RECEIVE_PLUGIN_SETTINGS":return{...e,pluginSettings:s.payload,pluginSettingsLoading:!1,pluginSettingsError:null};case"PLUGIN_SETTINGS_ERROR":return{...e,pluginSettingsLoading:!1,pluginSettingsError:s.payload};default:return e}},actions:{receiveDashboard:e=>({type:"RECEIVE_DASHBOARD",payload:e}),dashboardError:e=>({type:"DASHBOARD_ERROR",payload:e}),dashboardLoading:()=>({type:"DASHBOARD_LOADING"}),receiveJobs:e=>({type:"RECEIVE_JOBS",payload:e}),jobsLoading:()=>({type:"JOBS_LOADING"}),receiveLanguages:e=>({type:"RECEIVE_LANGUAGES",payload:e}),languagesLoading:()=>({type:"LANGUAGES_LOADING"}),receiveRouting:e=>({type:"RECEIVE_ROUTING",payload:e}),receiveActivity:e=>({type:"RECEIVE_ACTIVITY",payload:e}),activityLoading:()=>({type:"ACTIVITY_LOADING"}),receiveScan:e=>({type:"RECEIVE_SCAN",payload:e}),setOnboardingStep:e=>({type:"SET_ONBOARDING_STEP",payload:e}),pluginSettingsLoading:()=>({type:"PLUGIN_SETTINGS_LOADING"}),receivePluginSettings:e=>({type:"RECEIVE_PLUGIN_SETTINGS",payload:e}),pluginSettingsError:e=>({type:"PLUGIN_SETTINGS_ERROR",payload:e})},selectors:{getDashboard:e=>e.dashboard,isDashboardLoading:e=>e.dashboardLoading,getDashboardError:e=>e.dashboardError,getJobs:e=>e.jobs,isJobsLoading:e=>e.jobsLoading,getLanguages:e=>e.languages,isLanguagesLoading:e=>e.languagesLoading,getRouting:e=>e.routing,getActivity:e=>e.activity,isActivityLoading:e=>e.activityLoading,getScan:e=>e.scan,getOnboardingStep:e=>e.onboardingStep,getPluginSettings:e=>e.pluginSettings,isPluginSettingsLoading:e=>e.pluginSettingsLoading,getPluginSettingsError:e=>e.pluginSettingsError}});(0,f.register)(Es);const Ls="gloty/admin";function Ms(e){return{gloty:"dashboard","gloty-dashboard":"dashboard","gloty-queue":"sync","gloty-sync":"sync","gloty-translations":"translations","gloty-languages":"languages","gloty-glossary":"glossary","gloty-onboarding":"onboarding","gloty-activity":"sync","gloty-settings":"settings","gloty-billing":"billing","gloty-design-system":"design-system"}[e]||"dashboard"}function As(){if("undefined"==typeof window)return{tab:null,view:null};const e=new URL(window.location.href),s=e.searchParams.get("tab"),t=e.searchParams.get("view");return{tab:s||Ms(e.searchParams.get("page")||"gloty"),view:t||null}}const Ds=[{key:"welcome",label:(0,l.__)("Welcome","gloty")},{key:"connection",label:(0,l.__)("Connection","gloty")},{key:"languages",label:(0,l.__)("Languages","gloty")},{key:"scan",label:(0,l.__)("Content scan","gloty")},{key:"done",label:(0,l.__)("Ready","gloty")}];function Rs({boot:e}){const s=(0,f.useSelect)(e=>e(Ls).getOnboardingStep(),[]),t=e=>(0,f.dispatch)(Ls).setOnboardingStep(e),[a,i]=(0,n.useState)(null),[r,o]=(0,n.useState)(e?.license?.hasKey?"existing":"new"),[c,d]=(0,n.useState)(""),[h,g]=(0,n.useState)(null),[_,p]=(0,n.useState)(null),[w,x]=(0,n.useState)(!1),[v,j]=(0,n.useState)(null),[b,N]=(0,n.useState)(!1),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(null),[B,E]=(0,n.useState)(e?.connection?.accountEmail||""),[L,M]=(0,n.useState)(e?.connection?.accountName||""),A=!!e?.connection?.connected,D=async()=>{x(!0),g(null),p(null);try{const e=await m()({path:"/gloty/v1/onboarding/connect",method:"POST",data:{email:B,name:L,use_existing_license:"existing"===r,license_key:"existing"===r?c.trim():""}});e?.ok?(i(e),d(""),window.dispatchEvent(new Event("gloty-license-refresh"))):(p(e?.stage||"connect"),g(e?.message||(0,l.__)("Could not complete the connection.","gloty")))}catch(e){p("network"),g(e?.message||(0,l.__)("Connection failed","gloty"))}finally{x(!1)}},R=()=>{m()({path:"/gloty/v1/onboarding/complete",method:"POST"}).catch(()=>{})},O=async()=>{N(!0),T(null),S(null);try{const e=await m()({path:"/gloty/v1/onboarding/language-packs",method:"POST"});S(e),!e.can_install&&e.message&&T(e.message)}catch(e){T(e?.message||(0,l.__)("Language pack install failed.","gloty"))}finally{N(!1)}},P=async()=>{x(!0),g(null);try{const e=await m()({path:"/gloty/v1/scan/start",method:"POST",data:{batch_size:20}});j(e),R(),t(4)}catch(e){g(e?.message||(0,l.__)("Scan failed","gloty"))}finally{x(!1)}},$=e?.language?.default||"en",I=(e?.language?.active||[]).filter(e=>e!==$),H=A||!!a?.ok,G=[{key:"connection",title:(0,l.__)("Site connected to Gloty","gloty"),done:H},{key:"languages",title:(0,l.__)("Target languages enabled","gloty"),done:I.length>0},{key:"scan",title:(0,l.__)("Initial content scan started","gloty"),done:!!v||(e?.content?.sourceCount??0)>0}],z=(0,n.useMemo)(()=>{const e=C?.items;if(!C?.can_install||!Array.isArray(e))return null;const s=e.filter(e=>"failed"===e.core).length,t=e.filter(e=>"installed"===e.core).length,a=e.filter(e=>"skipped"===e.core).length,l=e.reduce((e,s)=>e+(s.plugins?.installed?.length||0),0),n=e.reduce((e,s)=>e+(s.plugins?.failed?.length||0),0);return{failed:s,installed:t,skipped:a,total:e.length,pluginsInstalled:l,pluginsFailed:n}},[C]),F=(0,n.useRef)(null);(0,n.useEffect)(()=>{F.current&&F.current.focus()},[s]);const V=Ds[s]?.label||(0,l.__)("Onboarding","gloty");return(0,u.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Onboarding","gloty"),children:[(0,u.jsx)("h2",{ref:F,tabIndex:-1,className:"screen-reader-text","aria-live":"polite",children:(0,l.sprintf)(/* translators: 1: current step, 2: total steps, 3: step label */ /* translators: 1: current step, 2: total steps, 3: step label */54 (0,l.__)("Step %1$d of %2$d: %3$s","gloty"),s+1, Ds.length,V)}),(0,u.jsx)(pe,{items:G}),s<Ds.length-1&&(0,u.jsx)(_e,{steps:Ds,current:s}),(()=>{switch(s){case 0:return(0,u.jsx)(y.Card,{className:"wpshelf-onboard-card",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("h2",{style:{marginTop:0},children:(0,l.__)("Welcome to Gloty","gloty")}),(0,u.jsx)("p",{children:(0,l.__)("Gloty is a privacy-first WordPress translation plugin. Translations are generated by the Gloty service and stored locally in your database, so serving a translated page never calls out.","gloty")}),(0,u.jsx)("p",{children:(0,l.__)("Let's get your site set up in a few quick steps.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-row",style:{marginTop:16},children:(0,u.jsx)(y.Button,{variant:"primary",onClick:()=>t(1),children:(0,l.__)("Get started","gloty")})})]})});case 1:return(0,u.jsxs)(y.Card,{className:"wpshelf-onboard-card",children:[(0,u.jsx)(y.CardHeader,{children:(0,l.__)("Connect your site","gloty")}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Connect this site to your WP Shelf account to generate translations. New customers receive a one-time trial of 50,000 characters, with no payment details required.","gloty")}),!H&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(y.RadioControl,{label:(0,l.__)("Your WP Shelf account","gloty"),selected:r,options:[{label:(0,l.__)("I’m new — start a free trial","gloty"),value:"new"},{label:(0,l.__)("I already have an account or license","gloty"),value:"existing"}],onChange:e=>{o(e),g(null)}}),"existing"===r&&(0,u.jsxs)("div",{className:"wpshelf-mb",children:[(0,u.jsxs)("p",{children:[(0,u.jsx)("a",{href:"https://wp-shelf.com/dashboard/licenses",target:"_blank",rel:"noopener noreferrer",children:(0,l.__)("Copy your license from the WP Shelf dashboard","gloty")}),"."," ",(0,l.__)("Use the email address on that account below.","gloty")]}),(0,u.jsxs)("label",{children:[(0,u.jsx)("div",{children:(0,l.__)("License key","gloty")}),(0,u.jsx)("input",{type:"password",autoComplete:"off",value:c,onChange:e=>d(e.target.value),placeholder:e?.license?.hasKey?(0,l.__)("Saved license will be used","gloty"):"GLOTY-XXXX-XXXX-XXXX-XXXX",style:{width:"100%"}})]})]})]}),H?(0,u.jsx)(y.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.__)("This site is connected to Gloty. You can continue to the next step.","gloty")}):(0,u.jsxs)("div",{className:"wpshelf-grid",style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:12,marginTop:12},children:[(0,u.jsxs)("label",{children:[(0,u.jsx)("div",{children:(0,l.__)("Your email","gloty")}),(0,u.jsx)("input",{type:"email",value:B,onChange:e=>E(e.target.value),autoComplete:"email",required:!0,style:{width:"100%"}})]}),(0,u.jsxs)("label",{children:[(0,u.jsx)("div",{children:(0,l.__)("Your name","gloty")}),(0,u.jsx)("input",{type:"text",value:L,onChange:e=>M(e.target.value),autoComplete:"name",required:!0,style:{width:"100%"}})]})]}),h&&(0,u.jsxs)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:["license"===_?(0,l.__)("Could not connect your license:","gloty")+" ":"register"===_?(0,l.__)("Your license was created, but we couldn't register this site:","gloty")+" ":"",h]}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[!H&&(0,u.jsx)(y.Button,{variant:"primary",onClick:D,isBusy:w,disabled:w||!B.trim()||!L.trim()||"existing"===r&&!e?.license?.hasKey&&!c.trim(),children:w?(0,l.__)("Connecting…","gloty"):"existing"===r?(0,l.__)("Activate license & connect","gloty"):(0,l.__)("Start free trial & connect","gloty")}),(0,u.jsx)(y.Button,{variant:H?"primary":"secondary",onClick:()=>t(2),disabled:w||!H,children:(0,l.__)("Next","gloty")})]})]})]});case 2:return(0,u.jsxs)(y.Card,{className:"wpshelf-onboard-card",children:[(0,u.jsx)(y.CardHeader,{children:(0,l.__)("Language setup","gloty")}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsxs)("p",{children:[(0,l.__)("Your source language is set to:","gloty")," ",(0,u.jsx)("strong",{children:$})]}),I.length>0?(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("p",{children:(0,l.__)("Active target languages:","gloty")}),(0,u.jsx)("div",{className:"wpshelf-row",children:I.map(e=>(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--info",children:e},e))})]}):(0,u.jsx)(y.Notice,{status:"warning",isDismissible:!1,children:(0,l.__)("No target languages enabled yet. Enable them under the Languages tab.","gloty")}),(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:12},children:(0,l.__)("You can always adjust languages later under the Languages tab.","gloty")}),(0,u.jsx)("div",{style:{marginTop:20,marginBottom:12,borderTop:"1px solid var(--wpshelf-line-soft)"}}),(0,u.jsx)("p",{children:(0,l.__)("Install WordPress language packs so core, admin, theme, and plugin strings load translated .mo files for your locales — including JavaScript-rendered blocks like the WooCommerce Cart and Checkout that Gloty cannot translate from page HTML. This uses the same downloads as Settings → General → Site Language.","gloty")}),k&&(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:k}),C?.can_install&&C?.message&&0===C?.items?.length&&(0,u.jsx)(y.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",children:C.message}),z&&z.total>0&&0===z.failed&&(0,u.jsx)(y.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: 1: total locales, 2: newly installed, 3: already on disk */ /* translators: 1: total locales, 2: newly installed, 3: already on disk */55 (0,l.__)("Language packs processed: %1$d locale(s), %2$d installed, %3$d already present.","gloty"),z.total,z.installed,z.skipped)}),z&&z.failed>0&&(0, u.jsx)(y.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: 1: succeeded or skipped count, 2: failed count */ /* translators: 1: succeeded or skipped count, 2: failed count */56 (0,l.__)("Some packs could not be installed (%1$d ok, %2$d failed). Try again or install languages under Settings → General.","gloty"),z.total-z.failed,z.failed)}),z&&z.pluginsInstalled>0&&(0, u.jsx)(y.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: %d: number of plugin language packs installed */ /* translators: %d: number of plugin language packs installed */57 (0,l._n)("Installed %d plugin language pack so block-based screens (e.g. WooCommerce Cart & Checkout) render translated.","Installed %d plugin language packs so block-based screens (e.g. WooCommerce Cart & Checkout) render translated.",z.pluginsInstalled,"gloty"),z.pluginsInstalled)}),(0, u.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,u.jsx)(y.Button,{variant:"tertiary",href:"admin.php?page=gloty-languages&tab=languages",children:(0,l.__)("Open Languages","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>t(1),children:(0,l.__)("Back","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",onClick:O,isBusy:b,disabled:b,children:(0,l.__)("Install WordPress language packs","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:()=>t(3),disabled:0===I.length,children:(0,l.__)("Next","gloty")})]})]})]});case 3:return(0,u.jsxs)(y.Card,{className:"wpshelf-onboard-card",children:[(0,u.jsx)(y.CardHeader,{children:(0,l.__)("Content scan","gloty")}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{children:(0,l.__)("A content scan registers your existing posts and pages for translation. You can run a quick scan now or do it later from the Sync tab.","gloty")}),h&&(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:h}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,u.jsx)(y.Button,{variant:"secondary",onClick:()=>t(2),children:(0,l.__)("Back","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:P,isBusy:w,disabled:w,children:(0,l.__)("Start scan now","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>{R(),t(4)},children:(0,l.__)("Skip for now","gloty")})]})]})]});case 4:return(0,u.jsx)(y.Card,{className:"wpshelf-onboard-card",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("h2",{style:{marginTop:0},children:(0,l.__)("You're all set!","gloty")}),(0,u.jsx)("p",{children:(0,l.__)("Gloty is configured and ready to translate. Visit your site with a language prefix to start capturing template strings, or use the Sync tab to scan content and generate translations.","gloty")}),v&&(0,u.jsx)(y.Notice,{status:"success",isDismissible:!1,children:(0,l.__)("Content scan started successfully.","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,u.jsx)(y.Button,{variant:"primary",href:"admin.php?page=gloty",children:(0,l.__)("Go to Dashboard","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",href:"admin.php?page=gloty-sync&tab=sync",children:(0,l.__)("View sync status","gloty")})]}),(0,u.jsxs)("div",{className:"wpshelf-role-handoff",children:[(0,u.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Next actions by role","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-role-grid",children:[(0,u.jsx)(y.Card,{children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("strong",{children:(0,l.__)("Site owner","gloty")}),(0,u.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Confirm provider limits and monitor queue and processing health.","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",href:"admin.php?page=gloty-sync&tab=sync&view=workspace",children:(0,l.__)("Open Sync workspace","gloty")})]})}),(0,u.jsx)(y.Card,{children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("strong",{children:(0,l.__)("Content manager","gloty")}),(0,u.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Review stale rows first and manually improve priority translations.","gloty")}),(0,u.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("They do not need an administrator account — under Settings you can let a role correct translations, optionally in one language only.","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",href:"admin.php?page=gloty-translations&tab=translations&view=workspace",children:(0,l.__)("Open Translations","gloty")})]})}),(0,u.jsx)(y.Card,{children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("strong",{children:(0,l.__)("Developer","gloty")}),(0,u.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Validate language packs, route prefixes, and switcher behavior on frontend pages.","gloty")}),(0,u.jsx)(y.Button,{variant:"secondary",href:"admin.php?page=gloty-languages&tab=languages&view=languages",children:(0,l.__)("Open Languages","gloty")})]})})]})]})]})});default:return null}})()]})}const Os=[{key:"capture",label:(0,l.__)("Collected","gloty"),tab:"sync",hint:(0,l.__)("Strings found on your site. Opens the content scan.","gloty")},{key:"queued",label:(0,l.__)("Queued","gloty"),tab:"sync",hint:(0,l.__)("Waiting to be sent. Opens the sync queue.","gloty")},{key:"dispatch",label:(0,l.__)("Sent","gloty"),tab:"sync",hint:(0,l.__)("In flight to the translator. Opens the job list.","gloty")},{key:"processing",label:(0,l.__)("Translating","gloty"),tab:"translations",filters:{status:"processing"},hint:(0,l.__)("Opens these rows in the translations table.","gloty")},{key:"completed",label:(0,l.__)("Done","gloty"),hint:(0,l.__)("Distinct strings finished in each language you have enabled — counted once per language, so it is smaller than the number of rows in the translations table.","gloty")},{key:"stale",label:(0,l.__)("Out of date","gloty"),tab:"translations",filters:{stale:"1"},hint:(0,l.__)("Opens the translations whose source text has changed.","gloty")}],Ps={auto:(0,l.__)("Show synced translations","gloty"),manual:(0,l.__)("Show manually edited translations","gloty"),pending:(0,l.__)("Show translations waiting to be sent","gloty"),processing:(0,l.__)("Show translations in progress","gloty")};function $s({boot:e,onNavigate:s}){const t=Le(),[a,i]=(0,n.useState)(!1),[r,o]=(0,n.useState)(!1),c=(0,f.useSelect)(e=>e(Ls).getDashboard(),[]),d=(0,f.useSelect)(e=>e(Ls).isDashboardLoading(),[]),h=(0,f.useSelect)(e=>e(Ls).getDashboardError(),[]),g=(0,n.useCallback)(async()=>{(0,f.dispatch)(Ls).dashboardLoading();try{const e=await m()({path:"/gloty/v1/dashboard",parse:!0});(0,f.dispatch)(Ls).receiveDashboard(e)}catch(e){(0,f.dispatch)(Ls).dashboardError(e?.message||(0,l.__)("Failed to load dashboard","gloty"))}},[]);(0,n.useEffect)(()=>{g()},[g]);const p=(0,n.useCallback)(async()=>{o(!0);try{const e=await m()({path:"/gloty/v1/maintenance/purge-stale-translations",method:"POST",data:{limit:5e3}}),s=Number(e?.removed||0),a=Number(e?.remaining||0);0===s?t.info((0,l.__)("Nothing was out of date.","gloty")):t.success(a>0?(0,l.sprintf)(/* translators: 1: rows removed, 2: rows still out of date */ /* translators: 1: rows removed, 2: rows still out of date */58 (0,l.__)("%1$s out-of-date translations removed and re-queued. %2$s still to go — run it again.","gloty"), se(s),se(a)):(0,l.sprintf)(/* translators: %s: number of rows removed */ /* translators: %s: number of rows removed */59 (0,l.__)("%s out-of-date translations removed and re-queued for translation.","gloty"), se(s))),await g()}catch(e){t.error(e?.message||(0,l.__)("Could not remove the out-of-date entries.","gloty"))}finally{o(!1),i(!1)}},[g,t]);if(d&&!c)return(0,u.jsxs)("div",{className:"wpshelf-screen",children:[(0,u.jsx)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[0,1,2].map(e=>(0,u.jsx)(y.Card,{className:"wpshelf-stat",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("span",{className:"wpshelf-shimmer",style:{width:"40%",height:12,marginBottom:10}}),(0,u.jsx)("span",{className:"wpshelf-shimmer",style:{width:"30%",height:28,marginBottom:8}}),(0,u.jsx)("span",{className:"wpshelf-shimmer",style:{width:"60%",height:12}})]})},e))}),(0,u.jsx)(ce,{cols:5,rows:4,headers:[(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Lang","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Updated","gloty")]})]});if(h)return(0,u.jsx)("div",{className:"wpshelf-screen",children:(0,u.jsx)(y.Notice,{status:"error",isDismissible:!1,children:h})});if(!c)return(0,u.jsx)(ne,{icon:"\\uD83D\\uDCCA",title:(0,l.__)("No data yet","gloty"),hint:(0,l.__)("Visit the front end in a target language to register template strings, or use the Sync tab to scan your content.","gloty")});const w=c.overview||{},x=c.status_breakdown||{},v=w.status_model||{},j=c.language_progress||[],b=(x.auto||0)+(x.manual||0)+(x.pending||0)+(x.processing||0),N=w.source_count??w.total_strings??0,C=w.translated_count??(x.auto||0)+(x.manual||0),S=w.pending_count??0,k=w.stale_count??0,T=w.target_languages??Math.max(0,(w.languages_active??1)-1),B=w.characters_per_language??0,E=w.characters_all_languages??B*T,L=w.expected_translations??N*Math.max(1,T),M={source:0===N?[{label:(0,l.__)("Scan content for strings","gloty"),tab:"sync"}]:[{label:(0,l.__)("Browse strings","gloty"),tab:"translations"}],translated:0===C?[{label:(0,l.__)("Start your first translation","gloty"),tab:"sync"}]:[{label:(0,l.__)("Review translations","gloty"),tab:"translations",filters:{status:"translated"}},{label:(0,l.__)("Review manual edits","gloty"),tab:"translations",filters:{status:"manual"}}],pending:S>0?[{label:(0,l.__)("Translate pending","gloty"),tab:"sync",prominent:!0},{label:(0,l.__)("View pending rows","gloty"),tab:"translations",filters:{status:"pending"}}]:null,stale:k>0?[{label:(0,l.__)("Re-sync out-of-date items","gloty"),tab:"sync"},{label:(0,l.__)("Review out-of-date rows","gloty"),tab:"translations",filters:{stale:"1"}}]:null,languages:0===T?[{label:(0,l.__)("Add a target language","gloty"),tab:"languages"}]:[{label:(0,l.__)("Manage languages","gloty"),tab:"languages"}]},A=e=>{const t=(Array.isArray(e)?e:[e]).filter(Boolean);return 0!==t.length&&s?(0,u.jsx)("div",{className:"wpshelf-stat-grid__cta"+(t.some(e=>e.prominent)?" wpshelf-stat-grid__cta--prominent":""),children:t.map(e=>(0,u.jsxs)(y.Button,{variant:e.prominent?"secondary":"link",onClick:()=>s(e.tab,e.filters||null),children:[e.label," →"]},e.label))}):null},D=e=>({template_string:(0,l.__)("theme & UI (unique gettext strings seen on localized pages)","gloty"),post_field:(0,l.__)("post / page segments (title, excerpt, each translatable block slice)","gloty"),term_field:(0,l.__)("taxonomy name & description","gloty")}[e]??e);return(0,u.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Dashboard","gloty"),children:[(0,u.jsx)(We,{boot:e,onNavigate:s}),(0,u.jsx)(Ye,{hasLanguages:T>0,hasSource:N>0,hasTranslated:C>0,pendingCount:S,onNavigate:s}),(0,u.jsx)(os,{onNavigate:s}),(0,u.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--translated",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Translated","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:se(C)}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:0===N?(0,l.__)("no content captured yet","gloty"):0===T?(0,l.__)("add a target language to begin","gloty"):(0,l.sprintf)(/* translators: 1: total expected translations (strings × languages), 2: number of target languages */ /* translators: 1: total expected translations (strings × languages), 2: number of target languages */60 (0,l._n)("of %1$s translation in %2$d language","of %1$s translations across %2$d languages",T,"gloty"),L.toLocaleString(),T)}),A(M.translated)]})}),(0, u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--pending",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Pending","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:se(S)}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:S>0?(0,l.__)("strings waiting to be translated","gloty"):(0,l.__)("queue is clear","gloty")}),A(M.pending)]})}),(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--stale",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Out of date","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value",children:se(k)}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:k>0?(0,l.__)("source content changed","gloty"):(0,l.__)("all in sync","gloty")}),A(M.stale)]})})]}),(0,u.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--supporting",children:[(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--source",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Source strings","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value wpshelf-stat__value--medium",children:se(N)}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("every translatable text snippet found on your site","gloty")}),B>0&&(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:T>0?(0,l.sprintf)(/* translators: 1: characters in the site, 2: characters needed for every active language */ /* translators: 1: characters in the site, 2: characters needed for every active language */61 (0,l.__)("%1$s characters of source text — about %2$s to translate into every language you have enabled","gloty"), se(B),se(E)):(0,l.sprintf)(/* translators: %s: characters in the site */ /* translators: %s: characters in the site */62 (0,l.__)("%s characters of source text — this is what a language costs to add","gloty"), se(B))}),w.registry_by_source_kind&&Object.keys(w.registry_by_source_kind).length>0&&(0,u.jsx)("ul",{className:"wpshelf-stat__breakdown",children:Object.entries(w.registry_by_source_kind).map(([e,s])=>(0,u.jsxs)("li",{children:[(0,u.jsx)("strong",{children:se(s)})," ",D(e)]},e))}),A(M.source)]})}),(0,u.jsx)(y.Card,{className:"wpshelf-stat wpshelf-stat--languages",children:(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Target languages","gloty")}),(0,u.jsx)("div",{className:"wpshelf-stat__value wpshelf-stat__value--medium",children:T}),(0,u.jsx)("div",{className:"wpshelf-stat__sub",children:T>0?(0,l.sprintf)(/* translators: %s: source language code */ /* translators: %s: source language code */63 (0,l.__)("alongside %s as source","gloty"),(e?.language?.default||"en").toUpperCase()):(0,l.__)("no target languages enabled","gloty")}),A(M.languages)]})})]}),(0, u.jsxs)("div",{className:"wpshelf-content-boxes",children:[b>0&&(0,u.jsxs)(y.Card,{className:"wpshelf-content-box",children:[(0,u.jsxs)(y.CardHeader,{children:[(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Translation status","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:[k>0&&(0,u.jsx)(y.Button,{variant:"tertiary",size:"small",isDestructive:!0,onClick:()=>i(!0),disabled:r,isBusy:r,children:r?(0,l.__)("Removing…","gloty"):(0,l.__)("Remove out-of-date","gloty")}),(0,u.jsx)(y.Button,{variant:"tertiary",size:"small",onClick:g,disabled:d,isBusy:d,"aria-live":"polite",children:d?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]})]}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("div",{className:"wpshelf-row",style:{gap:24},children:Object.entries(x).map(([e,t])=>Ps[e]&&s?(0,u.jsxs)("button",{type:"button",className:"wpshelf-status-link",title:Ps[e],onClick:()=>s("translations",{status:e}),children:[(0,u.jsx)(K,{status:e}),(0,u.jsx)("span",{className:"wpshelf-status-link__value",children:se(t)})]},e):(0,u.jsxs)("div",{className:"wpshelf-status-link wpshelf-status-link--static",children:[(0,u.jsx)(K,{status:e}),(0,u.jsx)("span",{className:"wpshelf-status-link__value",children:se(t)})]},e))}),Object.keys(v).length>0&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{margin:"16px 0 8px"},children:(0,l.__)("Each string moves through these stages: Collected → Queued → Sent → Translating → Done.","gloty")}),(0,u.jsx)("div",{className:"wpshelf-row",style:{gap:10},children:Os.map(e=>{const t=se(v[e.key]??0);return s&&e.tab?(0,u.jsxs)("button",{type:"button",className:"wpshelf-pipeline-chip wpshelf-pipeline-chip--link",title:e.hint,onClick:()=>s(e.tab,e.filters||null),children:[(0,u.jsx)("span",{className:"wpshelf-pipeline-chip__label",children:e.label}),(0,u.jsx)("strong",{className:"wpshelf-pipeline-chip__value",children:t})]},e.key):(0,u.jsxs)("div",{className:"wpshelf-pipeline-chip",title:e.hint,children:[(0,u.jsx)("span",{className:"wpshelf-pipeline-chip__label",children:e.label}),(0,u.jsx)("strong",{className:"wpshelf-pipeline-chip__value",children:t})]},e.key)})})]})]})]}),j.length>0&&(0,u.jsxs)(y.Card,{className:"wpshelf-content-box",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Language progress","gloty")})}),(0,u.jsx)(y.CardBody,{children:j.map(e=>(0,u.jsxs)("div",{style:{marginBottom:8},children:[(0,u.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{marginBottom:2},children:[(0,u.jsxs)("span",{style:{fontSize:13,fontWeight:500},children:[e.native_name||e.name," ",(0,u.jsxs)("span",{className:"wpshelf-muted",children:["(",e.code,")"]})]}),(0,u.jsxs)("span",{className:"wpshelf-muted",children:[se(e.translated),"/",se(e.total)]})]}),(0,u.jsx)(ue,{value:e.translated,max:e.total,label:`${e.percentage}%`,scale:"completion"})]},e.code))})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-content-box",children:[(0,u.jsx)(y.CardHeader,{children:(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Recent translations","gloty")})}),(0,u.jsx)(y.CardBody,{children:0===(c.recent||[]).length?(0,u.jsx)(ne,{title:(0,l.__)("No translation rows yet","gloty"),hint:(0,l.__)("Visit the front end in a target language to register template strings.","gloty")}):(0,u.jsxs)(_,{className:"wp-list-table widefat striped",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{children:(0,l.__)("Original","gloty")}),(0,u.jsx)("th",{children:(0,l.__)("Translated","gloty")}),(0,u.jsx)("th",{children:(0,l.__)("Lang","gloty")}),(0,u.jsx)("th",{children:(0,l.__)("Status","gloty")}),(0,u.jsx)("th",{children:(0,l.__)("Updated","gloty")})]})}),(0,u.jsx)("tbody",{children:c.recent.map(e=>(0,u.jsxs)("tr",{children:[(0,u.jsx)("td",{title:ae(e.original)||void 0,children:ae(e.original)?ae(e.original).slice(0,80):(0,u.jsx)("em",{className:"wpshelf-muted",title:(0,l.__)("Structured block content — its text is captured when the block is sent for translation.","gloty"),children:(0,l.__)("Block content","gloty")})}),(0,u.jsx)("td",{title:le(e.translated)||void 0,children:le(e.translated)?le(e.translated).slice(0,80):(0,u.jsx)("span",{className:"wpshelf-muted",children:"pending"===e.status||"processing"===e.status?(0,l.__)("Not translated yet","gloty"):"—"})}),(0,u.jsx)("td",{children:(0,u.jsx)("code",{children:e.language_code})}),(0,u.jsx)("td",{children:(0,u.jsx)(K,{status:e.status})}),(0,u.jsx)("td",{className:"wpshelf-muted",children:te(e.updated_at)})]},e.id))})]})})]})]}),a&&(0,u.jsx)(ie,{title:(0,l.__)("Remove out-of-date entries?","gloty"),message:(0,l.sprintf)(/* translators: %s: number of out-of-date translations */ /* translators: %s: number of out-of-date translations */64 (0,l.__)("%s translations are of source text that has since changed. Removing them puts those strings back in the queue, so the next sync translates them again — which spends quota. Until it runs, visitors see the original text for those strings. Manual edits of changed content are removed too.","gloty"), se(k)),confirmLabel:(0,l.__)("Remove and re-queue","gloty"),busy:r,onConfirm:p,onCancel:()=>i(!1)})]})}function Is({boot:e}){const s=Le(),t=(0,f.useSelect)(e=>e(Ls).getLanguages(),[]),a=(0,f.useSelect)(e=>e(Ls).isLanguagesLoading(),[]),i=(0,f.useSelect)(e=>e(Ls).getRouting(),[]),[r,o]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[h,g]=(0,n.useState)(!1),[p,x]=(0,n.useState)(""),[b,N]=(0,n.useState)(!1),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(!1);(0,n.useEffect)(()=>{(async()=>{(0,f.dispatch)(Ls).languagesLoading(),d(null);try{const e=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(e)}catch(e){(0,f.dispatch)(Ls).receiveLanguages({default:"en",languages:[]}),d({status:"error",message:e?.message||(0,l.__)("Could not load languages.","gloty")})}try{const e=await m()({path:"/gloty/v1/settings/routing",parse:!0});(0,f.dispatch)(Ls).receiveRouting(e)}catch(e){(0,f.dispatch)(Ls).receiveRouting({url_structure:"subdirectory"}),d(s=>"error"===s?.status?s:{status:"error",message:e?.message||(0,l.__)("Could not load routing settings.","gloty")})}})()},[]);const B=(0,n.useMemo)(()=>t?.languages||[],[t]),E=t?.default||e?.language?.default||"en",L=(0,n.useMemo)(()=>{const e=[...B];return e.sort((e,s)=>e.code===E?-1:s.code===E?1:(Number(e.sort_order)||0)-(Number(s.sort_order)||0)),e},[B,E]),M=(0,n.useMemo)(()=>L.filter(e=>e.code!==E&&1!==Number(e.is_active)),[L,E]),A=k?L:L.filter(e=>e.code===E||1===Number(e.is_active)),D=async(e,t)=>{const a=L.filter(e=>e.code!==E),n=a.findIndex(s=>s.id===e.id),i=n+t;if(n<0||i<0||i>=a.length)return;const r=a[n],c=a[i],h=Number(r.sort_order)||0,g=Number(c.sort_order)||0;o(!0),d(null);try{await Promise.all([m()({path:`/gloty/v1/languages/${r.id}`,method:"PUT",data:{sort_order:g}}),m()({path:`/gloty/v1/languages/${c.id}`,method:"PUT",data:{sort_order:h}})]),s.success((0,l.__)("Display order updated.","gloty"));const e=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(e)}catch(e){s.error(e?.message||(0,l.__)("Could not update display order.","gloty"))}finally{o(!1)}},R=i?.url_structure||e?.routing?.url_structure||"subdirectory",O=(0,n.useMemo)(()=>function(e){const s=new Set((e||[]).map(e=>String(e.code||"").toLowerCase()));return Ke.filter(e=>!s.has(e.code.toLowerCase())).map(e=>({label:`${e.native_name} — ${e.name} (${e.code})`,value:e.code}))}(B),[B]);return a&&!t?(0,u.jsx)("div",{className:"wpshelf-screen",children:(0,u.jsx)(ce,{cols:5,rows:4,headers:[(0,l.__)("Language","gloty"),(0,l.__)("Code","gloty"),(0,l.__)("Direction","gloty"),(0,l.__)("Default","gloty"),(0,l.__)("Order","gloty")]})}):(0,u.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Languages","gloty"),children:[(0,u.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Source language is the canonical site language. Enable target languages to create URL prefixes and start capturing translations.","gloty")}),c&&(0,u.jsx)(y.Notice,{status:c.status,isDismissible:!0,onDismiss:()=>d(null),className:"wpshelf-mb",children:c.message}),(0,u.jsxs)(y.Card,{className:"wpshelf-mb",children:[(0,u.jsxs)(y.CardHeader,{children:[(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("URL strategy","gloty")}),r&&(0,u.jsx)(re,{label:(0,l.__)("Saving…","gloty")})]}),(0,u.jsxs)(y.CardBody,{children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Choose how translated pages are addressed. This affects every translated URL on your site.","gloty")}),i?.deferred?.message&&(0,u.jsx)("p",{className:"wpshelf-muted",children:i.deferred.message}),(0,u.jsx)("div",{className:"wpshelf-urlstrategy",role:"radiogroup","aria-label":(0,l.__)("URL strategy","gloty"),children:[{value:"subdirectory",title:(0,l.__)("Path prefix","gloty"),example:"example.com/fr/page",desc:(0,l.__)("Recommended for SEO — each language gets its own path.","gloty")},{value:"parameter",title:(0,l.__)("Query parameter","gloty"),example:"example.com/page?lang=fr",desc:(0,l.__)("Simplest setup — no rewrite rules required.","gloty")}].map(e=>{const t=R===e.value;return(0,u.jsxs)("button",{type:"button",role:"radio","aria-checked":t,className:"wpshelf-urlstrategy__opt"+(t?" wpshelf-urlstrategy__opt--active":""),onClick:()=>!t&&(async e=>{o(!0),d(null);try{await m()({path:"/gloty/v1/settings/routing/update",method:"POST",data:{url_structure:e}});const t=await m()({path:"/gloty/v1/settings/routing",parse:!0});(0,f.dispatch)(Ls).receiveRouting(t),s.success((0,l.__)("Routing settings saved.","gloty"))}catch(e){s.error(e?.message||(0,l.__)("Could not save routing settings.","gloty"))}finally{o(!1)}})(e.value),disabled:r,children:[(0,u.jsxs)("span",{className:"wpshelf-urlstrategy__top",children:[(0,u.jsx)("span",{className:"wpshelf-urlstrategy__title",children:e.title}),t?(0,u.jsxs)("span",{className:"wpshelf-chip wpshelf-chip--success",children:["✓ ",(0,l.__)("Selected","gloty")]}):(0,u.jsx)("span",{className:"wpshelf-urlstrategy__pick wpshelf-muted",children:(0,l.__)("Use this","gloty")})]}),(0,u.jsx)("code",{className:"wpshelf-urlstrategy__example",children:e.example}),(0,u.jsx)("span",{className:"wpshelf-urlstrategy__desc wpshelf-muted",children:e.desc})]},e.value)})})]})]}),(0,u.jsxs)(y.Card,{className:"wpshelf-mb",children:[(0,u.jsxs)(y.CardHeader,{children:[(0,u.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Target languages","gloty")}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:12},children:[r&&(0,u.jsx)(re,{label:(0,l.__)("Saving…","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:()=>{x(""),g(!0)},disabled:r,children:(0,l.__)("Add language","gloty")})]})]}),(0,u.jsxs)(y.CardBody,{children:[0===B.length?(0,u.jsx)(ne,{title:(0,l.__)("No languages configured","gloty"),hint:(0,l.__)("Add a target language to start capturing translations.","gloty")}):(0,u.jsxs)(_,{className:"wp-list-table widefat striped",children:[(0,u.jsx)("thead",{children:(0,u.jsxs)("tr",{children:[(0,u.jsx)("th",{children:(0,l.__)("Code","gloty")}),(0,u.jsx)("th",{children:(0,l.__)("Language","gloty")}),(0,u.jsx)("th",{title:(0,l.__)("The language your content is written in. Every other language is translated from it.","gloty"),children:(0,l.__)("Source","gloty")}),(0,u.jsx)("th",{title:(0,l.__)("Controls the order languages appear in the front-end switcher.","gloty"),children:(0,l.__)("Order","gloty")}),(0,u.jsx)("th",{title:(0,l.__)("Active languages show in the switcher and are served to visitors. Inactive ones stay configured but hidden.","gloty"),children:(0,l.__)("Active","gloty")}),(0,u.jsx)("th",{children:(0,u.jsx)("span",{className:"screen-reader-text",children:(0,l.__)("Actions","gloty")})})]})}),(0,u.jsx)("tbody",{children:A.map(e=>{const t=L.filter(e=>e.code!==E),a=t[0]?.id,n=t[t.length-1]?.id,i=e.native_name||e.name||e.code;return(0,u.jsxs)("tr",{children:[(0,u.jsx)("td",{children:(0,u.jsx)("code",{children:e.code})}),(0,u.jsxs)("td",{children:[e.native_name," ",(0,u.jsxs)("span",{className:"wpshelf-muted",children:["(",e.name,")"]})]}),(0,u.jsx)("td",{children:e.code===E?(0,u.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success",title:(0,l.__)("This is your source language — content is translated from it.","gloty"),children:(0,l.__)("Source","gloty")}):(0,u.jsx)(y.Button,{variant:"link",onClick:()=>(async e=>{o(!0),d(null);try{await m()({path:"/gloty/v1/languages/default",method:"POST",data:{code:e}});const t=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(t),s.success((0,l.__)("Default language updated.","gloty"))}catch(e){s.error(e?.message||(0,l.__)("Could not set default language.","gloty"))}finally{o(!1)}})(e.code),disabled:r,children:(0,l.__)("Make source","gloty")})}),(0,u.jsx)("td",{children:e.code!==E?(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:4},children:[(0,u.jsx)(y.Button,{variant:"tertiary",isSmall:!0,disabled:r||e.id===a,onClick:()=>D(e,-1),"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */65 (0,l.__)("Move %s up","gloty"),i),children:(0, u.jsx)(w,{icon:v,size:20})}),(0,u.jsx)(y.Button,{variant:"tertiary",isSmall:!0,disabled:r||e.id===n,onClick:()=>D(e,1),"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */66 (0,l.__)("Move %s down","gloty"),i),children:(0, u.jsx)(w,{icon:j,size:20})})]}):(0,u.jsx)("span",{className:"wpshelf-muted",children:"—"})}),(0,u.jsx)("td",{children:(0,u.jsx)(y.ToggleControl,{__nextHasNoMarginBottom:!0,label:1===Number(e.is_active)?(0,l.__)("Active","gloty"):(0,l.__)("Inactive","gloty"),help:e.code===E?(0,l.__)("Source language always stays active.","gloty"):void 0,checked:1===Number(e.is_active),disabled:r||e.code===E,onChange:t=>(async(e,t)=>{o(!0),d(null);try{await m()({path:`/gloty/v1/languages/${e}`,method:"PUT",data:{is_active:t}}),s.success((0,l.__)("Language updated.","gloty"));const a=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(a)}catch(e){s.error(e?.message||(0,l.__)("Error updating","gloty"))}finally{o(!1)}})(e.id,t)})}),(0,u.jsx)("td",{children:e.code!==E&&(0,u.jsx)(y.Button,{variant:"tertiary",isDestructive:!0,isSmall:!0,onClick:()=>S(e),disabled:r,"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */67 (0,l.__)("Remove %s","gloty"),i),children:(0,l.__)("Remove","gloty")})})]},e.id)})})]}),M.length>0&&(0, u.jsx)("div",{className:"wpshelf-lang-showmore",children:(0,u.jsxs)(y.Button,{variant:"link",onClick:()=>T(e=>!e),"aria-expanded":k,children:[k?(0,l.__)("Hide inactive languages","gloty"):(0,l.sprintf)(/* translators: %d: number of inactive (configured but disabled) languages */ /* translators: %d: number of inactive (configured but disabled) languages */68 (0,l._n)("Show %d inactive language","Show %d inactive languages",M.length,"gloty"),M.length),(0, u.jsx)(w,{icon:k?v:j,size:20})]})}),B.length>0&&(0,u.jsx)("p",{className:"wpshelf-muted wpshelf-lang-legend",children:(0,l.__)("Source is the language you author in. Active languages appear in the switcher and are served to visitors; turn one off to keep it configured but hidden. Order sets where each appears in the switcher.","gloty")})]})]}),h&&(0,u.jsxs)(y.Modal,{title:(0,l.__)("Add language","gloty"),onRequestClose:()=>{b||(g(!1),x(""))},className:"wpshelf-language-modal",children:[(0,u.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Pick a language. Base tags only — regional variants like en-GB or pt-BR are not offered.","gloty")}),(0,u.jsx)(y.ComboboxControl,{label:(0,l.__)("Language","gloty"),value:p,onChange:e=>x(e||""),options:O,allowReset:!0,__nextHasNoMarginBottom:!0}),(0,u.jsx)("div",{style:{marginTop:12},children:(0,u.jsx)(ds,{code:p})}),(0,u.jsxs)("div",{className:"wpshelf-row",style:{gap:8,marginTop:16,justifyContent:"flex-end"},children:[(0,u.jsx)(y.Button,{variant:"tertiary",onClick:()=>{g(!1),x("")},disabled:b,children:(0,l.__)("Cancel","gloty")}),(0,u.jsx)(y.Button,{variant:"primary",onClick:async()=>{if(!p)return;const e=Qe(p);if(e){N(!0);try{await m()({path:"/gloty/v1/languages",method:"POST",data:{code:e.code,name:e.name,native_name:e.native_name,is_rtl:!!e.is_rtl}});const t=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(t),s.success((0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */69 (0,l.__)("%s added.","gloty"),e.native_name)),g(!1), x("")}catch(e){s.error(e?.message||(0,l.__)("Could not add language.","gloty"))}finally{N(!1)}}else s.error((0,l.__)("Unknown language code.","gloty"))},disabled:!p||b,isBusy:b,children:(0,l.__)("Add language","gloty")})]})]}),C&&(0,u.jsx)(ie,{title:(0,l.__)("Remove language","gloty"),message:(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */70 (0,l.__)("Remove %s? Translated content in this language will no longer be served, but the stored translations will remain in the database.","gloty"),C.native_name||C.name||C.code),confirmLabel:(0,l.__)("Remove","gloty"),busy:r,onConfirm:async()=>{const e=C;if(!e)return;const t=e.native_name||e.name||e.code;o(!0);try{await m()({path:`/gloty/v1/languages/${e.id}`,method:"DELETE"});const a=await m()({path:"/gloty/v1/languages",parse:!0});(0,f.dispatch)(Ls).receiveLanguages(a),s.success((0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */71 (0,l.__)("%s removed.","gloty"),t))}catch(e){s.error(e?.message||(0,l.__)("Could not remove language.","gloty"))}finally{o(!1),S(null)}},onCancel:()=>S(null)})]})}function Hs({boot:e}){const s=!e?.onboardingComplete,t=Ms(e?.adminPage||"gloty"),a=As().tab||t,i=s&&"dashboard"===a?"onboarding":a,[r,o]=(0,n.useState)(!1),c=!!e?.devMode||"design-system"===a,d=!1!==e?.capabilities?.manageOptions,h=d?[{label:(0,l.__)("Operations","gloty"),items:[{name:"dashboard",title:(0,l.__)("Overview","gloty"),icon:N},{name:"sync",title:(0,l.__)("Sync","gloty"),icon:C},{name:"translations",title:(0,l.__)("Translations","gloty"),icon:b},{name:"analytics",title:(0,l.__)("Analytics","gloty"),icon:S}]},{label:(0,l.__)("Configure","gloty"),items:[{name:"languages",title:(0,l.__)("Languages","gloty"),icon:k},{name:"glossary",title:(0,l.__)("Glossary","gloty"),icon:T},{name:"seo",title:(0,l.__)("SEO","gloty"),icon:B},{name:"settings",title:(0,l.__)("Settings","gloty"),icon:E}]},{label:(0,l.__)("Account","gloty"),items:[{name:"billing",title:(0,l.__)("Billing","gloty"),icon:L}]},...e?.onboardingComplete?[]:[{label:(0,l.__)("Setup","gloty"),items:[{name:"onboarding",title:(0,l.__)("Setup","gloty"),icon:M}]}],...c?[{label:(0,l.__)("Developer","gloty"),items:[{name:"design-system",title:(0,l.__)("Design system","gloty"),icon:A}]}]:[]]:[{label:(0,l.__)("Operations","gloty"),items:[{name:"translations",title:(0,l.__)("Translations","gloty"),icon:b}]}],g=h.flatMap(e=>e.items),_=e=>d&&"design-system"===e||g.some(s=>s.name===e),p=d?"dashboard":"translations",m=_(i)?i:p,[f,x]=(0,n.useState)(m);(0,n.useEffect)(()=>{const e=()=>{const e=As(),s=e.tab&&_(e.tab)?e.tab:p;x(s)};return window.addEventListener("popstate",e),()=>window.removeEventListener("popstate",e)},[g]);const[v,j]=(0,n.useState)(null),D=(e,s=null)=>{x(e),j(s),function(e,s=null){if("undefined"==typeof window)return;const t=new URL(window.location.href);t.searchParams.set("page",{dashboard:"gloty",translations:"gloty-translations",sync:"gloty-sync",languages:"gloty-languages",glossary:"gloty-glossary",settings:"gloty-settings",billing:"gloty-billing",onboarding:"gloty-onboarding","design-system":"gloty-design-system"}[e]||"gloty"),t.searchParams.set("tab",e),s?t.searchParams.set("view",s):t.searchParams.delete("view"),window.history.replaceState({},"",t.toString())}(e)};return(0,u.jsx)(Ee,{children:(0,u.jsxs)("div",{className:"wpshelf-app",children:[(0,u.jsx)("a",{className:"screen-reader-text",href:"#gloty-main-content",children:(0,l.__)("Skip to main content","gloty")}),(0,u.jsxs)("header",{className:"wpshelf-app__header",children:[(0,u.jsxs)("div",{className:"wpshelf-app__brand",children:[(0,u.jsx)("div",{className:"wpshelf-app__mark","aria-hidden":"true",children:(0,u.jsx)("svg",{viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:(0,u.jsxs)("g",{transform:"matrix(1 0 0 -1 0 48)",children:[(0,u.jsx)("path",{d:"M39 24 A15 15 0 1 0 34.6 34.6",stroke:"#ffffff",strokeWidth:"2.4",strokeLinecap:"round"}),(0,u.jsx)("path",{d:"M39 24 H27.5",stroke:"#ffffff",strokeWidth:"2.4",strokeLinecap:"round"}),(0,u.jsx)("ellipse",{cx:"24",cy:"24",rx:"6.4",ry:"15",stroke:"#ffffff",strokeWidth:"1.6",strokeOpacity:"0.7"}),(0,u.jsx)("path",{d:"M13.5 16 H34.5",stroke:"#ffffff",strokeWidth:"1.5",strokeLinecap:"round",strokeOpacity:"0.55"}),(0,u.jsx)("path",{d:"M13.5 32 H32",stroke:"#ffffff",strokeWidth:"1.5",strokeLinecap:"round",strokeOpacity:"0.55"}),(0,u.jsx)("circle",{cx:"27.5",cy:"24",r:"2.4",fill:"#ffffff"})]})})}),(0,u.jsxs)("div",{className:"wpshelf-app__brand-text",children:[(0,u.jsx)("h1",{className:"wpshelf-app__title",children:(0,l.__)("Gloty","gloty")}),(0,u.jsx)("p",{className:"wpshelf-app__subtitle",children:(0,l.__)("AI-powered multilingual WordPress, done locally","gloty")})]})]}),(0,u.jsxs)("div",{className:"wpshelf-app__header-right",children:[(0,u.jsx)(ls,{onNavigate:D}),(0,u.jsxs)("span",{className:"wpshelf-app__version",children:["v",e?.plugin?.version]})]})]}),(0,u.jsxs)("div",{className:"wpshelf-layout"+(r?" wpshelf-layout--collapsed":""),children:[(0,u.jsxs)("nav",{className:"wpshelf-sidebar","aria-label":(0,l.__)("Gloty navigation","gloty"),children:[(0,u.jsx)("button",{type:"button",className:"wpshelf-sidebar__toggle",onClick:()=>o(e=>!e),"aria-label":r?(0,l.__)("Expand navigation","gloty"):(0,l.__)("Collapse navigation","gloty"),children:r?"❯":"❮"}),h.map(e=>(0,u.jsxs)("div",{className:"wpshelf-sidebar__section",children:[!r&&(0,u.jsx)("div",{className:"wpshelf-sidebar__section-label",children:e.label}),e.items.map(e=>{const s=(0,u.jsxs)("button",{type:"button",className:"wpshelf-sidebar__item"+(f===e.name?" wpshelf-sidebar__item--active":""),onClick:()=>D(e.name),"aria-selected":f===e.name,"aria-label":e.title,role:"tab",children:[(0,u.jsx)(w,{icon:e.icon,size:20,className:"wpshelf-sidebar__item-icon"}),!r&&(0,u.jsx)("span",{className:"wpshelf-sidebar__item-label",children:e.title})]},e.name);return r?(0,u.jsx)(y.Tooltip,{text:e.title,children:s},e.name):s})]},e.label))]}),(0,u.jsxs)("div",{id:"gloty-main-content",className:"wpshelf-tab-content",role:"tabpanel",tabIndex:"-1",children:[(0,u.jsx)(fs,{license:e?.license,hideOnboarding:"onboarding"===f}),"dashboard"===f?(0,u.jsx)($s,{boot:e,onNavigate:D}):"translations"===f?(0,u.jsx)(Ts,{boot:e,filters:v}):"sync"===f?(0,u.jsx)(vs,{boot:e,onNavigate:D}):"languages"===f?(0,u.jsx)(Is,{boot:e}):"glossary"===f?(0,u.jsx)(ts,{boot:e}):"seo"===f?(0,u.jsx)(xs,{boot:e}):"analytics"===f?(0,u.jsx)(X,{}):"billing"===f?(0,u.jsx)(Se,{boot:e}):"onboarding"===f?(0,u.jsx)(Rs,{boot:e}):"design-system"===f?(0,u.jsx)(qe,{}):(0,u.jsx)(ms,{boot:e})]})]})]})})}function Gs(){const e=document.getElementById("gloty-admin-root");if(!e)return;const s="undefined"!=typeof window?window.glotyBoot:void 0;s&&function(e){e?.api&&(m().use(m().createNonceMiddleware(e.api.restNonce)),m().use((e,s)=>{if("GET"!==(e.method??"GET").toUpperCase()||e.url)return s(e);const t=e.path??"",a=t.includes("?")?"&":"?";return s({...e,path:`${t}${a}_cb=${Date.now()}`,cache:"no-store"})}),m().use((s,t)=>{if(s.url)return t(s);const a=s.path??"",l=e.api.restRoot.replace(/\/$/,""),n=a.startsWith("/")?a:`/${a}`;return t({...s,url:l+n})}))}(s),(0,a.H)(e).render((0,u.jsx)(Hs,{boot:s}))}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",Gs):Gs()},930(e,s,t){var a=t(795);s.H=a.createRoot,a.hydrateRoot},795(e){e.exports=window.ReactDOM}},t={};function a(e){var l=t[e];if(void 0!==l)return l.exports;var n=t[e]={exports:{}};return s[e](n,n.exports,a),n.exports}a.m=s,e=[],a.O=(s,t,l,n)=>{if(!t){var i=1/0;for(d=0;d<e.length;d++){for(var[t,l,n]=e[d],r=!0,o=0;o<t.length;o++)(!1&n||i>=n)&&Object.keys(a.O).every(e=>a.O[e](t[o]))?t.splice(o--,1):(r=!1,n<i&&(i=n));if(r){e.splice(d--,1);var c=l();void 0!==c&&(s=c)}}return s}n=n||0;for(var d=e.length;d>0&&e[d-1][2]>n;d--)e[d]=e[d-1];e[d]=[t,l,n]},a.n=e=>{var s=e&&e.__esModule?()=>e.default:()=>e;return a.d(s,{a:s}),s},a.d=(e,s)=>{for(var t in s)a.o(s,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:s[t]})},a.o=(e,s)=>Object.prototype.hasOwnProperty.call(e,s),(()=>{var e={366:0,757:0};a.O.j=s=>0===e[s];var s=(s,t)=>{var l,n,[i,r,o]=t,c=0;if(i.some(s=>0!==e[s])){for(l in r)a.o(r,l)&&(a.m[l]=r[l]);if(o)var d=o(a)}for(s&&s(t);c<i.length;c++)n=i[c],a.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return a.O(d)},t=globalThis.webpackChunk_wp_shelf_gloty=globalThis.webpackChunk_wp_shelf_gloty||[];t.forEach(s.bind(null,0)),t.push=s.bind(null,t.push.bind(t))})();var l=a.O(void 0,[757],()=>a(843));l=a.O(l)})();51 (0,l.__)("The glossary already covers “%s” for this language.","gloty"),n))}catch(e){t.error(e?.message||(0,l.__)("Could not add this to the glossary.","gloty"))}finally{O(null)}})(e)},children:(0,l.__)("Add to glossary","gloty")}),(0,_.jsx)(f.MenuItem,{icon:Cs,isDestructive:!0,onClick:()=>{n(),X({type:"single",id:s})},children:(0,l.__)("Delete","gloty")})]})})})})]},s)})})]})}),c>1&&(0,_.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{marginTop:12},children:[(0,_.jsxs)("span",{className:"wpshelf-muted",children:[(0,l.__)("Page","gloty")," ",h," / ",c]}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:4},children:[(0,_.jsxs)(f.Button,{variant:"secondary",isSmall:!0,disabled:h<=1||u,onClick:()=>g(e=>e-1),children:["« ",(0,l.__)("Prev","gloty")]}),(0,_.jsxs)(f.Button,{variant:"secondary",isSmall:!0,disabled:h>=c||u,onClick:()=>g(e=>e+1),children:[(0,l.__)("Next","gloty")," »"]})]})]})]}),P&&(0,_.jsx)(f.Modal,{title:(0,l.__)("Edit translation","gloty"),onRequestClose:()=>$(null),className:"wpshelf-edit-modal",children:(0,_.jsxs)("div",{className:"wpshelf-edit-modal__body",children:[(0,_.jsxs)(f.Card,{className:"wpshelf-mb",children:[(0,_.jsx)(f.CardHeader,{size:"small",children:(0,_.jsxs)("strong",{children:[(0,l.__)("Original","gloty")," (",P.source_language,")"]})}),(0,_.jsx)(f.CardBody,{children:(0,_.jsx)("pre",{className:"wpshelf-pre",children:P.original_text})})]}),(0,_.jsx)(f.TextareaControl,{label:(0,l.__)("Translation","gloty")+` (${P.target_language})`,value:I,onChange:H,rows:5,__nextHasNoMarginBottom:!0}),I!==(P.translated_text||"")&&(0,_.jsxs)("div",{className:"wpshelf-diff",children:[(0,_.jsx)("span",{className:"wpshelf-diff__label",children:(0,l.__)("Changes","gloty")}),(0,_.jsx)(ye,{oldText:P.translated_text||"",newText:I})]}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16,justifyContent:"flex-end"},children:[(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>$(null),children:(0,l.__)("Cancel","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{if(P){z(!0);try{await y()({path:`/gloty/v1/translations/${P.id}`,method:"POST",data:{translated_text:I}}),t.success((0,l.__)("Translation saved.","gloty")),$(null),await _e()}catch(e){t.error(e?.message||(0,l.__)("Failed to save translation.","gloty"))}finally{z(!1)}}},isBusy:G,disabled:G||""===I,children:(0,l.__)("Save","gloty")})]})]})}),W&&(0,_.jsx)(re,{title:(0,l.__)("Delete translations","gloty"),message:"bulk"===W.type?(0,l.sprintf)(/* translators: %d: number of rows */ /* translators: %d: number of rows */ 52 (0,l.__)("Delete %d cached translation(s)? They may be regenerated later.","gloty"),W.ids.length):(0,l.__)("Delete this cached translation? It may be generated again later.","gloty"),busy:"bulk"===W.type?U:null!==R,onConfirm:()=>"bulk"===W.type?(async()=>{const e=W?.ids||Array.from(F);if(0!==e.length){q(!0);try{const s=await y()({path:"/gloty/v1/translations/delete-selected",method:"POST",data:{ids:e}});t.success((0,l.sprintf)(/* translators: %d: number of translation rows deleted */ /* translators: %d: number of translation rows deleted */ 53 (0,l.__)("%d translation(s) deleted.","gloty"),s?.deleted||e.length)),we(),await _e()}catch(e){t.error(e?.message||(0,l.__)("Bulk delete failed.","gloty"))}finally{q(!1),X(null)}}})():(async e=>{O(e);try{await y()({path:`/gloty/v1/translations/${e}`,method:"DELETE"}),t.success((0,l.__)("Translation deleted.","gloty")),await _e()}catch(e){t.error(e?.message||(0,l.__)("Could not delete translation.","gloty"))}finally{O(null),X(null)}})(W.id),onCancel:()=>X(null)})]})}const Es={dashboard:null,dashboardLoading:!1,dashboardError:null,jobs:null,jobsLoading:!1,languages:null,languagesLoading:!1,routing:null,activity:null,activityLoading:!1,scan:null,onboardingStep:0,pluginSettings:null,pluginSettingsLoading:!1,pluginSettingsError:null},Ls=(0,w.createReduxStore)("gloty/admin",{reducer:function(e=Es,s){switch(s.type){case"RECEIVE_DASHBOARD":return{...e,dashboard:s.payload,dashboardLoading:!1,dashboardError:null};case"DASHBOARD_ERROR":return{...e,dashboardLoading:!1,dashboardError:s.payload};case"DASHBOARD_LOADING":return{...e,dashboardLoading:!0,dashboardError:null};case"RECEIVE_JOBS":return{...e,jobs:s.payload,jobsLoading:!1};case"JOBS_LOADING":return{...e,jobsLoading:!0};case"RECEIVE_LANGUAGES":return{...e,languages:s.payload,languagesLoading:!1};case"LANGUAGES_LOADING":return{...e,languagesLoading:!0};case"RECEIVE_ROUTING":return{...e,routing:s.payload};case"RECEIVE_ACTIVITY":return{...e,activity:s.payload,activityLoading:!1};case"ACTIVITY_LOADING":return{...e,activityLoading:!0};case"RECEIVE_SCAN":return{...e,scan:s.payload};case"SET_ONBOARDING_STEP":return{...e,onboardingStep:s.payload};case"PLUGIN_SETTINGS_LOADING":return{...e,pluginSettingsLoading:!0,pluginSettingsError:null};case"RECEIVE_PLUGIN_SETTINGS":return{...e,pluginSettings:s.payload,pluginSettingsLoading:!1,pluginSettingsError:null};case"PLUGIN_SETTINGS_ERROR":return{...e,pluginSettingsLoading:!1,pluginSettingsError:s.payload};default:return e}},actions:{receiveDashboard:e=>({type:"RECEIVE_DASHBOARD",payload:e}),dashboardError:e=>({type:"DASHBOARD_ERROR",payload:e}),dashboardLoading:()=>({type:"DASHBOARD_LOADING"}),receiveJobs:e=>({type:"RECEIVE_JOBS",payload:e}),jobsLoading:()=>({type:"JOBS_LOADING"}),receiveLanguages:e=>({type:"RECEIVE_LANGUAGES",payload:e}),languagesLoading:()=>({type:"LANGUAGES_LOADING"}),receiveRouting:e=>({type:"RECEIVE_ROUTING",payload:e}),receiveActivity:e=>({type:"RECEIVE_ACTIVITY",payload:e}),activityLoading:()=>({type:"ACTIVITY_LOADING"}),receiveScan:e=>({type:"RECEIVE_SCAN",payload:e}),setOnboardingStep:e=>({type:"SET_ONBOARDING_STEP",payload:e}),pluginSettingsLoading:()=>({type:"PLUGIN_SETTINGS_LOADING"}),receivePluginSettings:e=>({type:"RECEIVE_PLUGIN_SETTINGS",payload:e}),pluginSettingsError:e=>({type:"PLUGIN_SETTINGS_ERROR",payload:e})},selectors:{getDashboard:e=>e.dashboard,isDashboardLoading:e=>e.dashboardLoading,getDashboardError:e=>e.dashboardError,getJobs:e=>e.jobs,isJobsLoading:e=>e.jobsLoading,getLanguages:e=>e.languages,isLanguagesLoading:e=>e.languagesLoading,getRouting:e=>e.routing,getActivity:e=>e.activity,isActivityLoading:e=>e.activityLoading,getScan:e=>e.scan,getOnboardingStep:e=>e.onboardingStep,getPluginSettings:e=>e.pluginSettings,isPluginSettingsLoading:e=>e.pluginSettingsLoading,getPluginSettingsError:e=>e.pluginSettingsError}});(0,w.register)(Ls);const Ms="gloty/admin";function As(e){return{gloty:"dashboard","gloty-dashboard":"dashboard","gloty-queue":"sync","gloty-sync":"sync","gloty-translations":"translations","gloty-languages":"languages","gloty-glossary":"glossary","gloty-onboarding":"onboarding","gloty-activity":"sync","gloty-settings":"settings","gloty-billing":"billing","gloty-design-system":"design-system"}[e]||"dashboard"}function Ds(){if("undefined"==typeof window)return{tab:null,view:null};const e=new URL(window.location.href),s=e.searchParams.get("tab"),t=e.searchParams.get("view");return{tab:s||As(e.searchParams.get("page")||"gloty"),view:t||null}}const Rs=[{key:"welcome",label:(0,l.__)("Welcome","gloty")},{key:"connection",label:(0,l.__)("Connection","gloty")},{key:"languages",label:(0,l.__)("Languages","gloty")},{key:"scan",label:(0,l.__)("Content scan","gloty")},{key:"done",label:(0,l.__)("Ready","gloty")}];function Os({boot:e}){const s=(0,w.useSelect)(e=>e(Ms).getOnboardingStep(),[]),t=e=>(0,w.dispatch)(Ms).setOnboardingStep(e),[a,i]=(0,n.useState)(null),[r,o]=(0,n.useState)(e?.license?.hasKey?"existing":"new"),[c,d]=(0,n.useState)(""),[h,g]=(0,n.useState)(null),[u,p]=(0,n.useState)(null),[m,x]=(0,n.useState)(!1),[v,j]=(0,n.useState)(null),[b,N]=(0,n.useState)(!1),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(null),[B,E]=(0,n.useState)(e?.connection?.accountEmail||""),[L,M]=(0,n.useState)(e?.connection?.accountName||""),A=!!e?.connection?.connected,D=async()=>{x(!0),g(null),p(null);try{const e=await y()({path:"/gloty/v1/onboarding/connect",method:"POST",data:{email:B,name:L,use_existing_license:"existing"===r,license_key:"existing"===r?c.trim():""}});e?.ok?(i(e),d(""),window.dispatchEvent(new Event("gloty-license-refresh"))):(p(e?.stage||"connect"),g(e?.message||(0,l.__)("Could not complete the connection.","gloty")))}catch(e){p("network"),g(e?.message||(0,l.__)("Connection failed","gloty"))}finally{x(!1)}},R=()=>{y()({path:"/gloty/v1/onboarding/complete",method:"POST"}).catch(()=>{})},O=async()=>{N(!0),T(null),S(null);try{const e=await y()({path:"/gloty/v1/onboarding/language-packs",method:"POST"});S(e),!e.can_install&&e.message&&T(e.message)}catch(e){T(e?.message||(0,l.__)("Language pack install failed.","gloty"))}finally{N(!1)}},P=async()=>{x(!0),g(null);try{const e=await y()({path:"/gloty/v1/scan/start",method:"POST",data:{batch_size:20}});j(e),R(),t(4)}catch(e){g(e?.message||(0,l.__)("Scan failed","gloty"))}finally{x(!1)}},$=e?.language?.default||"en",I=(e?.language?.active||[]).filter(e=>e!==$),H=A||!!a?.ok,G=[{key:"connection",title:(0,l.__)("Site connected to Gloty","gloty"),done:H},{key:"languages",title:(0,l.__)("Target languages enabled","gloty"),done:I.length>0},{key:"scan",title:(0,l.__)("Initial content scan started","gloty"),done:!!v||(e?.content?.sourceCount??0)>0}],z=(0,n.useMemo)(()=>{const e=C?.items;if(!C?.can_install||!Array.isArray(e))return null;const s=e.filter(e=>"failed"===e.core).length,t=e.filter(e=>"installed"===e.core).length,a=e.filter(e=>"skipped"===e.core).length,l=e.reduce((e,s)=>e+(s.plugins?.installed?.length||0),0),n=e.reduce((e,s)=>e+(s.plugins?.failed?.length||0),0);return{failed:s,installed:t,skipped:a,total:e.length,pluginsInstalled:l,pluginsFailed:n}},[C]),F=(0,n.useRef)(null);(0,n.useEffect)(()=>{F.current&&F.current.focus()},[s]);const V=Rs[s]?.label||(0,l.__)("Onboarding","gloty");return(0,_.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Onboarding","gloty"),children:[(0,_.jsx)("h2",{ref:F,tabIndex:-1,className:"screen-reader-text","aria-live":"polite",children:(0,l.sprintf)(/* translators: 1: current step, 2: total steps, 3: step label */ /* translators: 1: current step, 2: total steps, 3: step label */ 54 (0,l.__)("Step %1$d of %2$d: %3$s","gloty"),s+1,Rs.length,V)}),(0,_.jsx)(me,{items:G}),s<Rs.length-1&&(0,_.jsx)(pe,{steps:Rs,current:s}),(()=>{switch(s){case 0:return(0,_.jsx)(f.Card,{className:"wpshelf-onboard-card",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("h2",{style:{marginTop:0},children:(0,l.__)("Welcome to Gloty","gloty")}),(0,_.jsx)("p",{children:(0,l.__)("Gloty is a privacy-first WordPress translation plugin. Translations are generated by the Gloty service and stored locally in your database, so serving a translated page never calls out.","gloty")}),(0,_.jsx)("p",{children:(0,l.__)("Let's get your site set up in a few quick steps.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-row",style:{marginTop:16},children:(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>t(1),children:(0,l.__)("Get started","gloty")})})]})});case 1:return(0,_.jsxs)(f.Card,{className:"wpshelf-onboard-card",children:[(0,_.jsx)(f.CardHeader,{children:(0,l.__)("Connect your site","gloty")}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Connect this site to your WP Shelf account to generate translations. New customers receive a one-time trial of 50,000 characters, with no payment details required.","gloty")}),!H&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(f.RadioControl,{label:(0,l.__)("Your WP Shelf account","gloty"),selected:r,options:[{label:(0,l.__)("I’m new — start a free trial","gloty"),value:"new"},{label:(0,l.__)("I already have an account or license","gloty"),value:"existing"}],onChange:e=>{o(e),g(null)}}),"existing"===r&&(0,_.jsxs)("div",{className:"wpshelf-mb",children:[(0,_.jsxs)("p",{children:[(0,_.jsx)("a",{href:"https://wp-shelf.com/dashboard/licenses",target:"_blank",rel:"noopener noreferrer",children:(0,l.__)("Copy your license from the WP Shelf dashboard","gloty")}),"."," ",(0,l.__)("Use the email address on that account below.","gloty")]}),(0,_.jsxs)("label",{children:[(0,_.jsx)("div",{children:(0,l.__)("License key","gloty")}),(0,_.jsx)("input",{type:"password",autoComplete:"off",value:c,onChange:e=>d(e.target.value),placeholder:e?.license?.hasKey?(0,l.__)("Saved license will be used","gloty"):"GLOTY-XXXX-XXXX-XXXX-XXXX",style:{width:"100%"}})]})]})]}),H?(0,_.jsx)(f.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.__)("This site is connected to Gloty. You can continue to the next step.","gloty")}):(0,_.jsxs)("div",{className:"wpshelf-grid",style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:12,marginTop:12},children:[(0,_.jsxs)("label",{children:[(0,_.jsx)("div",{children:(0,l.__)("Your email","gloty")}),(0,_.jsx)("input",{type:"email",value:B,onChange:e=>E(e.target.value),autoComplete:"email",required:!0,style:{width:"100%"}})]}),(0,_.jsxs)("label",{children:[(0,_.jsx)("div",{children:(0,l.__)("Your name","gloty")}),(0,_.jsx)("input",{type:"text",value:L,onChange:e=>M(e.target.value),autoComplete:"name",required:!0,style:{width:"100%"}})]})]}),h&&(0,_.jsxs)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:["license"===u?(0,l.__)("Could not connect your license:","gloty")+" ":"register"===u?(0,l.__)("Your license was created, but we couldn't register this site:","gloty")+" ":"",h]}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[!H&&(0,_.jsx)(f.Button,{variant:"primary",onClick:D,isBusy:m,disabled:m||!B.trim()||!L.trim()||"existing"===r&&!e?.license?.hasKey&&!c.trim(),children:m?(0,l.__)("Connecting…","gloty"):"existing"===r?(0,l.__)("Activate license & connect","gloty"):(0,l.__)("Start free trial & connect","gloty")}),(0,_.jsx)(f.Button,{variant:H?"primary":"secondary",onClick:()=>t(2),disabled:m||!H,children:(0,l.__)("Next","gloty")})]})]})]});case 2:return(0,_.jsxs)(f.Card,{className:"wpshelf-onboard-card",children:[(0,_.jsx)(f.CardHeader,{children:(0,l.__)("Language setup","gloty")}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsxs)("p",{children:[(0,l.__)("Your source language is set to:","gloty")," ",(0,_.jsx)("strong",{children:$})]}),I.length>0?(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("p",{children:(0,l.__)("Active target languages:","gloty")}),(0,_.jsx)("div",{className:"wpshelf-row",children:I.map(e=>(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--info",children:e},e))})]}):(0,_.jsx)(f.Notice,{status:"warning",isDismissible:!1,children:(0,l.__)("No target languages enabled yet. Enable them under the Languages tab.","gloty")}),(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:12},children:(0,l.__)("You can always adjust languages later under the Languages tab.","gloty")}),(0,_.jsx)("div",{style:{marginTop:20,marginBottom:12,borderTop:"1px solid var(--wpshelf-line-soft)"}}),(0,_.jsx)("p",{children:(0,l.__)("Install WordPress language packs so core, admin, theme, and plugin strings load translated .mo files for your locales — including JavaScript-rendered blocks like the WooCommerce Cart and Checkout that Gloty cannot translate from page HTML. This uses the same downloads as Settings → General → Site Language.","gloty")}),k&&(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:k}),C?.can_install&&C?.message&&0===C?.items?.length&&(0,_.jsx)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",children:C.message}),z&&z.total>0&&0===z.failed&&(0,_.jsx)(f.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: 1: total locales, 2: newly installed, 3: already on disk */ /* translators: 1: total locales, 2: newly installed, 3: already on disk */ 55 (0,l.__)("Language packs processed: %1$d locale(s), %2$d installed, %3$d already present.","gloty"),z.total,z.installed,z.skipped)}),z&&z.failed>0&&(0,_.jsx)(f.Notice,{status:"warning",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: 1: succeeded or skipped count, 2: failed count */ /* translators: 1: succeeded or skipped count, 2: failed count */ 56 (0,l.__)("Some packs could not be installed (%1$d ok, %2$d failed). Try again or install languages under Settings → General.","gloty"),z.total-z.failed,z.failed)}),z&&z.pluginsInstalled>0&&(0,_.jsx)(f.Notice,{status:"success",isDismissible:!1,className:"wpshelf-mt",children:(0,l.sprintf)(/* translators: %d: number of plugin language packs installed */ /* translators: %d: number of plugin language packs installed */ 57 (0,l._n)("Installed %d plugin language pack so block-based screens (e.g. WooCommerce Cart & Checkout) render translated.","Installed %d plugin language packs so block-based screens (e.g. WooCommerce Cart & Checkout) render translated.",z.pluginsInstalled,"gloty"),z.pluginsInstalled)}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,_.jsx)(f.Button,{variant:"tertiary",href:"admin.php?page=gloty-languages&tab=languages",children:(0,l.__)("Open Languages","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>t(1),children:(0,l.__)("Back","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",onClick:O,isBusy:b,disabled:b,children:(0,l.__)("Install WordPress language packs","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>t(3),disabled:0===I.length,children:(0,l.__)("Next","gloty")})]})]})]});case 3:return(0,_.jsxs)(f.Card,{className:"wpshelf-onboard-card",children:[(0,_.jsx)(f.CardHeader,{children:(0,l.__)("Content scan","gloty")}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{children:(0,l.__)("A content scan registers your existing posts and pages for translation. You can run a quick scan now or do it later from the Sync tab.","gloty")}),h&&(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,className:"wpshelf-mt",children:h}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,_.jsx)(f.Button,{variant:"secondary",onClick:()=>t(2),children:(0,l.__)("Back","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:P,isBusy:m,disabled:m,children:(0,l.__)("Start scan now","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>{R(),t(4)},children:(0,l.__)("Skip for now","gloty")})]})]})]});case 4:return(0,_.jsx)(f.Card,{className:"wpshelf-onboard-card",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("h2",{style:{marginTop:0},children:(0,l.__)("You're all set!","gloty")}),(0,_.jsx)("p",{children:(0,l.__)("Gloty is configured and ready to translate. Visit your site with a language prefix to start capturing template strings, or use the Sync tab to scan content and generate translations.","gloty")}),v&&(0,_.jsx)(f.Notice,{status:"success",isDismissible:!1,children:(0,l.__)("Content scan started successfully.","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{marginTop:16},children:[(0,_.jsx)(f.Button,{variant:"primary",href:"admin.php?page=gloty",children:(0,l.__)("Go to Dashboard","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",href:"admin.php?page=gloty-sync&tab=sync",children:(0,l.__)("View sync status","gloty")})]}),(0,_.jsxs)("div",{className:"wpshelf-role-handoff",children:[(0,_.jsx)("h3",{className:"wpshelf-section-heading",children:(0,l.__)("Next actions by role","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-role-grid",children:[(0,_.jsx)(f.Card,{children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("strong",{children:(0,l.__)("Site owner","gloty")}),(0,_.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Confirm provider limits and monitor queue and processing health.","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",href:"admin.php?page=gloty-sync&tab=sync&view=workspace",children:(0,l.__)("Open Sync workspace","gloty")})]})}),(0,_.jsx)(f.Card,{children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("strong",{children:(0,l.__)("Content manager","gloty")}),(0,_.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Review stale rows first and manually improve priority translations.","gloty")}),(0,_.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("They do not need an administrator account — under Settings you can let a role correct translations, optionally in one language only.","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",href:"admin.php?page=gloty-translations&tab=translations&view=workspace",children:(0,l.__)("Open Translations","gloty")})]})}),(0,_.jsx)(f.Card,{children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("strong",{children:(0,l.__)("Developer","gloty")}),(0,_.jsx)("p",{className:"wpshelf-muted",children:(0,l.__)("Validate language packs, route prefixes, and switcher behavior on frontend pages.","gloty")}),(0,_.jsx)(f.Button,{variant:"secondary",href:"admin.php?page=gloty-languages&tab=languages&view=languages",children:(0,l.__)("Open Languages","gloty")})]})})]})]})]})});default:return null}})()]})}const Ps=[{key:"capture",label:(0,l.__)("Collected","gloty"),tab:"sync",hint:(0,l.__)("Strings found on your site. Opens the content scan.","gloty")},{key:"queued",label:(0,l.__)("Queued","gloty"),tab:"sync",hint:(0,l.__)("Waiting to be sent. Opens the sync queue.","gloty")},{key:"dispatch",label:(0,l.__)("Sent","gloty"),tab:"sync",hint:(0,l.__)("In flight to the translator. Opens the job list.","gloty")},{key:"processing",label:(0,l.__)("Translating","gloty"),tab:"translations",filters:{status:"processing"},hint:(0,l.__)("Opens these rows in the translations table.","gloty")},{key:"completed",label:(0,l.__)("Done","gloty"),hint:(0,l.__)("Distinct strings finished in each language you have enabled — counted once per language, so it is smaller than the number of rows in the translations table.","gloty")},{key:"stale",label:(0,l.__)("Out of date","gloty"),tab:"translations",filters:{stale:"1"},hint:(0,l.__)("Opens the translations whose source text has changed.","gloty")}],$s={auto:(0,l.__)("Show synced translations","gloty"),manual:(0,l.__)("Show manually edited translations","gloty"),pending:(0,l.__)("Show translations waiting to be sent","gloty"),processing:(0,l.__)("Show translations in progress","gloty")};function Is({boot:e,onNavigate:s}){const t=Me(),[a,i]=(0,n.useState)(!1),[r,o]=(0,n.useState)(!1),c=(0,w.useSelect)(e=>e(Ms).getDashboard(),[]),d=(0,w.useSelect)(e=>e(Ms).isDashboardLoading(),[]),h=(0,w.useSelect)(e=>e(Ms).getDashboardError(),[]),g=(0,n.useCallback)(async()=>{(0,w.dispatch)(Ms).dashboardLoading();try{const e=await y()({path:"/gloty/v1/dashboard",parse:!0});(0,w.dispatch)(Ms).receiveDashboard(e)}catch(e){(0,w.dispatch)(Ms).dashboardError(e?.message||(0,l.__)("Failed to load dashboard","gloty"))}},[]);(0,n.useEffect)(()=>{g()},[g]);const u=(0,n.useCallback)(async()=>{o(!0);try{const e=await y()({path:"/gloty/v1/maintenance/purge-stale-translations",method:"POST",data:{limit:5e3}}),s=Number(e?.removed||0),a=Number(e?.remaining||0);0===s?t.info((0,l.__)("Nothing was out of date.","gloty")):t.success(a>0?(0,l.sprintf)(/* translators: 1: rows removed, 2: rows still out of date */ /* translators: 1: rows removed, 2: rows still out of date */ 58 (0,l.__)("%1$s out-of-date translations removed and re-queued. %2$s still to go — run it again.","gloty"),te(s),te(a)):(0,l.sprintf)(/* translators: %s: number of rows removed */ /* translators: %s: number of rows removed */ 59 (0,l.__)("%s out-of-date translations removed and re-queued for translation.","gloty"),te(s))),await g()}catch(e){t.error(e?.message||(0,l.__)("Could not remove the out-of-date entries.","gloty"))}finally{o(!1),i(!1)}},[g,t]);if(d&&!c)return(0,_.jsxs)("div",{className:"wpshelf-screen",children:[(0,_.jsx)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[0,1,2].map(e=>(0,_.jsx)(f.Card,{className:"wpshelf-stat",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("span",{className:"wpshelf-shimmer",style:{width:"40%",height:12,marginBottom:10}}),(0,_.jsx)("span",{className:"wpshelf-shimmer",style:{width:"30%",height:28,marginBottom:8}}),(0,_.jsx)("span",{className:"wpshelf-shimmer",style:{width:"60%",height:12}})]})},e))}),(0,_.jsx)(de,{cols:5,rows:4,headers:[(0,l.__)("Original","gloty"),(0,l.__)("Translated","gloty"),(0,l.__)("Lang","gloty"),(0,l.__)("Status","gloty"),(0,l.__)("Updated","gloty")]})]});if(h)return(0,_.jsx)("div",{className:"wpshelf-screen",children:(0,_.jsx)(f.Notice,{status:"error",isDismissible:!1,children:h})});if(!c)return(0,_.jsx)(ie,{icon:"\\uD83D\\uDCCA",title:(0,l.__)("No data yet","gloty"),hint:(0,l.__)("Visit the front end in a target language to register template strings, or use the Sync tab to scan your content.","gloty")});const m=c.overview||{},x=c.status_breakdown||{},v=m.status_model||{},j=c.language_progress||[],b=(x.auto||0)+(x.manual||0)+(x.pending||0)+(x.processing||0),N=m.source_count??m.total_strings??0,C=m.translated_count??(x.auto||0)+(x.manual||0),S=m.pending_count??0,k=m.stale_count??0,T=m.target_languages??Math.max(0,(m.languages_active??1)-1),B=m.characters_per_language??0,E=m.characters_all_languages??B*T,L=m.expected_translations??N*Math.max(1,T),M={source:0===N?[{label:(0,l.__)("Scan content for strings","gloty"),tab:"sync"}]:[{label:(0,l.__)("Browse strings","gloty"),tab:"translations"}],translated:0===C?[{label:(0,l.__)("Start your first translation","gloty"),tab:"sync"}]:[{label:(0,l.__)("Review translations","gloty"),tab:"translations",filters:{status:"translated"}},{label:(0,l.__)("Review manual edits","gloty"),tab:"translations",filters:{status:"manual"}}],pending:S>0?[{label:(0,l.__)("Translate pending","gloty"),tab:"sync",prominent:!0},{label:(0,l.__)("View pending rows","gloty"),tab:"translations",filters:{status:"pending"}}]:null,stale:k>0?[{label:(0,l.__)("Re-sync out-of-date items","gloty"),tab:"sync"},{label:(0,l.__)("Review out-of-date rows","gloty"),tab:"translations",filters:{stale:"1"}}]:null,languages:0===T?[{label:(0,l.__)("Add a target language","gloty"),tab:"languages"}]:[{label:(0,l.__)("Manage languages","gloty"),tab:"languages"}]},A=e=>{const t=(Array.isArray(e)?e:[e]).filter(Boolean);return 0!==t.length&&s?(0,_.jsx)("div",{className:"wpshelf-stat-grid__cta"+(t.some(e=>e.prominent)?" wpshelf-stat-grid__cta--prominent":""),children:t.map(e=>(0,_.jsxs)(f.Button,{variant:e.prominent?"secondary":"link",onClick:()=>s(e.tab,e.filters||null),children:[e.label," →"]},e.label))}):null},D=e=>({template_string:(0,l.__)("theme & UI (unique gettext strings seen on localized pages)","gloty"),post_field:(0,l.__)("post / page segments (title, excerpt, each translatable block slice)","gloty"),term_field:(0,l.__)("taxonomy name & description","gloty")}[e]??e);return(0,_.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Dashboard","gloty"),children:[(0,_.jsx)(Xe,{boot:e,onNavigate:s}),(0,_.jsx)(Ze,{hasLanguages:T>0,hasSource:N>0,hasTranslated:C>0,pendingCount:S,onNavigate:s}),(0,_.jsx)(cs,{onNavigate:s}),(0,_.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--hero",children:[(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--translated",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Translated","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:te(C)}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:0===N?(0,l.__)("no content captured yet","gloty"):0===T?(0,l.__)("add a target language to begin","gloty"):(0,l.sprintf)(/* translators: 1: total expected translations (strings × languages), 2: number of target languages */ /* translators: 1: total expected translations (strings × languages), 2: number of target languages */ 60 (0,l._n)("of %1$s translation in %2$d language","of %1$s translations across %2$d languages",T,"gloty"),L.toLocaleString(),T)}),A(M.translated)]})}),(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--pending",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Pending","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:te(S)}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:S>0?(0,l.__)("strings waiting to be translated","gloty"):(0,l.__)("queue is clear","gloty")}),A(M.pending)]})}),(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--stale",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Out of date","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value",children:te(k)}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:k>0?(0,l.__)("source content changed","gloty"):(0,l.__)("all in sync","gloty")}),A(M.stale)]})})]}),(0,_.jsxs)("div",{className:"wpshelf-stat-grid wpshelf-stat-grid--supporting",children:[(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--source",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Source strings","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value wpshelf-stat__value--medium",children:te(N)}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:(0,l.__)("every translatable text snippet found on your site","gloty")}),B>0&&(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:T>0?(0,l.sprintf)(/* translators: 1: characters in the site, 2: characters needed for every active language */ /* translators: 1: characters in the site, 2: characters needed for every active language */ 61 (0,l.__)("%1$s characters of source text — about %2$s to translate into every language you have enabled","gloty"),te(B),te(E)):(0,l.sprintf)(/* translators: %s: characters in the site */ /* translators: %s: characters in the site */ 62 (0,l.__)("%s characters of source text — this is what a language costs to add","gloty"),te(B))}),m.registry_by_source_kind&&Object.keys(m.registry_by_source_kind).length>0&&(0,_.jsx)("ul",{className:"wpshelf-stat__breakdown",children:Object.entries(m.registry_by_source_kind).map(([e,s])=>(0,_.jsxs)("li",{children:[(0,_.jsx)("strong",{children:te(s)})," ",D(e)]},e))}),A(M.source)]})}),(0,_.jsx)(f.Card,{className:"wpshelf-stat wpshelf-stat--languages",children:(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-stat__label",children:(0,l.__)("Target languages","gloty")}),(0,_.jsx)("div",{className:"wpshelf-stat__value wpshelf-stat__value--medium",children:T}),(0,_.jsx)("div",{className:"wpshelf-stat__sub",children:T>0?(0,l.sprintf)(/* translators: %s: source language code */ /* translators: %s: source language code */ 63 (0,l.__)("alongside %s as source","gloty"),(e?.language?.default||"en").toUpperCase()):(0,l.__)("no target languages enabled","gloty")}),A(M.languages)]})})]}),(0,_.jsxs)("div",{className:"wpshelf-content-boxes",children:[b>0&&(0,_.jsxs)(f.Card,{className:"wpshelf-content-box",children:[(0,_.jsxs)(f.CardHeader,{children:[(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Translation status","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:8},children:[k>0&&(0,_.jsx)(f.Button,{variant:"tertiary",size:"small",isDestructive:!0,onClick:()=>i(!0),disabled:r,isBusy:r,children:r?(0,l.__)("Removing…","gloty"):(0,l.__)("Remove out-of-date","gloty")}),(0,_.jsx)(f.Button,{variant:"tertiary",size:"small",onClick:g,disabled:d,isBusy:d,"aria-live":"polite",children:d?(0,l.__)("Refreshing…","gloty"):(0,l.__)("Refresh","gloty")})]})]}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("div",{className:"wpshelf-row",style:{gap:24},children:Object.entries(x).map(([e,t])=>$s[e]&&s?(0,_.jsxs)("button",{type:"button",className:"wpshelf-status-link",title:$s[e],onClick:()=>s("translations",{status:e}),children:[(0,_.jsx)(Q,{status:e}),(0,_.jsx)("span",{className:"wpshelf-status-link__value",children:te(t)})]},e):(0,_.jsxs)("div",{className:"wpshelf-status-link wpshelf-status-link--static",children:[(0,_.jsx)(Q,{status:e}),(0,_.jsx)("span",{className:"wpshelf-status-link__value",children:te(t)})]},e))}),Object.keys(v).length>0&&(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{margin:"16px 0 8px"},children:(0,l.__)("Each string moves through these stages: Collected → Queued → Sent → Translating → Done.","gloty")}),(0,_.jsx)("div",{className:"wpshelf-row",style:{gap:10},children:Ps.map(e=>{const t=te(v[e.key]??0);return s&&e.tab?(0,_.jsxs)("button",{type:"button",className:"wpshelf-pipeline-chip wpshelf-pipeline-chip--link",title:e.hint,onClick:()=>s(e.tab,e.filters||null),children:[(0,_.jsx)("span",{className:"wpshelf-pipeline-chip__label",children:e.label}),(0,_.jsx)("strong",{className:"wpshelf-pipeline-chip__value",children:t})]},e.key):(0,_.jsxs)("div",{className:"wpshelf-pipeline-chip",title:e.hint,children:[(0,_.jsx)("span",{className:"wpshelf-pipeline-chip__label",children:e.label}),(0,_.jsx)("strong",{className:"wpshelf-pipeline-chip__value",children:t})]},e.key)})})]})]})]}),j.length>0&&(0,_.jsxs)(f.Card,{className:"wpshelf-content-box",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Language progress","gloty")})}),(0,_.jsx)(f.CardBody,{children:j.map(e=>(0,_.jsxs)("div",{style:{marginBottom:8},children:[(0,_.jsxs)("div",{className:"wpshelf-row wpshelf-row--apart",style:{marginBottom:2},children:[(0,_.jsxs)("span",{style:{fontSize:13,fontWeight:500},children:[e.native_name||e.name," ",(0,_.jsxs)("span",{className:"wpshelf-muted",children:["(",e.code,")"]})]}),(0,_.jsxs)("span",{className:"wpshelf-muted",children:[te(e.translated),"/",te(e.total)]})]}),(0,_.jsx)(_e,{value:e.translated,max:e.total,label:`${e.percentage}%`,scale:"completion"})]},e.code))})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-content-box",children:[(0,_.jsx)(f.CardHeader,{children:(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Recent translations","gloty")})}),(0,_.jsx)(f.CardBody,{children:0===(c.recent||[]).length?(0,_.jsx)(ie,{title:(0,l.__)("No translation rows yet","gloty"),hint:(0,l.__)("Visit the front end in a target language to register template strings.","gloty")}):(0,_.jsxs)(p,{className:"wp-list-table widefat striped",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{children:(0,l.__)("Original","gloty")}),(0,_.jsx)("th",{children:(0,l.__)("Translated","gloty")}),(0,_.jsx)("th",{children:(0,l.__)("Lang","gloty")}),(0,_.jsx)("th",{children:(0,l.__)("Status","gloty")}),(0,_.jsx)("th",{children:(0,l.__)("Updated","gloty")})]})}),(0,_.jsx)("tbody",{children:c.recent.map(e=>(0,_.jsxs)("tr",{children:[(0,_.jsx)("td",{title:le(e.original)||void 0,children:le(e.original)?le(e.original).slice(0,80):(0,_.jsx)("em",{className:"wpshelf-muted",title:(0,l.__)("Structured block content — its text is captured when the block is sent for translation.","gloty"),children:(0,l.__)("Block content","gloty")})}),(0,_.jsx)("td",{title:ne(e.translated)||void 0,children:ne(e.translated)?ne(e.translated).slice(0,80):(0,_.jsx)("span",{className:"wpshelf-muted",children:"pending"===e.status||"processing"===e.status?(0,l.__)("Not translated yet","gloty"):"—"})}),(0,_.jsx)("td",{children:(0,_.jsx)("code",{children:e.language_code})}),(0,_.jsx)("td",{children:(0,_.jsx)(Q,{status:e.status})}),(0,_.jsx)("td",{className:"wpshelf-muted",children:ae(e.updated_at)})]},e.id))})]})})]})]}),a&&(0,_.jsx)(re,{title:(0,l.__)("Remove out-of-date entries?","gloty"),message:(0,l.sprintf)(/* translators: %s: number of out-of-date translations */ /* translators: %s: number of out-of-date translations */ 64 (0,l.__)("%s translations are of source text that has since changed. Removing them puts those strings back in the queue, so the next sync translates them again — which spends quota. Until it runs, visitors see the original text for those strings. Manual edits of changed content are removed too.","gloty"),te(k)),confirmLabel:(0,l.__)("Remove and re-queue","gloty"),busy:r,onConfirm:u,onCancel:()=>i(!1)})]})}function Hs({boot:e}){const s=Me(),t=(0,w.useSelect)(e=>e(Ms).getLanguages(),[]),a=(0,w.useSelect)(e=>e(Ms).isLanguagesLoading(),[]),i=(0,w.useSelect)(e=>e(Ms).getRouting(),[]),[r,o]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[h,g]=(0,n.useState)(!1),[u,m]=(0,n.useState)(""),[v,N]=(0,n.useState)(!1),[C,S]=(0,n.useState)(null),[k,T]=(0,n.useState)(!1);(0,n.useEffect)(()=>{(async()=>{(0,w.dispatch)(Ms).languagesLoading(),d(null);try{const e=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(e)}catch(e){(0,w.dispatch)(Ms).receiveLanguages({default:"en",languages:[]}),d({status:"error",message:e?.message||(0,l.__)("Could not load languages.","gloty")})}try{const e=await y()({path:"/gloty/v1/settings/routing",parse:!0});(0,w.dispatch)(Ms).receiveRouting(e)}catch(e){(0,w.dispatch)(Ms).receiveRouting({url_structure:"subdirectory"}),d(s=>"error"===s?.status?s:{status:"error",message:e?.message||(0,l.__)("Could not load routing settings.","gloty")})}})()},[]);const B=(0,n.useMemo)(()=>t?.languages||[],[t]),E=t?.default||e?.language?.default||"en",L=(0,n.useMemo)(()=>{const e=[...B];return e.sort((e,s)=>e.code===E?-1:s.code===E?1:(Number(e.sort_order)||0)-(Number(s.sort_order)||0)),e},[B,E]),M=(0,n.useMemo)(()=>L.filter(e=>e.code!==E&&1!==Number(e.is_active)),[L,E]),A=k?L:L.filter(e=>e.code===E||1===Number(e.is_active)),D=async(e,t)=>{const a=L.filter(e=>e.code!==E),n=a.findIndex(s=>s.id===e.id),i=n+t;if(n<0||i<0||i>=a.length)return;const r=a[n],c=a[i],h=Number(r.sort_order)||0,g=Number(c.sort_order)||0;o(!0),d(null);try{await Promise.all([y()({path:`/gloty/v1/languages/${r.id}`,method:"PUT",data:{sort_order:g}}),y()({path:`/gloty/v1/languages/${c.id}`,method:"PUT",data:{sort_order:h}})]),s.success((0,l.__)("Display order updated.","gloty"));const e=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(e)}catch(e){s.error(e?.message||(0,l.__)("Could not update display order.","gloty"))}finally{o(!1)}},R=i?.url_structure||e?.routing?.url_structure||"subdirectory",O=(0,n.useMemo)(()=>function(e){const s=new Set((e||[]).map(e=>String(e.code||"").toLowerCase()));return Qe.filter(e=>!s.has(e.code.toLowerCase())).map(e=>({label:`${e.native_name} — ${e.name} (${e.code})`,value:e.code}))}(B),[B]);return a&&!t?(0,_.jsx)("div",{className:"wpshelf-screen",children:(0,_.jsx)(de,{cols:5,rows:4,headers:[(0,l.__)("Language","gloty"),(0,l.__)("Code","gloty"),(0,l.__)("Direction","gloty"),(0,l.__)("Default","gloty"),(0,l.__)("Order","gloty")]})}):(0,_.jsxs)("div",{className:"wpshelf-screen",role:"region","aria-label":(0,l.__)("Languages","gloty"),children:[(0,_.jsx)("p",{className:"wpshelf-screen__lead",children:(0,l.__)("Source language is the canonical site language. Enable target languages to create URL prefixes and start capturing translations.","gloty")}),c&&(0,_.jsx)(f.Notice,{status:c.status,isDismissible:!0,onDismiss:()=>d(null),className:"wpshelf-mb",children:c.message}),(0,_.jsxs)(f.Card,{className:"wpshelf-mb",children:[(0,_.jsxs)(f.CardHeader,{children:[(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("URL strategy","gloty")}),r&&(0,_.jsx)(oe,{label:(0,l.__)("Saving…","gloty")})]}),(0,_.jsxs)(f.CardBody,{children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Choose how translated pages are addressed. This affects every translated URL on your site.","gloty")}),i?.deferred?.message&&(0,_.jsx)("p",{className:"wpshelf-muted",children:i.deferred.message}),(0,_.jsx)("div",{className:"wpshelf-urlstrategy",role:"radiogroup","aria-label":(0,l.__)("URL strategy","gloty"),children:[{value:"subdirectory",title:(0,l.__)("Path prefix","gloty"),example:"example.com/fr/page",desc:(0,l.__)("Recommended for SEO — each language gets its own path.","gloty")},{value:"parameter",title:(0,l.__)("Query parameter","gloty"),example:"example.com/page?lang=fr",desc:(0,l.__)("Simplest setup — no rewrite rules required.","gloty")}].map(e=>{const t=R===e.value;return(0,_.jsxs)("button",{type:"button",role:"radio","aria-checked":t,className:"wpshelf-urlstrategy__opt"+(t?" wpshelf-urlstrategy__opt--active":""),onClick:()=>!t&&(async e=>{o(!0),d(null);try{await y()({path:"/gloty/v1/settings/routing/update",method:"POST",data:{url_structure:e}});const t=await y()({path:"/gloty/v1/settings/routing",parse:!0});(0,w.dispatch)(Ms).receiveRouting(t),s.success((0,l.__)("Routing settings saved.","gloty"))}catch(e){s.error(e?.message||(0,l.__)("Could not save routing settings.","gloty"))}finally{o(!1)}})(e.value),disabled:r,children:[(0,_.jsxs)("span",{className:"wpshelf-urlstrategy__top",children:[(0,_.jsx)("span",{className:"wpshelf-urlstrategy__title",children:e.title}),t?(0,_.jsxs)("span",{className:"wpshelf-chip wpshelf-chip--success",children:["✓ ",(0,l.__)("Selected","gloty")]}):(0,_.jsx)("span",{className:"wpshelf-urlstrategy__pick wpshelf-muted",children:(0,l.__)("Use this","gloty")})]}),(0,_.jsx)("code",{className:"wpshelf-urlstrategy__example",children:e.example}),(0,_.jsx)("span",{className:"wpshelf-urlstrategy__desc wpshelf-muted",children:e.desc})]},e.value)})})]})]}),(0,_.jsxs)(f.Card,{className:"wpshelf-mb",children:[(0,_.jsxs)(f.CardHeader,{children:[(0,_.jsx)("span",{className:"wpshelf-content-box__title",children:(0,l.__)("Target languages","gloty")}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:12},children:[r&&(0,_.jsx)(oe,{label:(0,l.__)("Saving…","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:()=>{m(""),g(!0)},disabled:r,children:(0,l.__)("Add language","gloty")})]})]}),(0,_.jsxs)(f.CardBody,{children:[0===B.length?(0,_.jsx)(ie,{title:(0,l.__)("No languages configured","gloty"),hint:(0,l.__)("Add a target language to start capturing translations.","gloty")}):(0,_.jsxs)(p,{className:"wp-list-table widefat striped",children:[(0,_.jsx)("thead",{children:(0,_.jsxs)("tr",{children:[(0,_.jsx)("th",{children:(0,l.__)("Code","gloty")}),(0,_.jsx)("th",{children:(0,l.__)("Language","gloty")}),(0,_.jsx)("th",{title:(0,l.__)("The language your content is written in. Every other language is translated from it.","gloty"),children:(0,l.__)("Source","gloty")}),(0,_.jsx)("th",{title:(0,l.__)("Controls the order languages appear in the front-end switcher.","gloty"),children:(0,l.__)("Order","gloty")}),(0,_.jsx)("th",{title:(0,l.__)("Active languages show in the switcher and are served to visitors. Inactive ones stay configured but hidden.","gloty"),children:(0,l.__)("Active","gloty")}),(0,_.jsx)("th",{children:(0,_.jsx)("span",{className:"screen-reader-text",children:(0,l.__)("Actions","gloty")})})]})}),(0,_.jsx)("tbody",{children:A.map(e=>{const t=L.filter(e=>e.code!==E),a=t[0]?.id,n=t[t.length-1]?.id,i=e.native_name||e.name||e.code;return(0,_.jsxs)("tr",{children:[(0,_.jsx)("td",{children:(0,_.jsx)("code",{children:e.code})}),(0,_.jsxs)("td",{children:[e.native_name," ",(0,_.jsxs)("span",{className:"wpshelf-muted",children:["(",e.name,")"]})]}),(0,_.jsx)("td",{children:e.code===E?(0,_.jsx)("span",{className:"wpshelf-chip wpshelf-chip--success",title:(0,l.__)("This is your source language — content is translated from it.","gloty"),children:(0,l.__)("Source","gloty")}):(0,_.jsx)(f.Button,{variant:"link",onClick:()=>(async e=>{o(!0),d(null);try{await y()({path:"/gloty/v1/languages/default",method:"POST",data:{code:e}});const t=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(t),s.success((0,l.__)("Default language updated.","gloty"))}catch(e){s.error(e?.message||(0,l.__)("Could not set default language.","gloty"))}finally{o(!1)}})(e.code),disabled:r,children:(0,l.__)("Make source","gloty")})}),(0,_.jsx)("td",{children:e.code!==E?(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:4},children:[(0,_.jsx)(f.Button,{variant:"tertiary",isSmall:!0,disabled:r||e.id===a,onClick:()=>D(e,-1),"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 65 (0,l.__)("Move %s up","gloty"),i),children:(0,_.jsx)(x,{icon:j,size:20})}),(0,_.jsx)(f.Button,{variant:"tertiary",isSmall:!0,disabled:r||e.id===n,onClick:()=>D(e,1),"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 66 (0,l.__)("Move %s down","gloty"),i),children:(0,_.jsx)(x,{icon:b,size:20})})]}):(0,_.jsx)("span",{className:"wpshelf-muted",children:"—"})}),(0,_.jsx)("td",{children:(0,_.jsx)(f.ToggleControl,{__nextHasNoMarginBottom:!0,label:1===Number(e.is_active)?(0,l.__)("Active","gloty"):(0,l.__)("Inactive","gloty"),help:e.code===E?(0,l.__)("Source language always stays active.","gloty"):void 0,checked:1===Number(e.is_active),disabled:r||e.code===E,onChange:t=>(async(e,t)=>{o(!0),d(null);try{await y()({path:`/gloty/v1/languages/${e}`,method:"PUT",data:{is_active:t}}),s.success((0,l.__)("Language updated.","gloty"));const a=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(a)}catch(e){s.error(e?.message||(0,l.__)("Error updating","gloty"))}finally{o(!1)}})(e.id,t)})}),(0,_.jsx)("td",{children:e.code!==E&&(0,_.jsx)(f.Button,{variant:"tertiary",isDestructive:!0,isSmall:!0,onClick:()=>S(e),disabled:r,"aria-label":(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 67 (0,l.__)("Remove %s","gloty"),i),children:(0,l.__)("Remove","gloty")})})]},e.id)})})]}),M.length>0&&(0,_.jsx)("div",{className:"wpshelf-lang-showmore",children:(0,_.jsxs)(f.Button,{variant:"link",onClick:()=>T(e=>!e),"aria-expanded":k,children:[k?(0,l.__)("Hide inactive languages","gloty"):(0,l.sprintf)(/* translators: %d: number of inactive (configured but disabled) languages */ /* translators: %d: number of inactive (configured but disabled) languages */ 68 (0,l._n)("Show %d inactive language","Show %d inactive languages",M.length,"gloty"),M.length),(0,_.jsx)(x,{icon:k?j:b,size:20})]})}),B.length>0&&(0,_.jsx)("p",{className:"wpshelf-muted wpshelf-lang-legend",children:(0,l.__)("Source is the language you author in. Active languages appear in the switcher and are served to visitors; turn one off to keep it configured but hidden. Order sets where each appears in the switcher.","gloty")})]})]}),h&&(0,_.jsxs)(f.Modal,{title:(0,l.__)("Add language","gloty"),onRequestClose:()=>{v||(g(!1),m(""))},className:"wpshelf-language-modal",children:[(0,_.jsx)("p",{className:"wpshelf-muted",style:{marginTop:0},children:(0,l.__)("Pick a language. Base tags only — regional variants like en-GB or pt-BR are not offered.","gloty")}),(0,_.jsx)(f.ComboboxControl,{label:(0,l.__)("Language","gloty"),value:u,onChange:e=>m(e||""),options:O,allowReset:!0,__nextHasNoMarginBottom:!0}),(0,_.jsx)("div",{style:{marginTop:12},children:(0,_.jsx)(hs,{code:u})}),(0,_.jsxs)("div",{className:"wpshelf-row",style:{gap:8,marginTop:16,justifyContent:"flex-end"},children:[(0,_.jsx)(f.Button,{variant:"tertiary",onClick:()=>{g(!1),m("")},disabled:v,children:(0,l.__)("Cancel","gloty")}),(0,_.jsx)(f.Button,{variant:"primary",onClick:async()=>{if(!u)return;const e=es(u);if(e){N(!0);try{await y()({path:"/gloty/v1/languages",method:"POST",data:{code:e.code,name:e.name,native_name:e.native_name,is_rtl:!!e.is_rtl}});const t=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(t),s.success((0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 69 (0,l.__)("%s added.","gloty"),e.native_name)),g(!1),m("")}catch(e){s.error(e?.message||(0,l.__)("Could not add language.","gloty"))}finally{N(!1)}}else s.error((0,l.__)("Unknown language code.","gloty"))},disabled:!u||v,isBusy:v,children:(0,l.__)("Add language","gloty")})]})]}),C&&(0,_.jsx)(re,{title:(0,l.__)("Remove language","gloty"),message:(0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 70 (0,l.__)("Remove %s? Translated content in this language will no longer be served, but the stored translations will remain in the database.","gloty"),C.native_name||C.name||C.code),confirmLabel:(0,l.__)("Remove","gloty"),busy:r,onConfirm:async()=>{const e=C;if(!e)return;const t=e.native_name||e.name||e.code;o(!0);try{await y()({path:`/gloty/v1/languages/${e.id}`,method:"DELETE"});const a=await y()({path:"/gloty/v1/languages",parse:!0});(0,w.dispatch)(Ms).receiveLanguages(a),s.success((0,l.sprintf)(/* translators: %s: language name */ /* translators: %s: language name */ 71 (0,l.__)("%s removed.","gloty"),t))}catch(e){s.error(e?.message||(0,l.__)("Could not remove language.","gloty"))}finally{o(!1),S(null)}},onCancel:()=>S(null)})]})}function Gs({boot:e}){const s=!e?.onboardingComplete,t=As(e?.adminPage||"gloty"),a=Ds().tab||t,i=s&&"dashboard"===a?"onboarding":a,[r,o]=(0,n.useState)(!1),c=!!e?.devMode||"design-system"===a,d=!1!==e?.capabilities?.manageOptions,h=d?[{label:(0,l.__)("Operations","gloty"),items:[{name:"dashboard",title:(0,l.__)("Overview","gloty"),icon:C},{name:"sync",title:(0,l.__)("Sync","gloty"),icon:S},{name:"translations",title:(0,l.__)("Translations","gloty"),icon:N},{name:"analytics",title:(0,l.__)("Analytics","gloty"),icon:k}]},{label:(0,l.__)("Configure","gloty"),items:[{name:"languages",title:(0,l.__)("Languages","gloty"),icon:T},{name:"glossary",title:(0,l.__)("Glossary","gloty"),icon:B},{name:"seo",title:(0,l.__)("SEO","gloty"),icon:E},{name:"settings",title:(0,l.__)("Settings","gloty"),icon:L}]},{label:(0,l.__)("Account","gloty"),items:[{name:"billing",title:(0,l.__)("Billing","gloty"),icon:M}]},...e?.onboardingComplete?[]:[{label:(0,l.__)("Setup","gloty"),items:[{name:"onboarding",title:(0,l.__)("Setup","gloty"),icon:A}]}],...c?[{label:(0,l.__)("Developer","gloty"),items:[{name:"design-system",title:(0,l.__)("Design system","gloty"),icon:D}]}]:[]]:[{label:(0,l.__)("Operations","gloty"),items:[{name:"translations",title:(0,l.__)("Translations","gloty"),icon:N}]}],g=h.flatMap(e=>e.items),u=e=>d&&"design-system"===e||g.some(s=>s.name===e),p=d?"dashboard":"translations",m=u(i)?i:p,[y,w]=(0,n.useState)(m);(0,n.useEffect)(()=>{const e=()=>{const e=Ds(),s=e.tab&&u(e.tab)?e.tab:p;w(s)};return window.addEventListener("popstate",e),()=>window.removeEventListener("popstate",e)},[g]);const[v,j]=(0,n.useState)(null),b=(e,s=null)=>{w(e),j(s),function(e,s=null){if("undefined"==typeof window)return;const t=new URL(window.location.href);t.searchParams.set("page",{dashboard:"gloty",translations:"gloty-translations",sync:"gloty-sync",languages:"gloty-languages",glossary:"gloty-glossary",settings:"gloty-settings",billing:"gloty-billing",onboarding:"gloty-onboarding","design-system":"gloty-design-system"}[e]||"gloty"),t.searchParams.set("tab",e),s?t.searchParams.set("view",s):t.searchParams.delete("view"),window.history.replaceState({},"",t.toString())}(e)};return(0,_.jsx)(Le,{children:(0,_.jsxs)("div",{className:"wpshelf-app",children:[(0,_.jsx)("a",{className:"screen-reader-text",href:"#gloty-main-content",children:(0,l.__)("Skip to main content","gloty")}),(0,_.jsxs)("header",{className:"wpshelf-app__header",children:[(0,_.jsxs)("div",{className:"wpshelf-app__brand",children:[(0,_.jsx)("div",{className:"wpshelf-app__mark","aria-hidden":"true",children:(0,_.jsx)("svg",{viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:(0,_.jsxs)("g",{transform:"matrix(1 0 0 -1 0 48)",children:[(0,_.jsx)("path",{d:"M39 24 A15 15 0 1 0 34.6 34.6",stroke:"#ffffff",strokeWidth:"2.4",strokeLinecap:"round"}),(0,_.jsx)("path",{d:"M39 24 H27.5",stroke:"#ffffff",strokeWidth:"2.4",strokeLinecap:"round"}),(0,_.jsx)("ellipse",{cx:"24",cy:"24",rx:"6.4",ry:"15",stroke:"#ffffff",strokeWidth:"1.6",strokeOpacity:"0.7"}),(0,_.jsx)("path",{d:"M13.5 16 H34.5",stroke:"#ffffff",strokeWidth:"1.5",strokeLinecap:"round",strokeOpacity:"0.55"}),(0,_.jsx)("path",{d:"M13.5 32 H32",stroke:"#ffffff",strokeWidth:"1.5",strokeLinecap:"round",strokeOpacity:"0.55"}),(0,_.jsx)("circle",{cx:"27.5",cy:"24",r:"2.4",fill:"#ffffff"})]})})}),(0,_.jsxs)("div",{className:"wpshelf-app__brand-text",children:[(0,_.jsx)("h1",{className:"wpshelf-app__title",children:(0,l.__)("Gloty","gloty")}),(0,_.jsx)("p",{className:"wpshelf-app__subtitle",children:(0,l.__)("AI-powered multilingual WordPress, done locally","gloty")})]})]}),(0,_.jsxs)("div",{className:"wpshelf-app__header-right",children:[(0,_.jsx)(ns,{onNavigate:b}),(0,_.jsxs)("span",{className:"wpshelf-app__version",children:["v",e?.plugin?.version]})]})]}),(0,_.jsxs)("div",{className:"wpshelf-layout"+(r?" wpshelf-layout--collapsed":""),children:[(0,_.jsxs)("nav",{className:"wpshelf-sidebar","aria-label":(0,l.__)("Gloty navigation","gloty"),children:[(0,_.jsx)("button",{type:"button",className:"wpshelf-sidebar__toggle",onClick:()=>o(e=>!e),"aria-label":r?(0,l.__)("Expand navigation","gloty"):(0,l.__)("Collapse navigation","gloty"),children:r?"❯":"❮"}),h.map(e=>(0,_.jsxs)("div",{className:"wpshelf-sidebar__section",children:[!r&&(0,_.jsx)("div",{className:"wpshelf-sidebar__section-label",children:e.label}),e.items.map(e=>{const s=(0,_.jsxs)("button",{type:"button",className:"wpshelf-sidebar__item"+(y===e.name?" wpshelf-sidebar__item--active":""),onClick:()=>b(e.name),"aria-selected":y===e.name,"aria-label":e.title,role:"tab",children:[(0,_.jsx)(x,{icon:e.icon,size:20,className:"wpshelf-sidebar__item-icon"}),!r&&(0,_.jsx)("span",{className:"wpshelf-sidebar__item-label",children:e.title})]},e.name);return r?(0,_.jsx)(f.Tooltip,{text:e.title,children:s},e.name):s})]},e.label))]}),(0,_.jsxs)("div",{id:"gloty-main-content",className:"wpshelf-tab-content",role:"tabpanel",tabIndex:"-1",children:[(0,_.jsx)(ws,{license:e?.license,hideOnboarding:"onboarding"===y}),"dashboard"===y?(0,_.jsx)(Is,{boot:e,onNavigate:b}):"translations"===y?(0,_.jsx)(Bs,{boot:e,filters:v}):"sync"===y?(0,_.jsx)(js,{boot:e,onNavigate:b}):"languages"===y?(0,_.jsx)(Hs,{boot:e}):"glossary"===y?(0,_.jsx)(as,{boot:e}):"seo"===y?(0,_.jsx)(vs,{boot:e}):"analytics"===y?(0,_.jsx)(Y,{}):"billing"===y?(0,_.jsx)(ke,{boot:e}):"onboarding"===y?(0,_.jsx)(Os,{boot:e}):"design-system"===y?(0,_.jsx)(We,{}):(0,_.jsx)(ys,{boot:e})]})]})]})})}function zs(){const e=document.getElementById("gloty-admin-root");if(!e)return;const s="undefined"!=typeof window?window.glotyBoot:void 0;s&&function(e){e?.api&&(y().use(y().createNonceMiddleware(e.api.restNonce)),y().use((e,s)=>{if("GET"!==(e.method??"GET").toUpperCase()||e.url)return s(e);const t=e.path??"",a=t.includes("?")?"&":"?";return s({...e,path:`${t}${a}_cb=${Date.now()}`,cache:"no-store"})}),y().use((s,t)=>{if(s.url)return t(s);const a=s.path??"",l=e.api.restRoot.replace(/\/$/,""),n=a.startsWith("/")?a:`/${a}`;return t({...s,url:l+n})}))}(s),(0,a.H)(e).render((0,_.jsx)(Gs,{boot:s}))}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",zs):zs()},930(e,s,t){var a=t(795);s.H=a.createRoot,a.hydrateRoot},795(e){e.exports=window.ReactDOM}},t={};function a(e){var l=t[e];if(void 0!==l)return l.exports;var n=t[e]={exports:{}};return s[e](n,n.exports,a),n.exports}a.m=s,e=[],a.O=(s,t,l,n)=>{if(!t){var i=1/0;for(d=0;d<e.length;d++){for(var[t,l,n]=e[d],r=!0,o=0;o<t.length;o++)(!1&n||i>=n)&&Object.keys(a.O).every(e=>a.O[e](t[o]))?t.splice(o--,1):(r=!1,n<i&&(i=n));if(r){e.splice(d--,1);var c=l();void 0!==c&&(s=c)}}return s}n=n||0;for(var d=e.length;d>0&&e[d-1][2]>n;d--)e[d]=e[d-1];e[d]=[t,l,n]},a.n=e=>{var s=e&&e.__esModule?()=>e.default:()=>e;return a.d(s,{a:s}),s},a.d=(e,s)=>{for(var t in s)a.o(s,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:s[t]})},a.o=(e,s)=>Object.prototype.hasOwnProperty.call(e,s),(()=>{var e={366:0,757:0};a.O.j=s=>0===e[s];var s=(s,t)=>{var l,n,[i,r,o]=t,c=0;if(i.some(s=>0!==e[s])){for(l in r)a.o(r,l)&&(a.m[l]=r[l]);if(o)var d=o(a)}for(s&&s(t);c<i.length;c++)n=i[c],a.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return a.O(d)},t=globalThis.webpackChunk_wp_shelf_gloty=globalThis.webpackChunk_wp_shelf_gloty||[];t.forEach(s.bind(null,0)),t.push=s.bind(null,t.push.bind(t))})();var l=a.O(void 0,[757],()=>a(843));l=a.O(l)})(); -
gloty/trunk/build/style-gloty-editor-sidebar-rtl.css
r3688478 r3748411 1 .wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-bg:#fafafa;--wpshelf-surface:#fff;--wpshelf-surface-alt:#f5f5f5;--wpshelf-ink:#0a0a0a;--wpshelf-ink-soft:#525252;--wpshelf-muted:#6b6b6b;--wpshelf-line:#e5e5e5;--wpshelf-line-soft:#f0f0f0;--wpshelf-fill:#0a0a0a;--wpshelf-fill-hover:#333;--wpshelf-fill-ink:#fff;--wpshelf-accent:#2271b1;--wpshelf-accent-dark:#135e96;--wpshelf-accent-50:#f0f6fc;--wpshelf-accent-100:#72aee6;--wpshelf-success:#18794e;--wpshelf-success-dark:#106239;--wpshelf-success-50:#f0f9f4;--wpshelf-warn:#d97706;--wpshelf-warn-dark:#8a5300;--wpshelf-warn-50:#fdf8ec;--wpshelf-danger:#b42318;--wpshelf-danger-50:#fdf3f3;--wpshelf-brand-fill:var(--wpshelf-accent);--wpshelf-hue:247;--wpshelf-chroma:0.10;--wpshelf-control-h:32px;--wpshelf-control-h-sm:26px;--wpshelf-cell-pad-y:10px;--wpshelf-cell-pad-x:14px;--wpshelf-font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;--wpshelf-font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;--wpshelf-text-2xs:10px;--wpshelf-text-xs:11px;--wpshelf-text-sm:12px;--wpshelf-text-base:13px;--wpshelf-text-md:14px;--wpshelf-text-lg:15px;--wpshelf-text-xl:18px;--wpshelf-text-2xl:22px;--wpshelf-text-stat-md:24px;--wpshelf-text-stat-lg:30px;--wpshelf-leading-tight:1.15;--wpshelf-leading-snug:1.4;--wpshelf-leading-normal:1.55;--wpshelf-leading-relaxed:1.65;--wpshelf-weight-normal:400;--wpshelf-weight-medium:500;--wpshelf-weight-semi:600;--wpshelf-weight-bold:700;--wpshelf-tracking-tight:-0.02em;--wpshelf-tracking-normal:0;--wpshelf-tracking-caps:0.04em;--wpshelf-tracking-wide:0.06em;--wpshelf-space-1:4px;--wpshelf-space-2:8px;--wpshelf-space-3:12px;--wpshelf-space-4:16px;--wpshelf-space-5:20px;--wpshelf-space-6:24px;--wpshelf-space-7:28px;--wpshelf-space-8:32px;--wpshelf-space-10:40px;--wpshelf-space-14:56px;--wpshelf-space-16:64px;--wpshelf-sidebar-width:200px;--wpshelf-sidebar-collapsed:48px;--wpshelf-content-max:1280px;--wpshelf-measure:52em;--wpshelf-duration-fast:0.12s;--wpshelf-duration-base:0.15s;--wpshelf-duration-slow:0.20s;--wpshelf-duration-xslow:0.30s;--wpshelf-ease:cubic-bezier(0.4,0,0.2,1);--wpshelf-ease-out:cubic-bezier(0,0,0.2,1);--wpshelf-ease-in:cubic-bezier(0.4,0,1,1);--wpshelf-ease-spring:cubic-bezier(0.32,0.72,0,1);--wpshelf-ease-out-quart:cubic-bezier(0.25,1,0.5,1);--wpshelf-transition-color:color var(--wpshelf-duration-fast) var(--wpshelf-ease),background var(--wpshelf-duration-fast) var(--wpshelf-ease),border-color var(--wpshelf-duration-fast) var(--wpshelf-ease);--wpshelf-transition-lift:transform var(--wpshelf-duration-base) var(--wpshelf-ease),box-shadow var(--wpshelf-duration-base) var(--wpshelf-ease);--wpshelf-transition-progress:width var(--wpshelf-duration-xslow) var(--wpshelf-ease);--wpshelf-radius-xs:6px;--wpshelf-radius-sm:8px;--wpshelf-radius:10px;--wpshelf-radius-lg:12px;--wpshelf-radius-pill:999px;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.04);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.08);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.12);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.06);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.06);--wpshelf-focus-ring:2px solid var(--wpshelf-accent);--wpshelf-focus-ring-offset:2px;--wpshelf-z-base:1;--wpshelf-z-above:10;--wpshelf-z-sticky:100;--wpshelf-z-modal:100000;--wpshelf-z-toast:100100;--wpshelf-z-tooltip:100200}@supports (color:oklch(50% 0.1 200)){.wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-accent:oklch(0.53 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.46 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-100:oklch(0.73 calc(var(--wpshelf-chroma)*0.9) var(--wpshelf-hue));--wpshelf-accent-50:oklch(0.97 0.012 var(--wpshelf-hue))}}[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{color-scheme:dark;--wpshelf-bg:#0a0a0a;--wpshelf-surface:#111;--wpshelf-surface-alt:#171717;--wpshelf-ink:#ededed;--wpshelf-ink-soft:#a1a1a1;--wpshelf-muted:#8f8f8f;--wpshelf-line:#262626;--wpshelf-line-soft:#1f1f1f;--wpshelf-fill:#ededed;--wpshelf-fill-hover:#c9c9c9;--wpshelf-fill-ink:#0a0a0a;--wpshelf-accent:#4f94d4;--wpshelf-accent-dark:#72aee6;--wpshelf-accent-50:#24313e;--wpshelf-success:#3fb950;--wpshelf-success-dark:#56d364;--wpshelf-success-50:#16241a;--wpshelf-warn:#d29922;--wpshelf-warn-dark:#e3b341;--wpshelf-warn-50:#26200f;--wpshelf-danger:#f85149;--wpshelf-danger-50:#2a1615;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.5);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.6);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.4)}@supports (color:color-mix(in oklab,red,blue)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent-50:color-mix(in oklab,var(--wpshelf-accent) 14%,var(--wpshelf-surface));--wpshelf-success-50:color-mix(in oklab,var(--wpshelf-success) 16%,var(--wpshelf-surface));--wpshelf-warn-50:color-mix(in oklab,var(--wpshelf-warn) 16%,var(--wpshelf-surface));--wpshelf-danger-50:color-mix(in oklab,var(--wpshelf-danger) 16%,var(--wpshelf-surface))}}@supports (color:oklch(50% 0.1 200)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent:oklch(0.68 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.76 var(--wpshelf-chroma) var(--wpshelf-hue))}}[data-g-density=compact],[data-g-density=compact] .wpshelf-app,[data-g-density=compact] .wpshelf-app-wrap,[data-wpshelf-density=compact],[data-wpshelf-density=compact] .wpshelf-app,[data-wpshelf-density=compact] .wpshelf-app-wrap{--wpshelf-control-h:28px;--wpshelf-control-h-sm:22px;--wpshelf-cell-pad-y:5px;--wpshelf-cell-pad-x:12px}.wpshelf-chip{align-items:center;background:var(--wpshelf-line-soft);border:1px solid transparent;border-radius:var(--wpshelf-radius-pill);color:var(--wpshelf-ink-soft);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-medium);gap:6px;padding:2px 9px;text-transform:capitalize;white-space:nowrap}.wpshelf-chip:before{background:currentcolor;border-radius:50%;content:"";flex-shrink:0;height:6px;opacity:.9;width:6px}.wpshelf-chip--success{background:var(--wpshelf-success-50);color:var(--wpshelf-success-dark)}.wpshelf-chip--warn{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn-dark)}.wpshelf-chip--danger,.wpshelf-chip--error{background:var(--wpshelf-danger-50);color:var(--wpshelf-danger)}.wpshelf-chip--info{background:var(--wpshelf-accent-50);color:var(--wpshelf-accent-dark)}.wpshelf-chip--muted{background:var(--wpshelf-line-soft);color:var(--wpshelf-ink-soft)}@supports (color:color-mix(in oklab,red,blue)){.wpshelf-chip{border-color:var(--wpshelf-line)}.wpshelf-chip--success{border-color:color-mix(in oklab,var(--wpshelf-success) 22%,transparent)}.wpshelf-chip--warn{border-color:color-mix(in oklab,var(--wpshelf-warn) 26%,transparent)}.wpshelf-chip--danger,.wpshelf-chip--error{border-color:color-mix(in oklab,var(--wpshelf-danger) 22%,transparent)}.wpshelf-chip--info{border-color:color-mix(in oklab,var(--wpshelf-accent) 22%,transparent)}.wpshelf-chip--muted{border-color:var(--wpshelf-line)}}.wpshelf-status-glossary{display:grid;gap:10px 18px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.wpshelf-status-glossary__item{align-items:center;display:flex;gap:10px}.wpshelf-status-glossary__text{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0} 1 .wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-bg:#fafafa;--wpshelf-surface:#fff;--wpshelf-surface-alt:#f5f5f5;--wpshelf-ink:#0a0a0a;--wpshelf-ink-soft:#525252;--wpshelf-muted:#6b6b6b;--wpshelf-line:#e5e5e5;--wpshelf-line-soft:#f0f0f0;--wpshelf-fill:#0a0a0a;--wpshelf-fill-hover:#333;--wpshelf-fill-ink:#fff;--wpshelf-accent:#2271b1;--wpshelf-accent-dark:#135e96;--wpshelf-accent-50:#f0f6fc;--wpshelf-accent-100:#72aee6;--wpshelf-success:#18794e;--wpshelf-success-dark:#106239;--wpshelf-success-50:#f0f9f4;--wpshelf-warn:#d97706;--wpshelf-warn-dark:#8a5300;--wpshelf-warn-50:#fdf8ec;--wpshelf-danger:#b42318;--wpshelf-danger-50:#fdf3f3;--wpshelf-brand-fill:var(--wpshelf-accent);--wpshelf-hue:247;--wpshelf-chroma:0.10;--wpshelf-control-h:32px;--wpshelf-control-h-sm:26px;--wpshelf-cell-pad-y:10px;--wpshelf-cell-pad-x:14px;--wpshelf-font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;--wpshelf-font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;--wpshelf-text-2xs:10px;--wpshelf-text-xs:11px;--wpshelf-text-sm:12px;--wpshelf-text-base:13px;--wpshelf-text-md:14px;--wpshelf-text-lg:15px;--wpshelf-text-xl:18px;--wpshelf-text-2xl:22px;--wpshelf-text-stat-md:24px;--wpshelf-text-stat-lg:30px;--wpshelf-leading-tight:1.15;--wpshelf-leading-snug:1.4;--wpshelf-leading-normal:1.55;--wpshelf-leading-relaxed:1.65;--wpshelf-weight-normal:400;--wpshelf-weight-medium:500;--wpshelf-weight-semi:600;--wpshelf-weight-bold:700;--wpshelf-tracking-tight:-0.02em;--wpshelf-tracking-normal:0;--wpshelf-tracking-caps:0.04em;--wpshelf-tracking-wide:0.06em;--wpshelf-space-1:4px;--wpshelf-space-2:8px;--wpshelf-space-3:12px;--wpshelf-space-4:16px;--wpshelf-space-5:20px;--wpshelf-space-6:24px;--wpshelf-space-7:28px;--wpshelf-space-8:32px;--wpshelf-space-10:40px;--wpshelf-space-14:56px;--wpshelf-space-16:64px;--wpshelf-sidebar-width:200px;--wpshelf-sidebar-collapsed:48px;--wpshelf-content-max:1280px;--wpshelf-measure:52em;--wpshelf-duration-fast:0.12s;--wpshelf-duration-base:0.15s;--wpshelf-duration-slow:0.20s;--wpshelf-duration-xslow:0.30s;--wpshelf-ease:cubic-bezier(0.4,0,0.2,1);--wpshelf-ease-out:cubic-bezier(0,0,0.2,1);--wpshelf-ease-in:cubic-bezier(0.4,0,1,1);--wpshelf-ease-spring:cubic-bezier(0.32,0.72,0,1);--wpshelf-ease-out-quart:cubic-bezier(0.25,1,0.5,1);--wpshelf-transition-color:color var(--wpshelf-duration-fast) var(--wpshelf-ease),background var(--wpshelf-duration-fast) var(--wpshelf-ease),border-color var(--wpshelf-duration-fast) var(--wpshelf-ease);--wpshelf-transition-lift:transform var(--wpshelf-duration-base) var(--wpshelf-ease),box-shadow var(--wpshelf-duration-base) var(--wpshelf-ease);--wpshelf-transition-progress:width var(--wpshelf-duration-xslow) var(--wpshelf-ease);--wpshelf-radius-xs:6px;--wpshelf-radius-sm:8px;--wpshelf-radius:10px;--wpshelf-radius-lg:12px;--wpshelf-radius-pill:999px;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.04);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.08);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.12);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.06);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.06);--wpshelf-focus-ring:2px solid var(--wpshelf-accent);--wpshelf-focus-ring-offset:2px;--wpshelf-z-base:1;--wpshelf-z-above:10;--wpshelf-z-sticky:100;--wpshelf-z-modal:100000;--wpshelf-z-toast:100100;--wpshelf-z-tooltip:100200}@supports (color:oklch(50% 0.1 200)){.wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-accent:oklch(0.53 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.46 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-100:oklch(0.73 calc(var(--wpshelf-chroma)*0.9) var(--wpshelf-hue));--wpshelf-accent-50:oklch(0.97 0.012 var(--wpshelf-hue))}}[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{color-scheme:dark;--wpshelf-bg:#0a0a0a;--wpshelf-surface:#111;--wpshelf-surface-alt:#171717;--wpshelf-ink:#ededed;--wpshelf-ink-soft:#a1a1a1;--wpshelf-muted:#8f8f8f;--wpshelf-line:#262626;--wpshelf-line-soft:#1f1f1f;--wpshelf-fill:#ededed;--wpshelf-fill-hover:#c9c9c9;--wpshelf-fill-ink:#0a0a0a;--wpshelf-accent:#4f94d4;--wpshelf-accent-dark:#72aee6;--wpshelf-accent-50:#24313e;--wpshelf-success:#3fb950;--wpshelf-success-dark:#56d364;--wpshelf-success-50:#16241a;--wpshelf-warn:#d29922;--wpshelf-warn-dark:#e3b341;--wpshelf-warn-50:#26200f;--wpshelf-danger:#f85149;--wpshelf-danger-50:#2a1615;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.5);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.6);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.4)}@supports (color:color-mix(in oklab,red,blue)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent-50:color-mix(in oklab,var(--wpshelf-accent) 14%,var(--wpshelf-surface));--wpshelf-success-50:color-mix(in oklab,var(--wpshelf-success) 16%,var(--wpshelf-surface));--wpshelf-warn-50:color-mix(in oklab,var(--wpshelf-warn) 16%,var(--wpshelf-surface));--wpshelf-danger-50:color-mix(in oklab,var(--wpshelf-danger) 16%,var(--wpshelf-surface))}}@supports (color:oklch(50% 0.1 200)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent:oklch(0.68 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.76 var(--wpshelf-chroma) var(--wpshelf-hue))}}[data-g-density=compact],[data-g-density=compact] .wpshelf-app,[data-g-density=compact] .wpshelf-app-wrap,[data-wpshelf-density=compact],[data-wpshelf-density=compact] .wpshelf-app,[data-wpshelf-density=compact] .wpshelf-app-wrap{--wpshelf-control-h:28px;--wpshelf-control-h-sm:22px;--wpshelf-cell-pad-y:5px;--wpshelf-cell-pad-x:12px}.wpshelf-chip{align-items:center;background:var(--wpshelf-line-soft);border:1px solid transparent;border-radius:var(--wpshelf-radius-pill);color:var(--wpshelf-ink-soft);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-medium);gap:6px;padding:2px 9px;text-transform:capitalize;white-space:nowrap}.wpshelf-chip:before{background:currentcolor;border-radius:50%;content:"";flex-shrink:0;height:6px;opacity:.9;width:6px}.wpshelf-chip--success{background:var(--wpshelf-success-50);color:var(--wpshelf-success-dark)}.wpshelf-chip--warn{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn-dark)}.wpshelf-chip--danger,.wpshelf-chip--error{background:var(--wpshelf-danger-50);color:var(--wpshelf-danger)}.wpshelf-chip--info{background:var(--wpshelf-accent-50);color:var(--wpshelf-accent-dark)}.wpshelf-chip--muted{background:var(--wpshelf-line-soft);color:var(--wpshelf-ink-soft)}@supports (color:color-mix(in oklab,red,blue)){.wpshelf-chip{border-color:var(--wpshelf-line)}.wpshelf-chip--success{border-color:color-mix(in oklab,var(--wpshelf-success) 22%,transparent)}.wpshelf-chip--warn{border-color:color-mix(in oklab,var(--wpshelf-warn) 26%,transparent)}.wpshelf-chip--danger,.wpshelf-chip--error{border-color:color-mix(in oklab,var(--wpshelf-danger) 22%,transparent)}.wpshelf-chip--info{border-color:color-mix(in oklab,var(--wpshelf-accent) 22%,transparent)}.wpshelf-chip--muted{border-color:var(--wpshelf-line)}}.wpshelf-status-glossary{display:grid;gap:10px 18px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.wpshelf-status-glossary__item{align-items:center;display:flex;gap:10px}.wpshelf-status-glossary__text{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0}.wpshelf-cell--money{color:var(--wpshelf-ink);font-variant-numeric:tabular-nums;text-align:left}.wpshelf-cell--money.is-negative{color:var(--wpshelf-danger)}.wpshelf-cell--money.is-muted{color:var(--wpshelf-muted)}.wpshelf-ledger{display:flex;flex-direction:column;gap:var(--wpshelf-space-2);margin:0}.wpshelf-ledger__row{align-items:baseline;display:flex;gap:var(--wpshelf-space-4);justify-content:space-between;margin:0}.wpshelf-ledger__row dt{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-base);margin:0}.wpshelf-ledger__row dd{margin:0}.wpshelf-ledger__row--sub{padding-right:var(--wpshelf-space-4)}.wpshelf-ledger__row--sub dt{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm)}.wpshelf-ledger__total{border-top:1px solid var(--wpshelf-line);margin-top:var(--wpshelf-space-1);padding-top:var(--wpshelf-space-2)}.wpshelf-ledger__total dd,.wpshelf-ledger__total dt{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-semi)}.wpshelf-ledger__note{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0} 2 2 .wpshelf-editor-sidebar{color:var(--wpshelf-ink);display:flex;flex-direction:column;font-size:var(--wpshelf-text-base);gap:var(--wpshelf-space-4);padding:var(--wpshelf-space-4)}.wpshelf-editor-sidebar__loading{display:flex;justify-content:center;padding:var(--wpshelf-space-5) 0}.wpshelf-editor-sidebar__empty{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-base);line-height:var(--wpshelf-leading-normal);margin:0}.wpshelf-provider-status{background:var(--wpshelf-surface);border:1px solid var(--wpshelf-line);border-radius:var(--wpshelf-radius-sm);display:flex;flex-direction:column;gap:var(--wpshelf-space-2);padding:var(--wpshelf-space-3)}.wpshelf-provider-status__header{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between}.wpshelf-provider-status__name{color:var(--wpshelf-ink);font-size:var(--wpshelf-text-md)}.wpshelf-provider-status__badge{align-items:center;border-radius:var(--wpshelf-radius-pill);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-semi);padding:2px 8px}.wpshelf-provider-status__badge--connected{background:var(--wpshelf-success-50);color:var(--wpshelf-success)}.wpshelf-provider-status__badge--disconnected{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn)}.wpshelf-provider-status__actions{align-items:center;display:flex;gap:var(--wpshelf-space-2)}.wpshelf-language-switcher{display:flex;flex-wrap:wrap;gap:var(--wpshelf-space-1)}.wpshelf-language-switcher__btn{flex:0 0 auto}.wpshelf-language-switcher__btn--active{font-weight:var(--wpshelf-weight-semi)}.wpshelf-language-switcher__code{opacity:.7}.wpshelf-language-switcher__default{color:var(--wpshelf-muted)}.wpshelf-language-switcher__native{color:var(--wpshelf-ink-soft)}.wpshelf-language-switcher__empty{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);margin:0}.wpshelf-translation-row{border-bottom:1px solid var(--wpshelf-line-soft);display:flex;flex-direction:column;gap:2px;padding:var(--wpshelf-space-2) 0;width:100%}.wpshelf-translation-row__original{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-semi);word-break:break-word}.wpshelf-translation-row__translated{color:var(--wpshelf-ink-soft);word-break:break-word}.wpshelf-translation-row__meta{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between;margin-top:var(--wpshelf-space-1)}.wpshelf-inline-editor{background:var(--wpshelf-surface);border:1px solid var(--wpshelf-accent-100);border-radius:var(--wpshelf-radius-sm);display:flex;flex-direction:column;gap:var(--wpshelf-space-2);padding:var(--wpshelf-space-3);width:100%}.wpshelf-inline-editor__original{display:flex;flex-direction:column;gap:2px}.wpshelf-inline-editor__label{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-bold);letter-spacing:var(--wpshelf-tracking-caps);text-transform:uppercase}.wpshelf-inline-editor__text{color:var(--wpshelf-ink-soft);line-height:var(--wpshelf-leading-normal);max-height:7.5em;overflow-y:auto;word-break:break-word}.wpshelf-inline-editor__status{align-items:center;display:flex}.wpshelf-inline-editor__textarea textarea{font-size:var(--wpshelf-text-base);line-height:var(--wpshelf-leading-normal);width:100%}.wpshelf-inline-editor__actions,.wpshelf-pagination{align-items:center;display:flex;gap:var(--wpshelf-space-2)}.wpshelf-pagination{justify-content:space-between;margin-top:var(--wpshelf-space-3)}.wpshelf-pagination__info{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);font-variant-numeric:tabular-nums}.wpshelf-provider-status__result{margin:0}.wpshelf-string-list{width:100%}.wpshelf-string-list--empty{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);padding:var(--wpshelf-space-3) 0}.wpshelf-string-list--empty p{margin:0}.wpshelf-string-list__table{border-collapse:collapse;font-size:var(--wpshelf-text-sm);width:100%}.wpshelf-string-list__table th{border-bottom:1px solid var(--wpshelf-line);color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-semi);letter-spacing:var(--wpshelf-tracking-caps);padding:var(--wpshelf-space-1) var(--wpshelf-space-2);text-align:right;text-transform:uppercase;white-space:nowrap}.wpshelf-string-list__table td{border-bottom:1px solid var(--wpshelf-line-soft);padding:var(--wpshelf-space-2);vertical-align:top;word-break:break-word}.wpshelf-string-list__row:last-child td{border-bottom:none}.wpshelf-string-list__cell-status,.wpshelf-string-list__th-status{white-space:nowrap;width:1%}.wpshelf-string-list__cell-original{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-medium)}.wpshelf-string-list__cell-provider,.wpshelf-string-list__cell-translation{color:var(--wpshelf-ink-soft)}.wpshelf-string-list__th-original,.wpshelf-string-list__th-translation{width:40%}.wpshelf-string-list__cell-provider,.wpshelf-string-list__th-provider{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);white-space:nowrap;width:1%}.wpshelf-string-list__preview{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap}.wpshelf-string-list__pagination{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between;margin-top:var(--wpshelf-space-3)}.wpshelf-string-list__page-info{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);font-variant-numeric:tabular-nums} -
gloty/trunk/build/style-gloty-editor-sidebar.css
r3688478 r3748411 1 .wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-bg:#fafafa;--wpshelf-surface:#fff;--wpshelf-surface-alt:#f5f5f5;--wpshelf-ink:#0a0a0a;--wpshelf-ink-soft:#525252;--wpshelf-muted:#6b6b6b;--wpshelf-line:#e5e5e5;--wpshelf-line-soft:#f0f0f0;--wpshelf-fill:#0a0a0a;--wpshelf-fill-hover:#333;--wpshelf-fill-ink:#fff;--wpshelf-accent:#2271b1;--wpshelf-accent-dark:#135e96;--wpshelf-accent-50:#f0f6fc;--wpshelf-accent-100:#72aee6;--wpshelf-success:#18794e;--wpshelf-success-dark:#106239;--wpshelf-success-50:#f0f9f4;--wpshelf-warn:#d97706;--wpshelf-warn-dark:#8a5300;--wpshelf-warn-50:#fdf8ec;--wpshelf-danger:#b42318;--wpshelf-danger-50:#fdf3f3;--wpshelf-brand-fill:var(--wpshelf-accent);--wpshelf-hue:247;--wpshelf-chroma:0.10;--wpshelf-control-h:32px;--wpshelf-control-h-sm:26px;--wpshelf-cell-pad-y:10px;--wpshelf-cell-pad-x:14px;--wpshelf-font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;--wpshelf-font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;--wpshelf-text-2xs:10px;--wpshelf-text-xs:11px;--wpshelf-text-sm:12px;--wpshelf-text-base:13px;--wpshelf-text-md:14px;--wpshelf-text-lg:15px;--wpshelf-text-xl:18px;--wpshelf-text-2xl:22px;--wpshelf-text-stat-md:24px;--wpshelf-text-stat-lg:30px;--wpshelf-leading-tight:1.15;--wpshelf-leading-snug:1.4;--wpshelf-leading-normal:1.55;--wpshelf-leading-relaxed:1.65;--wpshelf-weight-normal:400;--wpshelf-weight-medium:500;--wpshelf-weight-semi:600;--wpshelf-weight-bold:700;--wpshelf-tracking-tight:-0.02em;--wpshelf-tracking-normal:0;--wpshelf-tracking-caps:0.04em;--wpshelf-tracking-wide:0.06em;--wpshelf-space-1:4px;--wpshelf-space-2:8px;--wpshelf-space-3:12px;--wpshelf-space-4:16px;--wpshelf-space-5:20px;--wpshelf-space-6:24px;--wpshelf-space-7:28px;--wpshelf-space-8:32px;--wpshelf-space-10:40px;--wpshelf-space-14:56px;--wpshelf-space-16:64px;--wpshelf-sidebar-width:200px;--wpshelf-sidebar-collapsed:48px;--wpshelf-content-max:1280px;--wpshelf-measure:52em;--wpshelf-duration-fast:0.12s;--wpshelf-duration-base:0.15s;--wpshelf-duration-slow:0.20s;--wpshelf-duration-xslow:0.30s;--wpshelf-ease:cubic-bezier(0.4,0,0.2,1);--wpshelf-ease-out:cubic-bezier(0,0,0.2,1);--wpshelf-ease-in:cubic-bezier(0.4,0,1,1);--wpshelf-ease-spring:cubic-bezier(0.32,0.72,0,1);--wpshelf-ease-out-quart:cubic-bezier(0.25,1,0.5,1);--wpshelf-transition-color:color var(--wpshelf-duration-fast) var(--wpshelf-ease),background var(--wpshelf-duration-fast) var(--wpshelf-ease),border-color var(--wpshelf-duration-fast) var(--wpshelf-ease);--wpshelf-transition-lift:transform var(--wpshelf-duration-base) var(--wpshelf-ease),box-shadow var(--wpshelf-duration-base) var(--wpshelf-ease);--wpshelf-transition-progress:width var(--wpshelf-duration-xslow) var(--wpshelf-ease);--wpshelf-radius-xs:6px;--wpshelf-radius-sm:8px;--wpshelf-radius:10px;--wpshelf-radius-lg:12px;--wpshelf-radius-pill:999px;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.04);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.08);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.12);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.06);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.06);--wpshelf-focus-ring:2px solid var(--wpshelf-accent);--wpshelf-focus-ring-offset:2px;--wpshelf-z-base:1;--wpshelf-z-above:10;--wpshelf-z-sticky:100;--wpshelf-z-modal:100000;--wpshelf-z-toast:100100;--wpshelf-z-tooltip:100200}@supports (color:oklch(50% 0.1 200)){.wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-accent:oklch(0.53 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.46 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-100:oklch(0.73 calc(var(--wpshelf-chroma)*0.9) var(--wpshelf-hue));--wpshelf-accent-50:oklch(0.97 0.012 var(--wpshelf-hue))}}[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{color-scheme:dark;--wpshelf-bg:#0a0a0a;--wpshelf-surface:#111;--wpshelf-surface-alt:#171717;--wpshelf-ink:#ededed;--wpshelf-ink-soft:#a1a1a1;--wpshelf-muted:#8f8f8f;--wpshelf-line:#262626;--wpshelf-line-soft:#1f1f1f;--wpshelf-fill:#ededed;--wpshelf-fill-hover:#c9c9c9;--wpshelf-fill-ink:#0a0a0a;--wpshelf-accent:#4f94d4;--wpshelf-accent-dark:#72aee6;--wpshelf-accent-50:#24313e;--wpshelf-success:#3fb950;--wpshelf-success-dark:#56d364;--wpshelf-success-50:#16241a;--wpshelf-warn:#d29922;--wpshelf-warn-dark:#e3b341;--wpshelf-warn-50:#26200f;--wpshelf-danger:#f85149;--wpshelf-danger-50:#2a1615;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.5);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.6);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.4)}@supports (color:color-mix(in oklab,red,blue)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent-50:color-mix(in oklab,var(--wpshelf-accent) 14%,var(--wpshelf-surface));--wpshelf-success-50:color-mix(in oklab,var(--wpshelf-success) 16%,var(--wpshelf-surface));--wpshelf-warn-50:color-mix(in oklab,var(--wpshelf-warn) 16%,var(--wpshelf-surface));--wpshelf-danger-50:color-mix(in oklab,var(--wpshelf-danger) 16%,var(--wpshelf-surface))}}@supports (color:oklch(50% 0.1 200)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent:oklch(0.68 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.76 var(--wpshelf-chroma) var(--wpshelf-hue))}}[data-g-density=compact],[data-g-density=compact] .wpshelf-app,[data-g-density=compact] .wpshelf-app-wrap,[data-wpshelf-density=compact],[data-wpshelf-density=compact] .wpshelf-app,[data-wpshelf-density=compact] .wpshelf-app-wrap{--wpshelf-control-h:28px;--wpshelf-control-h-sm:22px;--wpshelf-cell-pad-y:5px;--wpshelf-cell-pad-x:12px}.wpshelf-chip{align-items:center;background:var(--wpshelf-line-soft);border:1px solid transparent;border-radius:var(--wpshelf-radius-pill);color:var(--wpshelf-ink-soft);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-medium);gap:6px;padding:2px 9px;text-transform:capitalize;white-space:nowrap}.wpshelf-chip:before{background:currentcolor;border-radius:50%;content:"";flex-shrink:0;height:6px;opacity:.9;width:6px}.wpshelf-chip--success{background:var(--wpshelf-success-50);color:var(--wpshelf-success-dark)}.wpshelf-chip--warn{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn-dark)}.wpshelf-chip--danger,.wpshelf-chip--error{background:var(--wpshelf-danger-50);color:var(--wpshelf-danger)}.wpshelf-chip--info{background:var(--wpshelf-accent-50);color:var(--wpshelf-accent-dark)}.wpshelf-chip--muted{background:var(--wpshelf-line-soft);color:var(--wpshelf-ink-soft)}@supports (color:color-mix(in oklab,red,blue)){.wpshelf-chip{border-color:var(--wpshelf-line)}.wpshelf-chip--success{border-color:color-mix(in oklab,var(--wpshelf-success) 22%,transparent)}.wpshelf-chip--warn{border-color:color-mix(in oklab,var(--wpshelf-warn) 26%,transparent)}.wpshelf-chip--danger,.wpshelf-chip--error{border-color:color-mix(in oklab,var(--wpshelf-danger) 22%,transparent)}.wpshelf-chip--info{border-color:color-mix(in oklab,var(--wpshelf-accent) 22%,transparent)}.wpshelf-chip--muted{border-color:var(--wpshelf-line)}}.wpshelf-status-glossary{display:grid;gap:10px 18px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.wpshelf-status-glossary__item{align-items:center;display:flex;gap:10px}.wpshelf-status-glossary__text{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0} 1 .wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-bg:#fafafa;--wpshelf-surface:#fff;--wpshelf-surface-alt:#f5f5f5;--wpshelf-ink:#0a0a0a;--wpshelf-ink-soft:#525252;--wpshelf-muted:#6b6b6b;--wpshelf-line:#e5e5e5;--wpshelf-line-soft:#f0f0f0;--wpshelf-fill:#0a0a0a;--wpshelf-fill-hover:#333;--wpshelf-fill-ink:#fff;--wpshelf-accent:#2271b1;--wpshelf-accent-dark:#135e96;--wpshelf-accent-50:#f0f6fc;--wpshelf-accent-100:#72aee6;--wpshelf-success:#18794e;--wpshelf-success-dark:#106239;--wpshelf-success-50:#f0f9f4;--wpshelf-warn:#d97706;--wpshelf-warn-dark:#8a5300;--wpshelf-warn-50:#fdf8ec;--wpshelf-danger:#b42318;--wpshelf-danger-50:#fdf3f3;--wpshelf-brand-fill:var(--wpshelf-accent);--wpshelf-hue:247;--wpshelf-chroma:0.10;--wpshelf-control-h:32px;--wpshelf-control-h-sm:26px;--wpshelf-cell-pad-y:10px;--wpshelf-cell-pad-x:14px;--wpshelf-font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;--wpshelf-font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;--wpshelf-text-2xs:10px;--wpshelf-text-xs:11px;--wpshelf-text-sm:12px;--wpshelf-text-base:13px;--wpshelf-text-md:14px;--wpshelf-text-lg:15px;--wpshelf-text-xl:18px;--wpshelf-text-2xl:22px;--wpshelf-text-stat-md:24px;--wpshelf-text-stat-lg:30px;--wpshelf-leading-tight:1.15;--wpshelf-leading-snug:1.4;--wpshelf-leading-normal:1.55;--wpshelf-leading-relaxed:1.65;--wpshelf-weight-normal:400;--wpshelf-weight-medium:500;--wpshelf-weight-semi:600;--wpshelf-weight-bold:700;--wpshelf-tracking-tight:-0.02em;--wpshelf-tracking-normal:0;--wpshelf-tracking-caps:0.04em;--wpshelf-tracking-wide:0.06em;--wpshelf-space-1:4px;--wpshelf-space-2:8px;--wpshelf-space-3:12px;--wpshelf-space-4:16px;--wpshelf-space-5:20px;--wpshelf-space-6:24px;--wpshelf-space-7:28px;--wpshelf-space-8:32px;--wpshelf-space-10:40px;--wpshelf-space-14:56px;--wpshelf-space-16:64px;--wpshelf-sidebar-width:200px;--wpshelf-sidebar-collapsed:48px;--wpshelf-content-max:1280px;--wpshelf-measure:52em;--wpshelf-duration-fast:0.12s;--wpshelf-duration-base:0.15s;--wpshelf-duration-slow:0.20s;--wpshelf-duration-xslow:0.30s;--wpshelf-ease:cubic-bezier(0.4,0,0.2,1);--wpshelf-ease-out:cubic-bezier(0,0,0.2,1);--wpshelf-ease-in:cubic-bezier(0.4,0,1,1);--wpshelf-ease-spring:cubic-bezier(0.32,0.72,0,1);--wpshelf-ease-out-quart:cubic-bezier(0.25,1,0.5,1);--wpshelf-transition-color:color var(--wpshelf-duration-fast) var(--wpshelf-ease),background var(--wpshelf-duration-fast) var(--wpshelf-ease),border-color var(--wpshelf-duration-fast) var(--wpshelf-ease);--wpshelf-transition-lift:transform var(--wpshelf-duration-base) var(--wpshelf-ease),box-shadow var(--wpshelf-duration-base) var(--wpshelf-ease);--wpshelf-transition-progress:width var(--wpshelf-duration-xslow) var(--wpshelf-ease);--wpshelf-radius-xs:6px;--wpshelf-radius-sm:8px;--wpshelf-radius:10px;--wpshelf-radius-lg:12px;--wpshelf-radius-pill:999px;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.04);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.08);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.12);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.06);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.06);--wpshelf-focus-ring:2px solid var(--wpshelf-accent);--wpshelf-focus-ring-offset:2px;--wpshelf-z-base:1;--wpshelf-z-above:10;--wpshelf-z-sticky:100;--wpshelf-z-modal:100000;--wpshelf-z-toast:100100;--wpshelf-z-tooltip:100200}@supports (color:oklch(50% 0.1 200)){.wpshelf-app,.wpshelf-app-wrap,:root{--wpshelf-accent:oklch(0.53 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.46 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-100:oklch(0.73 calc(var(--wpshelf-chroma)*0.9) var(--wpshelf-hue));--wpshelf-accent-50:oklch(0.97 0.012 var(--wpshelf-hue))}}[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{color-scheme:dark;--wpshelf-bg:#0a0a0a;--wpshelf-surface:#111;--wpshelf-surface-alt:#171717;--wpshelf-ink:#ededed;--wpshelf-ink-soft:#a1a1a1;--wpshelf-muted:#8f8f8f;--wpshelf-line:#262626;--wpshelf-line-soft:#1f1f1f;--wpshelf-fill:#ededed;--wpshelf-fill-hover:#c9c9c9;--wpshelf-fill-ink:#0a0a0a;--wpshelf-accent:#4f94d4;--wpshelf-accent-dark:#72aee6;--wpshelf-accent-50:#24313e;--wpshelf-success:#3fb950;--wpshelf-success-dark:#56d364;--wpshelf-success-50:#16241a;--wpshelf-warn:#d29922;--wpshelf-warn-dark:#e3b341;--wpshelf-warn-50:#26200f;--wpshelf-danger:#f85149;--wpshelf-danger-50:#2a1615;--wpshelf-shadow:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-hover:0 1px 3px rgba(0,0,0,.5);--wpshelf-shadow-overlay:0 8px 24px rgba(0,0,0,.6);--wpshelf-shadow-brand:0 1px 2px rgba(0,0,0,.4);--wpshelf-shadow-mark:0 1px 2px rgba(0,0,0,.4)}@supports (color:color-mix(in oklab,red,blue)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent-50:color-mix(in oklab,var(--wpshelf-accent) 14%,var(--wpshelf-surface));--wpshelf-success-50:color-mix(in oklab,var(--wpshelf-success) 16%,var(--wpshelf-surface));--wpshelf-warn-50:color-mix(in oklab,var(--wpshelf-warn) 16%,var(--wpshelf-surface));--wpshelf-danger-50:color-mix(in oklab,var(--wpshelf-danger) 16%,var(--wpshelf-surface))}}@supports (color:oklch(50% 0.1 200)){[data-g-theme=dark],[data-g-theme=dark] .wpshelf-app,[data-g-theme=dark] .wpshelf-app-wrap,[data-wpshelf-theme=dark],[data-wpshelf-theme=dark] .wpshelf-app,[data-wpshelf-theme=dark] .wpshelf-app-wrap{--wpshelf-accent:oklch(0.68 var(--wpshelf-chroma) var(--wpshelf-hue));--wpshelf-accent-dark:oklch(0.76 var(--wpshelf-chroma) var(--wpshelf-hue))}}[data-g-density=compact],[data-g-density=compact] .wpshelf-app,[data-g-density=compact] .wpshelf-app-wrap,[data-wpshelf-density=compact],[data-wpshelf-density=compact] .wpshelf-app,[data-wpshelf-density=compact] .wpshelf-app-wrap{--wpshelf-control-h:28px;--wpshelf-control-h-sm:22px;--wpshelf-cell-pad-y:5px;--wpshelf-cell-pad-x:12px}.wpshelf-chip{align-items:center;background:var(--wpshelf-line-soft);border:1px solid transparent;border-radius:var(--wpshelf-radius-pill);color:var(--wpshelf-ink-soft);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-medium);gap:6px;padding:2px 9px;text-transform:capitalize;white-space:nowrap}.wpshelf-chip:before{background:currentcolor;border-radius:50%;content:"";flex-shrink:0;height:6px;opacity:.9;width:6px}.wpshelf-chip--success{background:var(--wpshelf-success-50);color:var(--wpshelf-success-dark)}.wpshelf-chip--warn{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn-dark)}.wpshelf-chip--danger,.wpshelf-chip--error{background:var(--wpshelf-danger-50);color:var(--wpshelf-danger)}.wpshelf-chip--info{background:var(--wpshelf-accent-50);color:var(--wpshelf-accent-dark)}.wpshelf-chip--muted{background:var(--wpshelf-line-soft);color:var(--wpshelf-ink-soft)}@supports (color:color-mix(in oklab,red,blue)){.wpshelf-chip{border-color:var(--wpshelf-line)}.wpshelf-chip--success{border-color:color-mix(in oklab,var(--wpshelf-success) 22%,transparent)}.wpshelf-chip--warn{border-color:color-mix(in oklab,var(--wpshelf-warn) 26%,transparent)}.wpshelf-chip--danger,.wpshelf-chip--error{border-color:color-mix(in oklab,var(--wpshelf-danger) 22%,transparent)}.wpshelf-chip--info{border-color:color-mix(in oklab,var(--wpshelf-accent) 22%,transparent)}.wpshelf-chip--muted{border-color:var(--wpshelf-line)}}.wpshelf-status-glossary{display:grid;gap:10px 18px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.wpshelf-status-glossary__item{align-items:center;display:flex;gap:10px}.wpshelf-status-glossary__text{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0}.wpshelf-cell--money{color:var(--wpshelf-ink);font-variant-numeric:tabular-nums;text-align:right}.wpshelf-cell--money.is-negative{color:var(--wpshelf-danger)}.wpshelf-cell--money.is-muted{color:var(--wpshelf-muted)}.wpshelf-ledger{display:flex;flex-direction:column;gap:var(--wpshelf-space-2);margin:0}.wpshelf-ledger__row{align-items:baseline;display:flex;gap:var(--wpshelf-space-4);justify-content:space-between;margin:0}.wpshelf-ledger__row dt{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-base);margin:0}.wpshelf-ledger__row dd{margin:0}.wpshelf-ledger__row--sub{padding-left:var(--wpshelf-space-4)}.wpshelf-ledger__row--sub dt{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm)}.wpshelf-ledger__total{border-top:1px solid var(--wpshelf-line);margin-top:var(--wpshelf-space-1);padding-top:var(--wpshelf-space-2)}.wpshelf-ledger__total dd,.wpshelf-ledger__total dt{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-semi)}.wpshelf-ledger__note{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-sm);margin:0} 2 2 .wpshelf-editor-sidebar{color:var(--wpshelf-ink);display:flex;flex-direction:column;font-size:var(--wpshelf-text-base);gap:var(--wpshelf-space-4);padding:var(--wpshelf-space-4)}.wpshelf-editor-sidebar__loading{display:flex;justify-content:center;padding:var(--wpshelf-space-5) 0}.wpshelf-editor-sidebar__empty{color:var(--wpshelf-ink-soft);font-size:var(--wpshelf-text-base);line-height:var(--wpshelf-leading-normal);margin:0}.wpshelf-provider-status{background:var(--wpshelf-surface);border:1px solid var(--wpshelf-line);border-radius:var(--wpshelf-radius-sm);display:flex;flex-direction:column;gap:var(--wpshelf-space-2);padding:var(--wpshelf-space-3)}.wpshelf-provider-status__header{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between}.wpshelf-provider-status__name{color:var(--wpshelf-ink);font-size:var(--wpshelf-text-md)}.wpshelf-provider-status__badge{align-items:center;border-radius:var(--wpshelf-radius-pill);display:inline-flex;font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-semi);padding:2px 8px}.wpshelf-provider-status__badge--connected{background:var(--wpshelf-success-50);color:var(--wpshelf-success)}.wpshelf-provider-status__badge--disconnected{background:var(--wpshelf-warn-50);color:var(--wpshelf-warn)}.wpshelf-provider-status__actions{align-items:center;display:flex;gap:var(--wpshelf-space-2)}.wpshelf-language-switcher{display:flex;flex-wrap:wrap;gap:var(--wpshelf-space-1)}.wpshelf-language-switcher__btn{flex:0 0 auto}.wpshelf-language-switcher__btn--active{font-weight:var(--wpshelf-weight-semi)}.wpshelf-language-switcher__code{opacity:.7}.wpshelf-language-switcher__default{color:var(--wpshelf-muted)}.wpshelf-language-switcher__native{color:var(--wpshelf-ink-soft)}.wpshelf-language-switcher__empty{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);margin:0}.wpshelf-translation-row{border-bottom:1px solid var(--wpshelf-line-soft);display:flex;flex-direction:column;gap:2px;padding:var(--wpshelf-space-2) 0;width:100%}.wpshelf-translation-row__original{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-semi);word-break:break-word}.wpshelf-translation-row__translated{color:var(--wpshelf-ink-soft);word-break:break-word}.wpshelf-translation-row__meta{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between;margin-top:var(--wpshelf-space-1)}.wpshelf-inline-editor{background:var(--wpshelf-surface);border:1px solid var(--wpshelf-accent-100);border-radius:var(--wpshelf-radius-sm);display:flex;flex-direction:column;gap:var(--wpshelf-space-2);padding:var(--wpshelf-space-3);width:100%}.wpshelf-inline-editor__original{display:flex;flex-direction:column;gap:2px}.wpshelf-inline-editor__label{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-bold);letter-spacing:var(--wpshelf-tracking-caps);text-transform:uppercase}.wpshelf-inline-editor__text{color:var(--wpshelf-ink-soft);line-height:var(--wpshelf-leading-normal);max-height:7.5em;overflow-y:auto;word-break:break-word}.wpshelf-inline-editor__status{align-items:center;display:flex}.wpshelf-inline-editor__textarea textarea{font-size:var(--wpshelf-text-base);line-height:var(--wpshelf-leading-normal);width:100%}.wpshelf-inline-editor__actions,.wpshelf-pagination{align-items:center;display:flex;gap:var(--wpshelf-space-2)}.wpshelf-pagination{justify-content:space-between;margin-top:var(--wpshelf-space-3)}.wpshelf-pagination__info{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);font-variant-numeric:tabular-nums}.wpshelf-provider-status__result{margin:0}.wpshelf-string-list{width:100%}.wpshelf-string-list--empty{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);padding:var(--wpshelf-space-3) 0}.wpshelf-string-list--empty p{margin:0}.wpshelf-string-list__table{border-collapse:collapse;font-size:var(--wpshelf-text-sm);width:100%}.wpshelf-string-list__table th{border-bottom:1px solid var(--wpshelf-line);color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);font-weight:var(--wpshelf-weight-semi);letter-spacing:var(--wpshelf-tracking-caps);padding:var(--wpshelf-space-1) var(--wpshelf-space-2);text-align:left;text-transform:uppercase;white-space:nowrap}.wpshelf-string-list__table td{border-bottom:1px solid var(--wpshelf-line-soft);padding:var(--wpshelf-space-2);vertical-align:top;word-break:break-word}.wpshelf-string-list__row:last-child td{border-bottom:none}.wpshelf-string-list__cell-status,.wpshelf-string-list__th-status{white-space:nowrap;width:1%}.wpshelf-string-list__cell-original{color:var(--wpshelf-ink);font-weight:var(--wpshelf-weight-medium)}.wpshelf-string-list__cell-provider,.wpshelf-string-list__cell-translation{color:var(--wpshelf-ink-soft)}.wpshelf-string-list__th-original,.wpshelf-string-list__th-translation{width:40%}.wpshelf-string-list__cell-provider,.wpshelf-string-list__th-provider{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-xs);white-space:nowrap;width:1%}.wpshelf-string-list__preview{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap}.wpshelf-string-list__pagination{align-items:center;display:flex;gap:var(--wpshelf-space-2);justify-content:space-between;margin-top:var(--wpshelf-space-3)}.wpshelf-string-list__page-info{color:var(--wpshelf-muted);font-size:var(--wpshelf-text-sm);font-variant-numeric:tabular-nums} -
gloty/trunk/composer.lock
r3723660 r3748411 9 9 { 10 10 "name": "wp-shelf/html-parser", 11 "version": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",11 "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 12 12 "dist": { 13 13 "type": "path", … … 46 46 { 47 47 "name": "wp-shelf/platform", 48 "version": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",48 "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 49 49 "dist": { 50 50 "type": "path", -
gloty/trunk/gloty.php
r3723660 r3748411 4 4 * Plugin URI: https://wp-shelf.com/gloty 5 5 * Description: AI translation for WordPress in 38 languages. Every translation is stored in your own database and served locally — no API call at render time. 6 * Version: 1.6 3.36 * Version: 1.64.0 7 7 * Author: WP Shelf 8 8 * Author URI: https://wp-shelf.com … … 61 61 * Plugin constants. 62 62 */ 63 define( 'GLOTY_VERSION', '1.6 3.3' );63 define( 'GLOTY_VERSION', '1.64.0' ); 64 64 define( 'GLOTY_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 65 65 define( 'GLOTY_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); -
gloty/trunk/includes/API/class-admin-rest-routes.php
r3723648 r3748411 1949 1949 if ( null === $status ) { 1950 1950 return new WP_REST_Response( [ 1951 'ok' => true, 1952 'has_key' => LicenseClient::has_key(), 1953 'key_masked' => LicenseClient::get_masked_license_key(), 1954 'status' => null, 1951 'ok' => true, 1952 'has_key' => LicenseClient::has_key(), 1953 'key_masked' => LicenseClient::get_masked_license_key(), 1954 'status' => null, 1955 // Null is either an outage or a key the service no 1956 // longer accepts (rotated, or the licence is gone); 1957 // the panel words the two differently. 1958 'key_refused' => LicenseClient::has_key() && LicenseClient::is_key_refused(), 1955 1959 ] ); 1956 1960 } 1957 1961 return new WP_REST_Response( [ 1958 'ok' => true, 1959 'has_key' => true, 1960 'key_masked' => LicenseClient::get_masked_license_key(), 1961 'status' => $status->to_array(), 1962 'ok' => true, 1963 'has_key' => true, 1964 'key_masked' => LicenseClient::get_masked_license_key(), 1965 'status' => $status->to_array(), 1966 'key_refused' => false, 1962 1967 ] ); 1963 1968 }, -
gloty/trunk/includes/Admin/class-admin-boot-data.php
r3692917 r3748411 249 249 'serverUrl' => $server_url, 250 250 'status' => $status?->to_array(), 251 // Only meaningful when status is null: the service answered and no 252 // longer accepts the key, as opposed to not answering at all. 253 'keyRefused' => null === $status && LicenseClient::is_key_refused(), 251 254 ]; 252 255 } -
gloty/trunk/includes/Admin/class-issues-service.php
r3723648 r3748411 179 179 180 180 $status = LicenseClient::check(); 181 182 /* 183 * Answered, and refused — not unreachable. An operator rotated the key, 184 * or the licence it belonged to is gone; the service answers both as it 185 * answers a mistyped key, deliberately, so this cannot say which and 186 * does not suggest the key was misused. Read after check(), which is 187 * what records a refusal it has just heard. Before this, the same state 188 * reported "will resolve automatically", which it never would. 189 */ 190 if ( null === $status && LicenseClient::is_key_refused() ) { 191 return [ 192 [ 193 'id' => 'license-refused', 194 'severity' => 'error', 195 'title' => __( 'License key no longer accepted', 'gloty' ), 196 'detail' => __( 197 'The licensing service no longer accepts the license key saved on this site. Translations keep running, but usage is not recorded against your plan. If you were sent a replacement key, or can see one in your WP Shelf account, enter it under Billing.', 198 'gloty' 199 ), 200 'action' => [ 201 'label' => __( 'Enter the new key', 'gloty' ), 202 'view' => 'billing', 203 ], 204 ], 205 ]; 206 } 207 181 208 if ( null === $status ) { 182 209 return [ -
gloty/trunk/includes/Licensing/class-license-client.php
r3635518 r3748411 21 21 22 22 use WpShelf\Platform\LicenseClient as PlatformLicenseClient; 23 use WpShelf\Platform\LicenseRefusal; 23 24 use WpShelf\Platform\ProductConfig; 24 25 … … 39 40 */ 40 41 private const DEFAULT_SERVER_URL = 'https://gloty-api.wp-shelf.com'; 42 43 /** 44 * Where a customer signed in to wp-shelf.com sees every licence key they 45 * hold — including a replacement an operator rotated in, which is how the 46 * licence-key rotation runbook delivers one. 47 */ 48 public const ACCOUNT_LICENSES_URL = 'https://wp-shelf.com/dashboard/licenses'; 41 49 42 50 private static ?PlatformLicenseClient $client = null; … … 109 117 */ 110 118 public static function activate( string $key, string $server_url = '' ): array { 111 return self::client()->activate( $key, $server_url ); 119 $response = self::client()->activate( $key, $server_url ); 120 121 // Also cleared inside the shared client, but only by a copy new enough 122 // to know about refusals — and the copy that runs is whichever sibling's 123 // autoloader won. Clearing here holds whichever one that is. 124 if ( ! empty( $response['ok'] ) ) { 125 LicenseRefusal::clear( self::client()->config() ); 126 } 127 128 return $response; 112 129 } 113 130 … … 118 135 */ 119 136 public static function deactivate(): array { 120 return self::client()->deactivate(); 137 $response = self::client()->deactivate(); 138 LicenseRefusal::clear( self::client()->config() ); 139 140 return $response; 141 } 142 143 /** 144 * Whether the licensing service has stopped accepting the key this site holds. 145 * 146 * True after an operator rotated a disclosed key, or the licence the key 147 * belonged to no longer exists. The service answers both exactly as it 148 * answers a mistyped key — on purpose, so a leaked key cannot be confirmed 149 * — which is why this cannot say which. It is not an outage: an 150 * unreachable service never sets it. 151 * 152 * Translation keeps running meanwhile (it authenticates with the site 153 * token), but usage stops being recorded against the plan, so this is 154 * worth an issue rather than a footnote. 155 * 156 * Reads one option; never calls the service. The refusal is recorded by 157 * the shared status check — the daily forced one included. 158 */ 159 public static function is_key_refused(): bool { 160 return LicenseRefusal::is_refused( self::client()->config(), self::get_license_key() ); 121 161 } 122 162 -
gloty/trunk/languages/gloty.pot
r3723648 r3748411 196 196 msgstr "" 197 197 198 #: includes/API/class-admin-rest-routes.php:211 3199 #: includes/API/class-admin-rest-routes.php:215 0198 #: includes/API/class-admin-rest-routes.php:2118 199 #: includes/API/class-admin-rest-routes.php:2155 200 200 msgid "Email and name are required." 201 201 msgstr "" 202 202 203 #: includes/API/class-admin-rest-routes.php:220 0203 #: includes/API/class-admin-rest-routes.php:2205 204 204 msgid "Could not create your license." 205 205 msgstr "" 206 206 207 #: includes/API/class-admin-rest-routes.php:22 17207 #: includes/API/class-admin-rest-routes.php:2222 208 208 msgid "Could not register this site with the translator service." 209 209 msgstr "" … … 358 358 msgstr "" 359 359 360 #: includes/Admin/class-issues-service.php:186 360 #: includes/Admin/class-issues-service.php:195 361 msgid "License key no longer accepted" 362 msgstr "" 363 364 #: includes/Admin/class-issues-service.php:196 365 msgid "The licensing service no longer accepts the license key saved on this site. Translations keep running, but usage is not recorded against your plan. If you were sent a replacement key, or can see one in your WP Shelf account, enter it under Billing." 366 msgstr "" 367 368 #: includes/Admin/class-issues-service.php:201 369 msgid "Enter the new key" 370 msgstr "" 371 372 #: includes/Admin/class-issues-service.php:213 361 373 msgid "License server is unreachable" 362 374 msgstr "" 363 375 364 #: includes/Admin/class-issues-service.php: 187376 #: includes/Admin/class-issues-service.php:214 365 377 msgid "We could not check your plan status. Translations still work; this will resolve automatically when the server is reachable." 366 378 msgstr "" 367 379 368 #: includes/Admin/class-issues-service.php:2 02380 #: includes/Admin/class-issues-service.php:229 369 381 msgid "Character quota exceeded" 370 382 msgstr "" 371 383 372 384 #. translators: 1: characters used, 2: character limit 373 #: includes/Admin/class-issues-service.php:2 05385 #: includes/Admin/class-issues-service.php:232 374 386 msgid "Used %1$s of %2$s characters. Dispatching is blocked until you upgrade or the period resets." 375 387 msgstr "" 376 388 377 #: includes/Admin/class-issues-service.php:2 10378 #: includes/Admin/class-issues-service.php:2 35389 #: includes/Admin/class-issues-service.php:237 390 #: includes/Admin/class-issues-service.php:262 379 391 msgid "Upgrade plan" 380 392 msgstr "" 381 393 382 394 #. translators: %d: percentage used 383 #: includes/Admin/class-issues-service.php:2 25395 #: includes/Admin/class-issues-service.php:252 384 396 msgid "Character quota at %d%%" 385 397 msgstr "" 386 398 387 399 #. translators: 1: characters used, 2: character limit 388 #: includes/Admin/class-issues-service.php:2 30400 #: includes/Admin/class-issues-service.php:257 389 401 msgid "Used %1$s of %2$s characters this billing period." 390 402 msgstr "" 391 403 392 #: includes/Admin/class-issues-service.php:2 45404 #: includes/Admin/class-issues-service.php:272 393 405 msgid "License expired" 394 406 msgstr "" 395 407 396 #: includes/Admin/class-issues-service.php:2 46408 #: includes/Admin/class-issues-service.php:273 397 409 msgid "Your subscription has expired. Renew to resume translation dispatch." 398 410 msgstr "" 399 411 400 #: includes/Admin/class-issues-service.php:2 51412 #: includes/Admin/class-issues-service.php:278 401 413 msgid "Manage billing" 402 414 msgstr "" 403 415 404 416 #. translators: %d: days remaining in the billing period 405 #: includes/Admin/class-issues-service.php:2 65417 #: includes/Admin/class-issues-service.php:292 406 418 msgid "Billing period resets in %d day" 407 419 msgid_plural "Billing period resets in %d days" … … 409 421 msgstr[1] "" 410 422 411 #: includes/Admin/class-issues-service.php: 273423 #: includes/Admin/class-issues-service.php:300 412 424 msgid "Usage will roll over automatically. No action required." 413 425 msgstr "" 414 426 415 #: includes/Admin/class-issues-service.php:3 21427 #: includes/Admin/class-issues-service.php:348 416 428 msgid "These translations are identical to the original text, and are not product names, codes, or text already written in that language. That usually means the translation service returned the source instead of a translation. They are stored as complete, so they will keep serving untranslated until they are translated again. Open the list to see exactly which rows this is counting before you remove any of them." 417 429 msgstr "" 418 430 419 431 #. translators: %s: comma-separated list of language codes with counts, e.g. "de (1,204), sl (980)" 420 #: includes/Admin/class-issues-service.php:3 29432 #: includes/Admin/class-issues-service.php:356 421 433 msgid "Most affected: %s." 422 434 msgstr "" 423 435 424 436 #. translators: %s: number of translations identical to their source 425 #: includes/Admin/class-issues-service.php:3 40437 #: includes/Admin/class-issues-service.php:367 426 438 msgid "%s translation is identical to its source" 427 439 msgid_plural "%s translations are identical to their source" … … 429 441 msgstr[1] "" 430 442 431 #: includes/Admin/class-issues-service.php:3 60443 #: includes/Admin/class-issues-service.php:387 432 444 msgid "Show these rows" 433 445 msgstr "" 434 446 435 #: includes/Admin/class-issues-service.php: 399447 #: includes/Admin/class-issues-service.php:426 436 448 msgid "Translated pages are not using the fast path" 437 449 msgstr "" 438 450 439 #: includes/Admin/class-issues-service.php:4 13451 #: includes/Admin/class-issues-service.php:440 440 452 msgid "Your translations are still served correctly, from the database, exactly as they were before this feature existed — pages are just not as fast as they could be." 441 453 msgstr "" 442 454 443 #: includes/Admin/class-issues-service.php:4 17455 #: includes/Admin/class-issues-service.php:444 444 456 msgid "Gloty speeds up translated pages by compiling your translations into a file your server keeps in memory, and your server's PHP OPcache has no free memory left to hold it. Writing the file anyway would make pages slower rather than faster, so Gloty did not. Ask your host to raise the PHP setting `opcache.memory_consumption` — on cPanel it is under MultiPHP INI Editor." 445 457 msgstr "" 446 458 447 #: includes/Admin/class-issues-service.php:4 20459 #: includes/Admin/class-issues-service.php:447 448 460 msgid "Your translation set compiles to a file larger than your server's `opcache.max_file_size` limit, so your server would refuse to keep it in memory. Ask your host to raise that setting." 449 461 msgstr "" 450 462 451 #: includes/Admin/class-issues-service.php:4 23463 #: includes/Admin/class-issues-service.php:450 452 464 msgid "Your translation set compiles to a file larger than the configured limit. Raise it with the `gloty_compiled_map_max_bytes` filter if your server has memory to spare." 453 465 msgstr "" 454 466 455 #: includes/Admin/class-issues-service.php:4 27467 #: includes/Admin/class-issues-service.php:454 456 468 msgid "Gloty could not write its translation cache file. This usually means the uploads directory is not writable by WordPress." 457 469 msgstr "" 458 470 459 #: includes/Admin/class-issues-service.php:4 30471 #: includes/Admin/class-issues-service.php:457 460 472 msgid "Writing the translation cache failed recently, so Gloty has paused trying for an hour. This usually means the uploads directory is not writable by WordPress." 461 473 msgstr "" 462 474 463 #: includes/Admin/class-issues-service.php:4 33475 #: includes/Admin/class-issues-service.php:460 464 476 msgid "Your server does not have PHP OPcache enabled, so Gloty cannot use its fastest path for serving translations. Ask your host whether OPcache can be turned on." 465 477 msgstr "" 466 478 467 479 #. translators: %d: number of stuck jobs 468 #: includes/Admin/class-issues-service.php:4 69480 #: includes/Admin/class-issues-service.php:496 469 481 msgid "%d job stuck processing" 470 482 msgid_plural "%d jobs stuck processing" … … 472 484 msgstr[1] "" 473 485 474 #: includes/Admin/class-issues-service.php: 477486 #: includes/Admin/class-issues-service.php:504 475 487 msgid "These jobs have been in the processing state for more than 10 minutes. They may be waiting on a webhook that never arrived." 476 488 msgstr "" 477 489 478 #: includes/Admin/class-issues-service.php: 482490 #: includes/Admin/class-issues-service.php:509 479 491 msgid "View jobs" 480 492 msgstr "" 481 493 482 494 #. translators: %d: number of failed jobs 483 #: includes/Admin/class-issues-service.php: 494495 #: includes/Admin/class-issues-service.php:521 484 496 msgid "%d job failed in the last 24 hours" 485 497 msgid_plural "%d jobs failed in the last 24 hours" … … 487 499 msgstr[1] "" 488 500 489 #: includes/Admin/class-issues-service.php:5 02501 #: includes/Admin/class-issues-service.php:529 490 502 msgid "Check the sync events log to see why these jobs failed, and retry them when the root cause is fixed." 491 503 msgstr "" 492 504 493 #: includes/Admin/class-issues-service.php:5 07494 #: includes/Admin/class-issues-service.php:5 29505 #: includes/Admin/class-issues-service.php:534 506 #: includes/Admin/class-issues-service.php:556 495 507 msgid "Open sync screen" 496 508 msgstr "" 497 509 498 #: includes/Admin/class-issues-service.php:5 23510 #: includes/Admin/class-issues-service.php:550 499 511 msgid "Automatic translation is delayed" 500 512 msgstr "" 501 513 502 #: includes/Admin/class-issues-service.php:5 24514 #: includes/Admin/class-issues-service.php:551 503 515 msgid "WordPress cron has not run recently, so scans and translations only progress when you trigger them. On low-traffic sites this is expected — set up a real server cron for wp-cron.php for hands-off processing, or use “Scan” / “Translate now”." 504 516 msgstr "" … … 868 880 869 881 #: src/admin/App.js:422 870 #: src/admin/LicensePanel.js:4 53882 #: src/admin/LicensePanel.js:464 871 883 msgid "License key" 872 884 msgstr "" … … 1172 1184 #: src/admin/App.js:1761 1173 1185 #: src/admin/DesignSystemScreen.js:518 1174 #: src/admin/LicensePanel.js:4 681186 #: src/admin/LicensePanel.js:479 1175 1187 #: src/admin/SyncScreen.js:480 1176 1188 #: src/admin/SyncScreen.js:938 … … 1734 1746 #: src/admin/DesignSystemScreen.js:146 1735 1747 #: src/admin/HealthPill.js:24 1736 #: src/admin/LicensePanel.js: 5911748 #: src/admin/LicensePanel.js:602 1737 1749 msgid "Checking…" 1738 1750 msgstr "" … … 2315 2327 msgstr "" 2316 2328 2317 #: src/admin/LicensePanel.js:1 792329 #: src/admin/LicensePanel.js:188 2318 2330 msgid "License provisioned and activated." 2319 2331 msgstr "" 2320 2332 2321 #: src/admin/LicensePanel.js:1 862322 #: src/admin/LicensePanel.js: 1922333 #: src/admin/LicensePanel.js:195 2334 #: src/admin/LicensePanel.js:201 2323 2335 msgid "Provisioning failed." 2324 2336 msgstr "" 2325 2337 2326 #: src/admin/LicensePanel.js:2 182338 #: src/admin/LicensePanel.js:228 2327 2339 msgid "License activated." 2328 2340 msgstr "" 2329 2341 2330 #: src/admin/LicensePanel.js:2 242331 #: src/admin/LicensePanel.js:2 302342 #: src/admin/LicensePanel.js:234 2343 #: src/admin/LicensePanel.js:240 2332 2344 msgid "Activation failed." 2333 2345 msgstr "" 2334 2346 2335 #: src/admin/LicensePanel.js:2 492347 #: src/admin/LicensePanel.js:260 2336 2348 msgid "License deactivated." 2337 2349 msgstr "" 2338 2350 2339 #: src/admin/LicensePanel.js:2 542351 #: src/admin/LicensePanel.js:265 2340 2352 msgid "Deactivation failed." 2341 2353 msgstr "" 2342 2354 2343 #: src/admin/LicensePanel.js: 2962355 #: src/admin/LicensePanel.js:307 2344 2356 msgid "No billing portal is available for this license — there’s no Stripe subscription to manage. This is normal for free or manually-granted plans." 2345 2357 msgstr "" 2346 2358 2347 #: src/admin/LicensePanel.js:3 052359 #: src/admin/LicensePanel.js:316 2348 2360 msgid "Could not open the billing portal." 2349 2361 msgstr "" 2350 2362 2351 #: src/admin/LicensePanel.js:3 332363 #: src/admin/LicensePanel.js:344 2352 2364 msgid "License" 2353 2365 msgstr "" 2354 2366 2355 #: src/admin/LicensePanel.js:3 522367 #: src/admin/LicensePanel.js:363 2356 2368 msgid "Get started with Gloty translation credits, or enter an existing license key." 2357 2369 msgstr "" 2358 2370 2359 #: src/admin/LicensePanel.js:3 752371 #: src/admin/LicensePanel.js:386 2360 2372 msgid "Get Started" 2361 2373 msgstr "" 2362 2374 2363 #: src/admin/LicensePanel.js:3 862375 #: src/admin/LicensePanel.js:397 2364 2376 msgid "I have a license key" 2365 2377 msgstr "" 2366 2378 2367 #: src/admin/LicensePanel.js: 3942379 #: src/admin/LicensePanel.js:405 2368 2380 msgid "Email" 2369 2381 msgstr "" 2370 2382 2371 #: src/admin/LicensePanel.js:4 032383 #: src/admin/LicensePanel.js:414 2372 2384 msgid "Name" 2373 2385 msgstr "" 2374 2386 2375 #: src/admin/LicensePanel.js:4 192387 #: src/admin/LicensePanel.js:430 2376 2388 msgid "Get Free License" 2377 2389 msgstr "" 2378 2390 2379 #: src/admin/LicensePanel.js:4 282391 #: src/admin/LicensePanel.js:439 2380 2392 msgid "License Key" 2381 2393 msgstr "" 2382 2394 2383 #: src/admin/LicensePanel.js:441 2395 #: src/admin/LicensePanel.js:452 2396 #: src/admin/LicensePanel.js:691 2384 2397 msgid "Activate" 2385 2398 msgstr "" 2386 2399 2387 #: src/admin/LicensePanel.js:4 622400 #: src/admin/LicensePanel.js:473 2388 2401 msgid "Plan" 2389 2402 msgstr "" 2390 2403 2391 #: src/admin/LicensePanel.js:4 742404 #: src/admin/LicensePanel.js:485 2392 2405 msgid "Sites" 2393 2406 msgstr "" 2394 2407 2395 #: src/admin/LicensePanel.js:4 822408 #: src/admin/LicensePanel.js:493 2396 2409 msgid "Usage" 2397 2410 msgstr "" 2398 2411 2399 #: src/admin/LicensePanel.js: 4942412 #: src/admin/LicensePanel.js:505 2400 2413 msgid "You’re approaching your monthly limit. Translation pauses at 100% until the limit resets or you upgrade — existing translations keep serving." 2401 2414 msgstr "" 2402 2415 2403 #: src/admin/LicensePanel.js: 4982416 #: src/admin/LicensePanel.js:509 2404 2417 msgid "Translation pauses when you reach your monthly limit, then resumes after it resets or you upgrade. Already-stored translations always keep serving." 2405 2418 msgstr "" 2406 2419 2407 #: src/admin/LicensePanel.js:5 072420 #: src/admin/LicensePanel.js:518 2408 2421 msgid "Resets" 2409 2422 msgstr "" 2410 2423 2411 #: src/admin/LicensePanel.js:5 202412 #: src/admin/LicensePanel.js:5 572424 #: src/admin/LicensePanel.js:531 2425 #: src/admin/LicensePanel.js:568 2413 2426 msgid "Upgrade" 2414 2427 msgstr "" 2415 2428 2416 #: src/admin/LicensePanel.js:5 372429 #: src/admin/LicensePanel.js:548 2417 2430 msgid "1 site" 2418 2431 msgstr "" 2419 2432 2420 2433 #. translators: %d: number of sites 2421 #: src/admin/LicensePanel.js:5 402434 #: src/admin/LicensePanel.js:551 2422 2435 msgid "Up to %d sites" 2423 2436 msgstr "" 2424 2437 2425 #: src/admin/LicensePanel.js:5 582438 #: src/admin/LicensePanel.js:569 2426 2439 msgid "Buy" 2427 2440 msgstr "" 2428 2441 2429 #: src/admin/LicensePanel.js:5 802442 #: src/admin/LicensePanel.js:591 2430 2443 msgid "Manage Subscription" 2431 2444 msgstr "" 2432 2445 2433 #: src/admin/LicensePanel.js: 5922446 #: src/admin/LicensePanel.js:603 2434 2447 msgid "Refresh status" 2435 2448 msgstr "" 2436 2449 2437 #: src/admin/LicensePanel.js:6 002438 #: src/admin/LicensePanel.js:6 192450 #: src/admin/LicensePanel.js:611 2451 #: src/admin/LicensePanel.js:630 2439 2452 msgid "Deactivate" 2440 2453 msgstr "" 2441 2454 2442 #: src/admin/LicensePanel.js:6 042455 #: src/admin/LicensePanel.js:615 2443 2456 msgid "Deactivating frees this license for another site. Your translations stay in place — nothing is deleted." 2444 2457 msgstr "" 2445 2458 2446 #: src/admin/LicensePanel.js:6 142459 #: src/admin/LicensePanel.js:625 2447 2460 msgid "Deactivate license on this site?" 2448 2461 msgstr "" 2449 2462 2450 #: src/admin/LicensePanel.js:6 152463 #: src/admin/LicensePanel.js:626 2451 2464 msgid "This frees the license seat for use on another site. Your stored translations stay in place and keep serving, but new translations stop until you reactivate. Nothing is deleted." 2452 2465 msgstr "" 2453 2466 2454 #: src/admin/LicensePanel.js:639 2467 #: src/admin/LicensePanel.js:656 2468 msgid "This license key is no longer accepted." 2469 msgstr "" 2470 2471 #: src/admin/LicensePanel.js:663 2472 msgid "Translations keep running, but usage is not recorded against your plan. If you were sent a replacement key, or can see one in your WP Shelf account, paste it here and activate it." 2473 msgstr "" 2474 2475 #: src/admin/LicensePanel.js:672 2476 msgid "Open your WP Shelf licenses" 2477 msgstr "" 2478 2479 #: src/admin/LicensePanel.js:678 2480 msgid "Replacement license key" 2481 msgstr "" 2482 2483 #: src/admin/LicensePanel.js:706 2455 2484 msgid "License key is configured but the license server could not be reached." 2456 2485 msgstr "" 2457 2486 2458 #: src/admin/LicensePanel.js: 6522487 #: src/admin/LicensePanel.js:719 2459 2488 msgid "Retrying…" 2460 2489 msgstr "" 2461 2490 2462 #: src/admin/LicensePanel.js: 6532491 #: src/admin/LicensePanel.js:720 2463 2492 #: src/admin/SyncScreen.js:991 2464 2493 msgid "Retry" … … 3483 3512 #. translators: %s: a number of views. 3484 3513 #: src/admin/TrendChart.js:340 3514 msgctxt "tooltip readout" 3485 3515 msgid "%s views" 3486 3516 msgstr "" -
gloty/trunk/package.json
r3723660 r3748411 1 1 { 2 2 "name": "@wp-shelf/gloty", 3 "version": "1.6 3.3",3 "version": "1.64.0", 4 4 "description": "Gloty - AI-powered translation plugin for WordPress.", 5 5 "private": true, -
gloty/trunk/readme.txt
r3723660 r3748411 5 5 Tested up to: 7.1 6 6 Requires PHP: 8.1 7 Stable tag: 1.6 3.37 Stable tag: 1.64.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 196 196 == Changelog == 197 197 198 = 1.64.0 = 199 * New: if your license key stops being accepted — for example because we replaced it at your request — Gloty says so in Needs attention and on the license card, with a field for the replacement key that reconnects this site without using another site slot. Before, it reported that the licensing service could not be reached and offered only Retry. Translations keep being served while you replace the key. 200 * Changed: on a site running several WP Shelf plugins, the newest version of the shared admin styles is used, whichever plugin was installed or updated last. Before, updating an older WP Shelf plugin could make every WP Shelf screen fall back to its older styles. 201 198 202 = 1.63.3 = 199 203 * Fixed: a translation that came back with part of Gloty's own request stuck to its end — text such as `','kind':'heading` or `','kind':'seo_title','doc':'post:1807` after the translated words — is no longer stored or shown. It is a stray piece of the translation service's instructions, not part of the translation, and it appeared in headings, menu labels, SEO titles and image captions. Gloty now refuses it and asks for that piece of text again, and no longer copies an affected entry onto other pages with the same text. Ordinary text that merely contains the word "kind" or apostrophes is unaffected. A refusal is written to the audit log with the value that was rejected. This fix first shipped as 1.61.1 to a single site and had not reached the 1.62 and 1.63 releases. -
gloty/trunk/shared-js/design-system/src/components.css
r3723648 r3748411 313 313 } 314 314 315 /* Sentence case. A column header is a label, not an abbreviation. */ 316 .wpshelf-table th { 315 /* Sentence case. A column header is a label, not an abbreviation. 316 One header whether or not the table also carries WordPress's 317 `wp-list-table widefat` classes (TASK-112): every property core sets on a 318 `.widefat` header is set here, at (0,1,4) — above core's 319 `.widefat th:not(tbody th)` at (0,1,3). Mirrored in 320 shared/php/platform/assets/admin.css, which also names the 321 `.wpshelf-app .wp-list-table th` it shares this rule with. */ 322 table.wpshelf-table > thead > tr > th { 323 padding: var(--wpshelf-cell-pad-y) var(--wpshelf-cell-pad-x); 324 border-bottom: 1px solid var(--wpshelf-line); 325 background: var(--wpshelf-surface-alt); 326 color: var(--wpshelf-muted); 317 327 font-size: var(--wpshelf-text-sm); 318 328 font-weight: var(--wpshelf-weight-medium); 319 color: var(--wpshelf-muted); 329 line-height: var(--wpshelf-leading-snug); 330 overflow-wrap: break-word; 331 text-align: start; 320 332 } 321 333 … … 384 396 } 385 397 398 /* A column's alignment reaches its header, above the header default. */ 399 .wpshelf-table th.wpshelf-cell--left { 400 text-align: left; 401 } 402 403 .wpshelf-table th.wpshelf-cell--right { 404 text-align: right; 405 } 406 407 .wpshelf-table th.wpshelf-cell--center { 408 text-align: center; 409 } 410 386 411 /* Declared even though it is the default: a column may state `align: 'left'` 387 412 explicitly, and a class that renders with no rule behind it is the failure -
gloty/trunk/shared-js/design-system/src/interactive-table.js
r3688478 r3748411 14 14 } from '@wordpress/element'; 15 15 import { FilterBar, TablePager } from './data-table'; 16 17 // Built once: `localeCompare` with options builds a collator per comparison, 18 // and a sort over a few thousand rows makes tens of thousands of them. 19 const collator = new Intl.Collator(undefined, { 20 numeric: true, 21 sensitivity: 'base', 22 }); 16 23 17 24 export function tableText(node) { … … 109 116 matching.sort( 110 117 (a, b) => 111 tableText( 112 Children.toArray(a.props.children)[sort.column] 113 ).localeCompare( 114 tableText(Children.toArray(b.props.children)[sort.column]), 115 undefined, 116 { numeric: true, sensitivity: 'base' } 118 collator.compare( 119 tableText(Children.toArray(a.props.children)[sort.column]), 120 tableText(Children.toArray(b.props.children)[sort.column]) 117 121 ) * sort.direction 118 122 ); -
gloty/trunk/shared-js/design-system/src/style.css
r3688478 r3748411 97 97 color: var(--wpshelf-ink-soft); 98 98 } 99 100 /* ================================================================ 101 Money cell and ledger — amounts in tables, and a label/value breakdown 102 with a ruled total. Promoted upstream so a PHP screen and a React screen 103 render the same money the same way. Mirrored in 104 shared/php/platform/assets/admin.css (AdminStyleTokenParityTest). 105 ================================================================ */ 106 107 .wpshelf-cell--money { 108 text-align: right; 109 font-variant-numeric: tabular-nums; 110 color: var(--wpshelf-ink); 111 } 112 113 .wpshelf-cell--money.is-negative { 114 color: var(--wpshelf-danger); 115 } 116 117 .wpshelf-cell--money.is-muted { 118 color: var(--wpshelf-muted); 119 } 120 121 .wpshelf-ledger { 122 margin: 0; 123 display: flex; 124 flex-direction: column; 125 gap: var(--wpshelf-space-2); 126 } 127 128 .wpshelf-ledger__row { 129 display: flex; 130 align-items: baseline; 131 justify-content: space-between; 132 gap: var(--wpshelf-space-4); 133 margin: 0; 134 } 135 136 .wpshelf-ledger__row dt { 137 margin: 0; 138 color: var(--wpshelf-ink-soft); 139 font-size: var(--wpshelf-text-base); 140 } 141 142 .wpshelf-ledger__row dd { 143 margin: 0; 144 } 145 146 .wpshelf-ledger__row--sub { 147 padding-left: var(--wpshelf-space-4); 148 } 149 150 .wpshelf-ledger__row--sub dt { 151 color: var(--wpshelf-muted); 152 font-size: var(--wpshelf-text-sm); 153 } 154 155 .wpshelf-ledger__total { 156 margin-top: var(--wpshelf-space-1); 157 padding-top: var(--wpshelf-space-2); 158 border-top: 1px solid var(--wpshelf-line); 159 } 160 161 .wpshelf-ledger__total dt, 162 .wpshelf-ledger__total dd { 163 font-weight: var(--wpshelf-weight-semi); 164 color: var(--wpshelf-ink); 165 } 166 167 .wpshelf-ledger__note { 168 margin: 0; 169 color: var(--wpshelf-ink-soft); 170 font-size: var(--wpshelf-text-sm); 171 } -
gloty/trunk/shared-js/design-system/src/table-state.js
r3723648 r3748411 148 148 * @return {number} Comparator result. 149 149 */ 150 /** 151 * One collator for every comparison. 152 * 153 * `localeCompare` with an options object builds a fresh `Intl.Collator` on 154 * each call, and a sort makes n·log n of them: 5,000 rows — the most these 155 * screens load — took about 100ms per sort that way, and the sort reruns on 156 * every keystroke in the search box. One collator built once sorts the same 157 * rows in about 6ms with exactly the same ordering. 158 */ 159 const collator = new Intl.Collator(undefined, { 160 numeric: true, 161 sensitivity: 'base', 162 }); 163 150 164 export function compareRows(a, b, column, direction) { 151 165 const pick = column.sortValue ? column.sortValue : (row) => row[column.key]; … … 161 175 } 162 176 163 return ( 164 String(left ?? '').localeCompare(String(right ?? ''), undefined, { 165 numeric: true, 166 sensitivity: 'base', 167 }) * sign 168 ); 177 return collator.compare(String(left ?? ''), String(right ?? '')) * sign; 169 178 } 170 179 -
gloty/trunk/src/admin/LicensePanel.js
r3723648 r3748411 88 88 const [hasKey, setHasKey] = useState(boot?.license?.hasKey || false); 89 89 const [keyMasked, setKeyMasked] = useState(boot?.license?.keyMasked || ''); 90 /* 91 * The service answered and no longer accepts the stored key — an operator 92 * rotated it, or the licence is gone. Distinct from "could not be reached": 93 * waiting fixes that one, only a replacement key fixes this. 94 */ 95 const [keyRefused, setKeyRefused] = useState( 96 boot?.license?.keyRefused || false 97 ); 90 98 const [busy, setBusy] = useState(false); 91 99 const [refreshing, setRefreshing] = useState(false); … … 123 131 setHasKey(res?.has_key || false); 124 132 setStatus(res?.status || null); 133 setKeyRefused(res?.key_refused || false); 125 134 if (res?.key_masked) { 126 135 setKeyMasked(res.key_masked); … … 213 222 if (res?.ok) { 214 223 setHasKey(true); 224 setKeyRefused(false); 215 225 setKeyInput(''); 216 226 setNotice({ … … 245 255 setHasKey(false); 246 256 setStatus(null); 257 setKeyRefused(false); 247 258 setNotice({ 248 259 status: 'info', … … 627 638 )} 628 639 629 {hasKey && !status && ( 640 {/* 641 Worded for both causes, because the service deliberately does 642 not say which, and with no suggestion the key was misused. The 643 field is here rather than behind Deactivate: activating the 644 replacement re-binds this site's existing activation, so it 645 takes no extra seat. 646 */} 647 {hasKey && !status && keyRefused && ( 648 <> 649 <Notice 650 status="warning" 651 isDismissible={false} 652 className="wpshelf-mb" 653 > 654 <p> 655 <strong> 656 {__( 657 'This license key is no longer accepted.', 658 'gloty' 659 )} 660 </strong> 661 </p> 662 <p> 663 {__( 664 'Translations keep running, but usage is not recorded against your plan. If you were sent a replacement key, or can see one in your WP Shelf account, paste it here and activate it.', 665 'gloty' 666 )}{' '} 667 <a 668 href="https://wp-shelf.com/dashboard/licenses" 669 target="_blank" 670 rel="noopener noreferrer" 671 > 672 {__('Open your WP Shelf licenses', 'gloty')} 673 </a> 674 </p> 675 </Notice> 676 <div className="wpshelf-settings-field"> 677 <TextControl 678 label={__('Replacement license key', 'gloty')} 679 value={keyInput} 680 onChange={setKeyInput} 681 placeholder="GLOTY-XXXX-XXXX-XXXX-XXXX" 682 __nextHasNoMarginBottom 683 /> 684 </div> 685 <Button 686 variant="primary" 687 onClick={activate} 688 isBusy={busy} 689 disabled={busy || !keyInput.trim()} 690 > 691 {__('Activate', 'gloty')} 692 </Button> 693 </> 694 )} 695 696 {hasKey && !status && !keyRefused && ( 630 697 <p className="wpshelf-muted"> 631 698 {keyMasked && ( -
gloty/trunk/src/admin/style.css
r3723648 r3748411 340 340 * Below the wp-admin breakpoint the sidebar stacks above the content. 341 341 * 342 * It used to be hidden outright, and the reason given was that "the plugin's own343 * submenu is still in the wp-admin menu, so a second copy of the same links342 * It used to be hidden outright, and the reason given was that "the plugin's 343 * own submenu is still in the wp-admin menu, so a second copy of the same links 344 344 * above the content is noise". That stopped being true the moment every plugin 345 345 * became a single entry under WP Shelf: this sidebar is now the only way to … … 525 525 526 526 /* This shell changes screens without a page load, so the fade is the motion a 527 motion-sensitive user meets most. Suppressed exactly as the shelf sheet does. */ 527 motion-sensitive user meets most. Suppressed exactly as the shelf sheet 528 does. */ 528 529 @media (prefers-reduced-motion: reduce) { 529 530 … … 1746 1747 } 1747 1748 1748 /* Hairline, solid, one step off the surface. Dashed grids read as thresholds. */ 1749 /* Hairline, solid, one step off the surface. Dashed grids read as 1750 thresholds. */ 1749 1751 .wpshelf-chart__grid { 1750 1752 stroke: var(--wpshelf-line); … … 1758 1760 } 1759 1761 1760 /* A wash, never a block: the line carries the shape, the fill only its weight. */ 1762 /* A wash, never a block: the line carries the shape, the fill only its 1763 weight. */ 1761 1764 .wpshelf-chart__area { 1762 1765 fill: var(--wpshelf-accent); … … 1772 1775 } 1773 1776 1774 /* The chart's one direct label — the busiest day. Ink, never the series colour. */ 1777 /* The chart's one direct label — the busiest day. Ink, never the series 1778 colour. */ 1775 1779 .wpshelf-chart__peak { 1776 1780 fill: var(--wpshelf-ink); -
gloty/trunk/vendor/composer/autoload_classmap.php
r3723648 r3748411 142 142 'WpShelf\\Platform\\FormMarkup' => $vendorDir . '/wp-shelf/platform/src/FormMarkup.php', 143 143 'WpShelf\\Platform\\LicenseClient' => $vendorDir . '/wp-shelf/platform/src/LicenseClient.php', 144 'WpShelf\\Platform\\LicenseRefusal' => $vendorDir . '/wp-shelf/platform/src/LicenseRefusal.php', 144 145 'WpShelf\\Platform\\LicenseTransport' => $vendorDir . '/wp-shelf/platform/src/LicenseTransport.php', 145 146 'WpShelf\\Platform\\Pager' => $vendorDir . '/wp-shelf/platform/src/Pager.php', -
gloty/trunk/vendor/composer/autoload_static.php
r3723648 r3748411 170 170 'WpShelf\\Platform\\FormMarkup' => __DIR__ . '/..' . '/wp-shelf/platform/src/FormMarkup.php', 171 171 'WpShelf\\Platform\\LicenseClient' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseClient.php', 172 'WpShelf\\Platform\\LicenseRefusal' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseRefusal.php', 172 173 'WpShelf\\Platform\\LicenseTransport' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseTransport.php', 173 174 'WpShelf\\Platform\\Pager' => __DIR__ . '/..' . '/wp-shelf/platform/src/Pager.php', -
gloty/trunk/vendor/composer/installed.json
r3723660 r3748411 3 3 { 4 4 "name": "wp-shelf/html-parser", 5 "version": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",6 "version_normalized": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",5 "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 6 "version_normalized": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 7 7 "dist": { 8 8 "type": "path", … … 43 43 { 44 44 "name": "wp-shelf/platform", 45 "version": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",46 "version_normalized": "dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd",45 "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 46 "version_normalized": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50", 47 47 "dist": { 48 48 "type": "path", -
gloty/trunk/vendor/composer/installed.php
r3723660 r3748411 2 2 'root' => array( 3 3 'name' => 'wp-shelf/gloty', 4 'pretty_version' => 'dev- main',5 'version' => 'dev- main',6 'reference' => '6 35a6dd92d2f2eb2936e79cfea23c4635ea223eb',4 'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 5 'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 6 'reference' => '6e5e1992bdcd2740c8e706d59d229784889aec50', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 12 12 'versions' => array( 13 13 'wp-shelf/gloty' => array( 14 'pretty_version' => 'dev- main',15 'version' => 'dev- main',16 'reference' => '6 35a6dd92d2f2eb2936e79cfea23c4635ea223eb',14 'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 15 'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 16 'reference' => '6e5e1992bdcd2740c8e706d59d229784889aec50', 17 17 'type' => 'wordpress-plugin', 18 18 'install_path' => __DIR__ . '/../../', … … 21 21 ), 22 22 'wp-shelf/html-parser' => array( 23 'pretty_version' => 'dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd',24 'version' => 'dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd',23 'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 24 'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 25 25 'reference' => '1c4b68cd06da61ac60b52a4a2bf25ec4cf160ca4', 26 26 'type' => 'library', … … 30 30 ), 31 31 'wp-shelf/platform' => array( 32 'pretty_version' => 'dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd',33 'version' => 'dev- e4bedc789bed392c81e083a5b22d932d6a8fecdd',32 'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 33 'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50', 34 34 'reference' => '1a5dd36e91615be4855bc9481ba9bacf32bb18c8', 35 35 'type' => 'library', -
gloty/trunk/vendor/wp-shelf/platform/assets/admin.css
r3723648 r3748411 492 492 } 493 493 494 /* 495 * Stacked, but compact: the links flow as a wrapped row with the group 496 * labels dropped. As a column of full-width rows it was a whole phone 497 * screen of navigation above the content, every visit. 498 */ 494 499 .wpshelf-sidebar { 495 500 position: static; 501 display: flex; 502 flex-wrap: wrap; 503 gap: 2px; 504 } 505 506 .wpshelf-sidebar__section { 507 display: contents; 508 } 509 510 .wpshelf-sidebar__section-label { 511 display: none; 512 } 513 514 /* Scoped under the sidebar so it outranks the base item rule below. */ 515 .wpshelf-sidebar .wpshelf-sidebar__item { 516 width: auto; 517 padding: 6px 10px; 496 518 } 497 519 } … … 627 649 /* ---- Content region ---- */ 628 650 .wpshelf-tab-content { 651 position: relative; 629 652 background: transparent; 630 653 border: 0; … … 632 655 margin-top: 0; 633 656 min-width: 0; 657 } 658 659 /* 660 * While an async save or navigation is in flight the content region carries 661 * aria-busy, and before this nothing drew it: the Save button stayed lit and 662 * the screen sat still until the swap. A 2px hairline across the top of the 663 * region is the shelf's whole busy signal — an edge, not a spinner, in keeping 664 * with the rest of the language. Under reduced motion the line simply shows. 665 * (`position: relative` is on the region's rule above.) 666 */ 667 .wpshelf-tab-content[aria-busy="true"]::before { 668 content: ""; 669 position: absolute; 670 top: 0; 671 left: 0; 672 width: 100%; 673 height: 2px; 674 background: var(--wpshelf-accent); 675 transform-origin: left; 676 animation: wpshelf-busy-bar 1.2s ease-in-out infinite; 677 pointer-events: none; 678 } 679 680 @keyframes wpshelf-busy-bar { 681 682 0% { 683 transform: scaleX(0); 684 } 685 686 50% { 687 transform: scaleX(0.7); 688 } 689 690 100% { 691 transform: scaleX(1); 692 opacity: 0; 693 } 694 } 695 696 /* The button that was pressed, until the server answers. */ 697 .wpshelf-is-saving { 698 opacity: 0.6; 699 cursor: progress; 700 } 701 702 /* 703 * A failure notice the script inserts gets focus so it is read out; the 704 * ring the browser draws for programmatic focus on a paragraph is noise. 705 */ 706 .wpshelf-tab-content .notice:focus, 707 .wpshelf-tab-content .wpshelf-notice:focus { 708 outline: none; 709 } 710 711 .wpshelf-tab-content .notice:focus-visible, 712 .wpshelf-tab-content .wpshelf-notice:focus-visible { 713 outline: var(--wpshelf-focus-ring); 714 } 715 716 @media (prefers-reduced-motion: reduce) { 717 718 .wpshelf-tab-content[aria-busy="true"]::before { 719 animation: none; 720 } 634 721 } 635 722 … … 821 908 } 822 909 823 /* Sentence case: a column header is a label, not an abbreviation. */ 824 .wpshelf-app .wp-list-table th { 910 /* 911 * Sentence case: a column header is a label, not an abbreviation. 912 * 913 * One header for every shelf table, whatever WordPress classes it carries. 914 * Crawlune and SnippetGrove print `wp-list-table widefat striped wpshelf-table` 915 * and Labely prints `wpshelf-table` alone, and while this rule named only the 916 * first the two computed different components from the same class: a filled, 917 * hairlined header against a bold, centred, unruled one that was the browser's 918 * default (TASK-112). So the shelf's own header is named here too, and every 919 * property WordPress sets on a `.widefat` header is set here as well — line 920 * height and wrapping included — so neither variant borrows anything from core. 921 * 922 * `table.wpshelf-table > thead > tr > th` is (0,1,4) on purpose: core's 923 * `.widefat th:not(tbody th)` is (0,1,3), and a tie would hand the header to 924 * whichever stylesheet happened to load last. It is also why this one rule is 925 * not scoped under `.wpshelf-app`: a shelf table in an order metabox is still 926 * a shelf table. Proved by computed style, not by selector, in 927 * products/labely/plugin/e2e/computed-styles.spec.js. 928 */ 929 .wpshelf-app .wp-list-table th, 930 table.wpshelf-table > thead > tr > th { 825 931 padding: var(--wpshelf-cell-pad-y) var(--wpshelf-cell-pad-x); 826 932 border-bottom: 1px solid var(--wpshelf-line); … … 829 935 font-size: var(--wpshelf-text-sm); 830 936 font-weight: var(--wpshelf-weight-medium); 937 line-height: var(--wpshelf-leading-snug); 938 overflow-wrap: break-word; 831 939 } 832 940 … … 978 1086 ───────────────────────────────────────────────────────────────────────── */ 979 1087 1088 /* No gaps between cells. `.widefat` sets this for WordPress's tables; a 1089 shelf table without it kept the browser's 2px, which showed as white seams 1090 through the header's fill. */ 980 1091 .wpshelf-table { 981 1092 max-width: var(--wpshelf-measure); 1093 border-spacing: 0; 982 1094 } 983 1095 … … 1128 1240 align-items: center; 1129 1241 gap: var(--wpshelf-space-1); 1242 /* A header and its glyph are one unit; "Statement ↕" wrapped the glyph 1243 onto a line of its own in a narrow column. */ 1244 white-space: nowrap; 1130 1245 padding: 0; 1131 1246 border: none; … … 1177 1292 } 1178 1293 1294 /* A header reads from its start edge, whatever the browser (centre) or 1295 WordPress (`.widefat th`, left — wrong in RTL) would have said. Above core 1296 for the same reason as the header rule; below the modifiers that follow. */ 1297 table.wpshelf-table > thead > tr > th { 1298 text-align: start; 1299 } 1300 1301 /* A column's alignment reaches its header, so a right-aligned figure sits 1302 under a right-aligned label. (0,2,1): above the header default and above 1303 `.widefat th`, which used to pin every DataTable header left. */ 1304 .wpshelf-table th.wpshelf-cell--left { 1305 text-align: left; 1306 } 1307 1308 .wpshelf-table th.wpshelf-cell--right { 1309 text-align: right; 1310 } 1311 1312 .wpshelf-table th.wpshelf-cell--center { 1313 text-align: center; 1314 } 1315 1179 1316 /* Declared even though it is the default: a column may state `align: 'left'` 1180 1317 explicitly, and a class that renders with no rule behind it is the failure … … 1191 1328 .wpshelf-cell--center { 1192 1329 text-align: center; 1330 } 1331 1332 /* ---- Money cell ---- 1333 Right-aligned and tabular so a column of amounts lines up on the decimal; 1334 `is-negative`/`is-muted` are plain state classes, not `.wpshelf-*` modifiers, 1335 because they say something about the value rather than name a variant of 1336 the component. */ 1337 .wpshelf-cell--money { 1338 text-align: right; 1339 font-variant-numeric: tabular-nums; 1340 /* An amount is one token: "€14,9 / 9" broken over two lines reads as two 1341 numbers. A narrow table scrolls in its wrapper instead. */ 1342 white-space: nowrap; 1343 color: var(--wpshelf-ink); 1344 } 1345 1346 .wpshelf-cell--money.is-negative { 1347 color: var(--wpshelf-danger); 1348 } 1349 1350 .wpshelf-cell--money.is-muted { 1351 color: var(--wpshelf-muted); 1193 1352 } 1194 1353 … … 1894 2053 font-size: var(--wpshelf-text-sm); 1895 2054 color: var(--wpshelf-muted); 2055 } 2056 2057 /* The table controls and the bulk bar hide with the `hidden` attribute, 2058 which a `display` rule would otherwise override — Previous/Next showed 2059 under a one-page table and "0 rows selected" sat above every list. */ 2060 .wpshelf-pager[hidden], 2061 .wpshelf-filters[hidden], 2062 .wpshelf-bulkbar[hidden] { 2063 display: none; 1896 2064 } 1897 2065 … … 2399 2567 } 2400 2568 2569 /* 2570 * A checkbox or radio inside a field label is a tick box beside its text, not 2571 * a full-width text box: the rule above drew one as an empty bar with its 2572 * label underneath. 2573 */ 2574 .wpshelf-field > input[type="checkbox"], 2575 .wpshelf-field > input[type="radio"] { 2576 display: inline-block; 2577 width: auto; 2578 margin: 0 var(--wpshelf-space-2) 0 0; 2579 padding: 0; 2580 vertical-align: middle; 2581 } 2582 2401 2583 .wpshelf-field > input:focus, 2402 2584 .wpshelf-field > textarea:focus, … … 2527 2709 font-size: var(--wpshelf-text-sm); 2528 2710 line-height: var(--wpshelf-leading-normal); 2711 } 2712 2713 /* ---- Ledger ---- 2714 A calculation read top to bottom, one line per input. A `<dl>` rather than a table — each row is a label/value 2715 pair, not a record with equal-weight columns — mirroring the definition-row 2716 shape `.wpshelf-license-*` already uses above. */ 2717 .wpshelf-ledger { 2718 margin: 0; 2719 display: flex; 2720 flex-direction: column; 2721 gap: var(--wpshelf-space-2); 2722 } 2723 2724 .wpshelf-ledger__row { 2725 display: flex; 2726 align-items: baseline; 2727 justify-content: space-between; 2728 gap: var(--wpshelf-space-4); 2729 margin: 0; 2730 } 2731 2732 .wpshelf-ledger__row dt { 2733 margin: 0; 2734 color: var(--wpshelf-ink-soft); 2735 font-size: var(--wpshelf-text-base); 2736 } 2737 2738 .wpshelf-ledger__row dd { 2739 margin: 0; 2740 } 2741 2742 /* A cost line's own detail — the shipping/packaging/fee rows under a line 2743 item, or a guard's cap under the amount. Indented so the hierarchy reads 2744 without a second column. */ 2745 .wpshelf-ledger__row--sub { 2746 padding-left: var(--wpshelf-space-4); 2747 } 2748 2749 .wpshelf-ledger__row--sub dt { 2750 color: var(--wpshelf-muted); 2751 font-size: var(--wpshelf-text-sm); 2752 } 2753 2754 .wpshelf-ledger__total { 2755 margin-top: var(--wpshelf-space-1); 2756 padding-top: var(--wpshelf-space-2); 2757 border-top: 1px solid var(--wpshelf-line); 2758 } 2759 2760 .wpshelf-ledger__total dt, 2761 .wpshelf-ledger__total dd { 2762 font-weight: var(--wpshelf-weight-semi); 2763 color: var(--wpshelf-ink); 2764 } 2765 2766 /* The measured/assumed footnote under a cost input. */ 2767 .wpshelf-ledger__note { 2768 margin: 0; 2769 color: var(--wpshelf-ink-soft); 2770 font-size: var(--wpshelf-text-sm); 2529 2771 } 2530 2772 … … 2754 2996 } 2755 2997 } 2998 2999 /* ---- Pagers: "Next" at the size of the page count beside it ------------- 3000 WordPress sets `.tablenav-pages .button` to 16 px for its « ‹ › » glyphs; 3001 `Pager` prints words there, so "Next" drew a size larger than 3002 "Page 1 of 2" and every other button on the screen. */ 3003 .wpshelf-app .tablenav-pages { 3004 display: flex; 3005 align-items: center; 3006 justify-content: flex-end; 3007 gap: var(--wpshelf-space-2); 3008 } 3009 3010 .wpshelf-app .tablenav-pages .displaying-num { 3011 margin: 0; 3012 } 3013 3014 .wpshelf-app .tablenav-pages .button { 3015 min-width: 0; 3016 min-height: 0; 3017 padding: 0 10px; 3018 font-size: var(--wpshelf-text-base); 3019 line-height: calc(var(--wpshelf-control-h) - 2px); 3020 vertical-align: middle; 3021 } -
gloty/trunk/vendor/wp-shelf/platform/assets/screens.js
r3688478 r3748411 15 15 let request; 16 16 let currentUrl = window.location.href; 17 // The content region the server printed, captured while this footer script 18 // runs. A client router that takes the shell over (Crawlune's and 19 // SnippetGrove's bundles) replaces it, and the ServerScreen it renders 20 // mounts its own content through render() — so a detached capture is the 21 // signal that first-load boot has nothing left to do. 22 const served = document.querySelector('.wpshelf-tab-content'); 17 23 const text = (tag, value, className) => { 18 24 const node = document.createElement(tag); … … 107 113 } 108 114 115 /** Rows above which a table gets a search box. */ 116 const SEARCH_THRESHOLD = 10; 117 // Built once: localeCompare with options builds a collator per comparison, 118 // and a sort over a few thousand rows makes tens of thousands of them. 119 const collator = new Intl.Collator(undefined, { 120 numeric: true, 121 sensitivity: 'base', 122 }); 123 109 124 function tableControls(root) { 110 125 for (const table of root.querySelectorAll( … … 124 139 let sort = -1; 125 140 let direction = 1; 141 // A search box, a "15 / 15 · 1 / 1" counter and Previous/Next on a 142 // one-row table are noise; they appear once there is something to 143 // search or page through. 144 const searchable = rows.length > SEARCH_THRESHOLD; 126 145 const toolbar = document.createElement('div'); 127 146 toolbar.className = 'wpshelf-filters'; 147 toolbar.hidden = !searchable; 128 148 const search = document.createElement('input'); 129 149 search.type = 'search'; … … 133 153 const summary = text('span', '', 'wpshelf-footnote'); 134 154 summary.setAttribute('aria-live', 'polite'); 135 toolbar.append(search, summary); 136 table.before(toolbar); 155 // In the search wrapper, so it takes the filter bar's search width 156 // rather than stretching across the whole card. 157 const searchWrap = document.createElement('div'); 158 searchWrap.className = 'wpshelf-filters__search'; 159 searchWrap.append(search); 160 toolbar.append(searchWrap, summary); 161 // Outside the scrolling wrapper, so the controls stay put while a 162 // wide table scrolls sideways beneath them. 163 const anchor = table.closest('.wpshelf-table-wrap') || table; 164 anchor.before(toolbar); 137 165 const pager = document.createElement('div'); 138 166 pager.className = 'wpshelf-pager'; … … 141 169 previous.type = next.type = 'button'; 142 170 pager.append(previous, next); 143 table.after(pager);171 anchor.after(pager); 144 172 const headers = [...table.tHead.rows[0].cells]; 173 const glyphs = []; 145 174 function draw() { 146 175 const terms = search.value … … 157 186 matching.sort( 158 187 (a, b) => 159 (a.cells[sort]?.textContent || '').localeCompare( 160 b.cells[sort]?.textContent || '', 161 undefined, 162 { numeric: true, sensitivity: 'base' } 188 collator.compare( 189 a.cells[sort]?.textContent || '', 190 b.cells[sort]?.textContent || '' 163 191 ) * direction 164 192 ); … … 172 200 table.tBodies[0].append(row); 173 201 }); 174 summary.textContent = `${matching.length} / ${rows.length} · ${page} / ${pages}`; 202 summary.textContent = 203 pages > 1 || matching.length !== rows.length 204 ? `${matching.length} / ${rows.length} · ${page} / ${pages}` 205 : ''; 175 206 previous.disabled = page <= 1; 176 207 next.disabled = page >= pages; … … 186 217 ) 187 218 ); 219 glyphs.forEach(([index, glyph]) => { 220 const active = index === sort; 221 glyph.textContent = active ? (direction === 1 ? '↑' : '↓') : '↕'; 222 glyph.parentNode.classList.toggle( 223 'wpshelf-table__sort--active', 224 active 225 ); 226 }); 188 227 } 189 228 headers.forEach((header, index) => { … … 193 232 ) 194 233 return; 234 // The label and a dimmed glyph that holds its width, so a 235 // header never wraps onto a line of its own for the arrow. 195 236 const button = text( 196 237 'button', 197 `${header.textContent} ↕`,238 header.textContent.trim(), 198 239 'wpshelf-table__sort' 199 240 ); 241 const glyph = text('span', '↕', 'wpshelf-table__sort-glyph'); 242 glyph.setAttribute('aria-hidden', 'true'); 243 button.append(glyph); 244 glyphs.push([index, glyph]); 200 245 button.type = 'button'; 201 246 header.replaceChildren(button); … … 225 270 } 226 271 227 function mount(root) { 228 mounted.get(root)?.(); 272 /** 273 * Where attention goes once a save has redrawn the screen. 274 * 275 * A full page load would put the reader at the top, beside the notice 276 * WordPress printed. The async swap removed the button that had focus, so 277 * without this focus fell to <body> and a screen reader said nothing. The 278 * notice is the outcome, so it is focused first; failing that, the 279 * heading; failing that, the content region itself. 280 */ 281 function settle(root) { 282 const target = 283 root.querySelector( 284 '.notice, .wpshelf-notice, [role="alert"], [role="status"]' 285 ) || 286 root.querySelector('h1') || 287 root; 288 if (!target.hasAttribute('tabindex')) target.tabIndex = -1; 289 target.focus(); 290 window.scrollTo({ top: 0 }); 291 } 292 293 /** 294 * A failure the reader cannot miss: announced, focused, dismissible. 295 * 296 * The dismiss control is the one WordPress adds to `is-dismissible` 297 * notices on page load, and only then — a notice inserted later gets none 298 * from core, so it is built here. 299 */ 300 function alert(message) { 301 const notice = text('p', message, 'notice notice-error is-dismissible'); 302 notice.setAttribute('role', 'alert'); 303 notice.tabIndex = -1; 304 const dismiss = document.createElement('button'); 305 dismiss.type = 'button'; 306 dismiss.className = 'notice-dismiss'; 307 dismiss.append(text('span', labels.dismiss || 'Dismiss', 'screen-reader-text')); 308 dismiss.addEventListener('click', () => notice.remove()); 309 notice.append(dismiss); 310 return notice; 311 } 312 313 /** Run every registered module on a root; return their cleanups. */ 314 function mountModules(root) { 229 315 const cleanups = []; 230 let submission;231 316 for (const init of modules.values()) { 232 317 const cleanup = init(root); 233 318 if (typeof cleanup === 'function') cleanups.push(cleanup); 234 319 } 320 return cleanups; 321 } 322 323 /** Record how to dispose a root's instance, so the next mount runs it first. */ 324 function remember(root, cleanups) { 325 let disposed = false; 326 const dispose = () => { 327 if (!disposed) { 328 disposed = true; 329 cleanups.reverse().forEach((cleanup) => cleanup()); 330 } 331 }; 332 mounted.set(root, dispose); 333 return () => mounted.get(root)?.(); 334 } 335 336 function mount(root) { 337 mounted.get(root)?.(); 338 const cleanups = mountModules(root); 339 let submission; 235 340 tableControls(root); 236 341 const submit = async (event) => { … … 270 375 submission = new AbortController(); 271 376 root.setAttribute('aria-busy', 'true'); 377 // aria-disabled rather than disabled: a disabled button drops out 378 // of the tab order and throws keyboard focus to the top of the 379 // page. The dataset flag above already stops a second submit. 380 const pressed = event.submitter; 381 pressed?.setAttribute('aria-disabled', 'true'); 382 pressed?.classList.add('wpshelf-is-saving'); 272 383 try { 273 384 await render(url.href, root, { … … 277 388 history: true, 278 389 }); 390 settle(root); 279 391 } catch (error) { 280 392 if (error.name === 'AbortError') return; 281 393 // Never retry a write automatically: the server may have saved it. 282 root.prepend( 283 text( 284 'p', 285 method === 'GET' ? labels.failed : labels.saveFailed, 286 'notice notice-error' 287 ) 394 const notice = alert( 395 method === 'GET' ? labels.failed : labels.saveFailed 288 396 ); 397 root.prepend(notice); 398 notice.focus(); 289 399 } finally { 290 400 delete form.dataset.shelfSubmitting; 291 401 root.removeAttribute('aria-busy'); 402 pressed?.removeAttribute('aria-disabled'); 403 pressed?.classList.remove('wpshelf-is-saving'); 292 404 } 293 405 }; … … 312 424 root.addEventListener('change', change); 313 425 cleanups.push(() => root.removeEventListener('change', change)); 314 let disposed = false; 315 const dispose = () => { 316 if (!disposed) { 317 disposed = true; 318 cleanups.reverse().forEach((cleanup) => cleanup()); 319 } 320 }; 321 mounted.set(root, dispose); 322 return () => mounted.get(root)?.(); 426 return remember(root, cleanups); 323 427 } 324 428 … … 417 521 tableControls, 418 522 refresh: (root) => render(location.href, root, screens.get(root)), 523 // A property, not a method, so a screen script can ask whether the copy 524 // that loaded mounts its module on a plain load — an older sibling's 525 // screens.js may be the one served, and it did not (TASK-106). 526 mountsOnLoad: true, 419 527 }; 528 529 /** 530 * First (non-async) load: mount the registered modules on the screen the 531 * server printed. Before this, a module only mounted from render(), so on 532 * a product that is not standalone every enhancement a screen registered 533 * was inert until something re-rendered it. 534 * 535 * A standalone product gets the whole mount — modules, table controls and 536 * form interception — because its links and saves are async. One that is 537 * not gets its modules only: its forms post and reload, and intercepting 538 * them is what once told a ShareCrew merchant "The save could not be 539 * confirmed" for a save that had succeeded. The product is recorded either 540 * way, so a module that calls refresh() redraws the right screen. Either 541 * way the disposer lands in `mounted`, so a later render() on the same 542 * root cleans this instance before mounting the next: never two live. 543 */ 544 function boot() { 545 const root = served || document.querySelector('.wpshelf-tab-content'); 546 if (!root || !root.isConnected || mounted.has(root)) return; 547 root.dataset.wpshelfPage = new URL(location.href).searchParams.get('page'); 548 screens.set(root, { product: labels.product }); 549 if (labels.standalone) mount(root); 550 else remember(root, mountModules(root)); 551 } 552 420 553 if (labels.standalone) { 421 554 document.addEventListener('click', (event) => { … … 448 581 if (currentUrl !== location.href) navigate(location.href, true); 449 582 }); 450 const boot = () => {451 const root = document.querySelector('.wpshelf-tab-content');452 if (root) {453 root.dataset.wpshelfPage = new URL(location.href).searchParams.get(454 'page'455 );456 screens.set(root, { product: labels.product });457 mount(root);458 }459 };460 583 if (document.readyState !== 'complete') 461 584 window.addEventListener('load', boot, { once: true }); 462 585 else boot(); 586 } else { 587 // DOMContentLoaded rather than load: these screens' forms post for 588 // real, and a guard (a confirm before a money-moving action) has to be 589 // on them before anyone can press one — the moment a page-load-time 590 // script would have attached it. Then one task later, so a client 591 // router that replaces the shell on DOMContentLoaded has done so. 592 const later = () => setTimeout(boot, 0); 593 if (document.readyState === 'loading') 594 document.addEventListener('DOMContentLoaded', later, { once: true }); 595 else later(); 463 596 } 464 597 })(); -
gloty/trunk/vendor/wp-shelf/platform/src/AdminAssets.php
r3723648 r3748411 45 45 * cards computed `border: none`. 46 46 * 47 * So the file is chosen by **mtime across every installed copy**, not by which 48 * class won. A stylesheet has no API to call and no version to negotiate; the 49 * newest one on disk is a superset of the older ones, because this package only 50 * ever adds — *if* newest on disk meant newest built, and it does not. WordPress 51 * writes each file as it unzips, so the mtime is when that plugin was last 52 * installed or updated on this site: updating the plugin with the stalest 53 * vendored copy makes that copy win (measured 2026-09-23, see 54 * docs/operations/shelf-coinstall-final-2026-09-23.md). A shared-asset change is 55 * durable only once every shelf plugin has shipped it, and 56 * infra/wordpress/shelf-together-check.sh fails when installed copies disagree. 47 * So the file is chosen **across every installed copy**, not by which class 48 * won. A stylesheet has no API to call and no version to negotiate; the newest 49 * copy is a superset of the older ones, because this package only ever adds. 50 * "Newest" was first taken from mtime, and that was wrong in a way that took a 51 * measurement to see: WordPress writes each file as it unzips, so the mtime is 52 * when that plugin was last installed or updated on this site, and updating the 53 * plugin with the stalest vendored copy made that copy win (2026-09-23, 54 * docs/operations/shelf-coinstall-final-2026-09-23.md). 55 * 56 * Newest now means the highest **revision stamp** — `assets/revision.txt`, 57 * written by `scripts/stamp-shared-assets.php`, committed beside the assets and 58 * copied wherever they are copied. It describes the bytes, not the install, so 59 * which plugin the customer updated last stops mattering. Mtime remains the 60 * tie-breaker, and the whole answer for copies vendored before the stamp 61 * existed. Two limits still hold: the *class* that does the choosing is still 62 * whichever copy won, so an old sibling's `AdminAssets` keeps choosing by mtime 63 * until that sibling is updated; and a shared-asset change is durable only once 64 * every shelf plugin has shipped it. infra/wordpress/shelf-together-check.sh 65 * fails when installed copies disagree. 57 66 * 58 67 * The class API is a different matter and cannot be fixed this way — the winning … … 149 158 * stylesheet for a day with a one-year max-age. 150 159 * 151 * The file's own mtime keys the URL to the bytes instead. It changes on any 152 * deploy that rewrites the file and on no deploy that does not. 160 * The copy's revision stamp keys the URL to the bytes instead: identical 161 * bytes get an identical URL whichever plugin they are served from, and a 162 * new revision is a new URL. A copy with no stamp — one vendored before the 163 * stamp existed — falls back to its mtime, which changes on any deploy that 164 * rewrites the file and on no deploy that does not. 153 165 * 154 166 * @param string $fallback Used when the file cannot be stat'd. … … 156 168 */ 157 169 private static function cache_key( string $fallback, string $file = 'admin.css' ): string { 158 $path = self::newest_path_for( $file ); 159 $mtime = '' !== $path && \is_readable( $path ) ? \filemtime( $path ) : false; 170 $path = self::newest_path_for( $file ); 171 172 if ( '' === $path || ! \is_readable( $path ) ) { 173 return $fallback; 174 } 175 176 $revision = self::revision_of( $path ); 177 178 if ( $revision > 0 ) { 179 return (string) $revision; 180 } 181 182 $mtime = \filemtime( $path ); 160 183 161 184 return false !== $mtime ? (string) $mtime : $fallback; … … 201 224 202 225 /** 203 * The most recently modified of a list of paths.226 * The newest of a list of copies: highest revision stamp, then latest mtime. 204 227 * 205 228 * Split out from the glob so it can be tested: the decision is the part with … … 208 231 * mid-update whose file is briefly gone cannot win by being unstat-able. 209 232 * 233 * The revision comes from `revision.txt` beside the copy, written by 234 * `scripts/stamp-shared-assets.php` and committed with the assets it 235 * describes — so it is a fact about the bytes, where the mtime is a fact 236 * about when this site unpacked them. A copy with no stamp predates the 237 * stamp and so is older than any copy that has one; among unstamped copies 238 * the mtime still decides, which is exactly the previous behaviour. 239 * 210 240 * @param list<string> $paths Absolute paths, any of which may not exist. 211 241 * … … 213 243 */ 214 244 private static function newest( array $paths ): string { 215 $best = ''; 216 $mtime = -1; 245 $best = ''; 246 $revision = -1; 247 $mtime = -1; 217 248 218 249 foreach ( $paths as $path ) { … … 221 252 } 222 253 223 $candidate = (int) \filemtime( $path ); 224 225 if ( $candidate > $mtime ) { 226 $best = $path; 227 $mtime = $candidate; 254 $candidate_revision = self::revision_of( $path ); 255 $candidate_mtime = (int) \filemtime( $path ); 256 257 if ( 258 $candidate_revision > $revision 259 || ( $candidate_revision === $revision && $candidate_mtime > $mtime ) 260 ) { 261 $best = $path; 262 $revision = $candidate_revision; 263 $mtime = $candidate_mtime; 228 264 } 229 265 } 230 266 231 267 return $best; 268 } 269 270 /** 271 * The revision stamped beside a copy of an asset, or 0 when it has none. 272 * 273 * The first line of `revision.txt` in the asset's directory, as an integer. 274 * Anything else in the file — the comment, the per-file hashes the stamp 275 * script checks — is for people and for `--check`, not for this method. 276 * Read once per directory per request: a site with five of our plugins 277 * asks about three files in each of five directories. 278 * 279 * @param string $asset_path Absolute path of a copy of an asset. 280 */ 281 private static function revision_of( string $asset_path ): int { 282 /** @var array<string, int> $revisions */ 283 static $revisions = []; 284 285 $dir = \dirname( $asset_path ); 286 287 if ( isset( $revisions[ $dir ] ) ) { 288 return $revisions[ $dir ]; 289 } 290 291 $manifest = $dir . '/revision.txt'; 292 $first = ''; 293 294 if ( \is_readable( $manifest ) ) { 295 $handle = \fopen( $manifest, 'r' ); 296 297 if ( false !== $handle ) { 298 $first = \trim( (string) \fgets( $handle ) ); 299 \fclose( $handle ); 300 } 301 } 302 303 $revisions[ $dir ] = '' !== $first && \ctype_digit( $first ) ? (int) $first : 0; 304 305 return $revisions[ $dir ]; 232 306 } 233 307 -
gloty/trunk/vendor/wp-shelf/platform/src/AsyncScreens.php
r3688478 r3748411 42 42 'next' => \__('Next', 'default'), 43 43 'loaded' => \__('Search and sort apply to the loaded rows.', 'default'), 44 'dismiss' => \__('Dismiss this notice.', 'default'), 44 45 ], $labels)); 45 46 } -
gloty/trunk/vendor/wp-shelf/platform/src/LicenseClient.php
r3723648 r3748411 133 133 $this->store_license_key( $key ); 134 134 $this->cache_status( $response ); 135 LicenseRefusal::clear( $this->config ); 135 136 } 136 137 … … 183 184 * response: a licensing outage must not stop a paying customer working. 184 185 * 186 * **A refusal is not an outage, and is not answered like one.** When the 187 * service answers and the answer is the uniform refusal (see 188 * {@see LicenseRefusal::is_refusal()}) — the key was rotated, or the 189 * licence it belonged to is gone — the cached status is dropped, the 190 * refusal is recorded for the product's screens to explain, and this 191 * returns null at once. It used to keep serving the cached plan for up to 192 * the status TTL and then return null anyway, which every caller read as 193 * "could not reach the service": the site stopped validating and blamed 194 * the network. Null is still what callers get, so `is_dispatch_allowed()` 195 * fails open exactly as before; what changed is that the plugin can now 196 * tell its owner why. An unreachable server, a 429 or a 5xx still fall 197 * back to the cache. 198 * 185 199 * The key is tested before the server URL is resolved, and the order is the 186 200 * point. Resolving reads the server-URL option, which SnippetGrove and … … 217 231 $response = ( $post['ok'] && isset( $post['data'] ) ) ? $post['data'] : null; 218 232 233 if ( LicenseRefusal::is_refusal( $response ) ) { 234 LicenseRefusal::record( $this->config, $key ); 235 \delete_transient( $this->config->status_transient ); 236 return null; 237 } 238 219 239 if ( ! is_array( $response ) || empty( $response['ok'] ) ) { 220 240 return $this->cached_status(); … … 222 242 223 243 $this->cache_status( $response ); 244 LicenseRefusal::clear( $this->config ); 224 245 225 246 return $response; … … 368 389 $this->store_license_key( '' ); 369 390 \delete_transient( $this->config->status_transient ); 391 LicenseRefusal::clear( $this->config ); 370 392 } 371 393
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)