Plugin Directory

Changeset 3748411


Ignore:
Timestamp:
10/15/2026 12:14:02 PM (9 days ago)
Author:
wpshelf
Message:

Gloty 1.64.0

Location:
gloty
Files:
4 added
56 edited
1 copied

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. */
    22(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 */
    1212(0,l.__)("%s / yr","gloty"),s):(0,l.sprintf)(/* translators: %s: price, e.g. $29 */ /* translators: %s: price, e.g. $29 */
    1313(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 */
    1515(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 */
    2424(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)
    2626// translators: %d is a number of minutes.
    2727return(0,l.sprintf)((0,l._n)("%d minute ago","%d minutes ago",a,"gloty"),a);const n=Math.round(a/60);if(n<24)
    … …  
    2929return(0,l.sprintf)((0,l._n)("%d hour ago","%d hours ago",n,"gloty"),n);const i=Math.round(n/24);
    3030// 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)(
     31return(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)(
    3232// translators: %s is a relative time, e.g. "2 minutes ago".
    3333// 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 */
    3636(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 */
    3939(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 */
    4343(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 */
    4747(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 */
    4848(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 */
    4949(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 */
    5050(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}
    22.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}
    22.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  
    99        {
    1010            "name": "wp-shelf/html-parser",
    11             "version": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
     11            "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
    1212            "dist": {
    1313                "type": "path",
    … …  
    4646        {
    4747            "name": "wp-shelf/platform",
    48             "version": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
     48            "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
    4949            "dist": {
    5050                "type": "path",
  • gloty/tags/1.64.0/gloty.php

    r3723660 r3748411  
    44 * Plugin URI: https://wp-shelf.com/gloty
    55 * 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.63.3
     6 * Version: 1.64.0
    77 * Author: WP Shelf
    88 * Author URI: https://wp-shelf.com
    … …  
    6161 * Plugin constants.
    6262 */
    63 define( 'GLOTY_VERSION', '1.63.3' );
     63define( 'GLOTY_VERSION', '1.64.0' );
    6464define( 'GLOTY_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
    6565define( 'GLOTY_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
  • gloty/tags/1.64.0/includes/API/class-admin-rest-routes.php

    r3723648 r3748411  
    19491949                                        if ( null === $status ) {
    19501950                                                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(),
    19551959                                                ] );
    19561960                                        }
    19571961                                        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,
    19621967                                        ] );
    19631968                                },
  • gloty/tags/1.64.0/includes/Admin/class-admin-boot-data.php

    r3692917 r3748411  
    249249                        'serverUrl'  => $server_url,
    250250                        '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(),
    251254                ];
    252255        }
  • gloty/tags/1.64.0/includes/Admin/class-issues-service.php

    r3723648 r3748411  
    179179
    180180                $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
    181208                if ( null === $status ) {
    182209                        return [
  • gloty/tags/1.64.0/includes/Licensing/class-license-client.php

    r3635518 r3748411  
    2121
    2222use WpShelf\Platform\LicenseClient as PlatformLicenseClient;
     23use WpShelf\Platform\LicenseRefusal;
    2324use WpShelf\Platform\ProductConfig;
    2425
    … …  
    3940         */
    4041        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';
    4149
    4250        private static ?PlatformLicenseClient $client = null;
    … …  
    109117         */
    110118        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;
    112129        }
    113130
    … …  
    118135         */
    119136        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() );
    121161        }
    122162
  • gloty/tags/1.64.0/languages/gloty.pot

    r3723648 r3748411  
    196196msgstr ""
    197197
    198 #: includes/API/class-admin-rest-routes.php:2113
    199 #: includes/API/class-admin-rest-routes.php:2150
     198#: includes/API/class-admin-rest-routes.php:2118
     199#: includes/API/class-admin-rest-routes.php:2155
    200200msgid "Email and name are required."
    201201msgstr ""
    202202
    203 #: includes/API/class-admin-rest-routes.php:2200
     203#: includes/API/class-admin-rest-routes.php:2205
    204204msgid "Could not create your license."
    205205msgstr ""
    206206
    207 #: includes/API/class-admin-rest-routes.php:2217
     207#: includes/API/class-admin-rest-routes.php:2222
    208208msgid "Could not register this site with the translator service."
    209209msgstr ""
    … …  
    358358msgstr ""
    359359
    360 #: includes/Admin/class-issues-service.php:186
     360#: includes/Admin/class-issues-service.php:195
     361msgid "License key no longer accepted"
     362msgstr ""
     363
     364#: includes/Admin/class-issues-service.php:196
     365msgid "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."
     366msgstr ""
     367
     368#: includes/Admin/class-issues-service.php:201
     369msgid "Enter the new key"
     370msgstr ""
     371
     372#: includes/Admin/class-issues-service.php:213
    361373msgid "License server is unreachable"
    362374msgstr ""
    363375
    364 #: includes/Admin/class-issues-service.php:187
     376#: includes/Admin/class-issues-service.php:214
    365377msgid "We could not check your plan status. Translations still work; this will resolve automatically when the server is reachable."
    366378msgstr ""
    367379
    368 #: includes/Admin/class-issues-service.php:202
     380#: includes/Admin/class-issues-service.php:229
    369381msgid "Character quota exceeded"
    370382msgstr ""
    371383
    372384#. translators: 1: characters used, 2: character limit
    373 #: includes/Admin/class-issues-service.php:205
     385#: includes/Admin/class-issues-service.php:232
    374386msgid "Used %1$s of %2$s characters. Dispatching is blocked until you upgrade or the period resets."
    375387msgstr ""
    376388
    377 #: includes/Admin/class-issues-service.php:210
    378 #: includes/Admin/class-issues-service.php:235
     389#: includes/Admin/class-issues-service.php:237
     390#: includes/Admin/class-issues-service.php:262
    379391msgid "Upgrade plan"
    380392msgstr ""
    381393
    382394#. translators: %d: percentage used
    383 #: includes/Admin/class-issues-service.php:225
     395#: includes/Admin/class-issues-service.php:252
    384396msgid "Character quota at %d%%"
    385397msgstr ""
    386398
    387399#. translators: 1: characters used, 2: character limit
    388 #: includes/Admin/class-issues-service.php:230
     400#: includes/Admin/class-issues-service.php:257
    389401msgid "Used %1$s of %2$s characters this billing period."
    390402msgstr ""
    391403
    392 #: includes/Admin/class-issues-service.php:245
     404#: includes/Admin/class-issues-service.php:272
    393405msgid "License expired"
    394406msgstr ""
    395407
    396 #: includes/Admin/class-issues-service.php:246
     408#: includes/Admin/class-issues-service.php:273
    397409msgid "Your subscription has expired. Renew to resume translation dispatch."
    398410msgstr ""
    399411
    400 #: includes/Admin/class-issues-service.php:251
     412#: includes/Admin/class-issues-service.php:278
    401413msgid "Manage billing"
    402414msgstr ""
    403415
    404416#. translators: %d: days remaining in the billing period
    405 #: includes/Admin/class-issues-service.php:265
     417#: includes/Admin/class-issues-service.php:292
    406418msgid "Billing period resets in %d day"
    407419msgid_plural "Billing period resets in %d days"
    … …  
    409421msgstr[1] ""
    410422
    411 #: includes/Admin/class-issues-service.php:273
     423#: includes/Admin/class-issues-service.php:300
    412424msgid "Usage will roll over automatically. No action required."
    413425msgstr ""
    414426
    415 #: includes/Admin/class-issues-service.php:321
     427#: includes/Admin/class-issues-service.php:348
    416428msgid "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."
    417429msgstr ""
    418430
    419431#. translators: %s: comma-separated list of language codes with counts, e.g. "de (1,204), sl (980)"
    420 #: includes/Admin/class-issues-service.php:329
     432#: includes/Admin/class-issues-service.php:356
    421433msgid "Most affected: %s."
    422434msgstr ""
    423435
    424436#. translators: %s: number of translations identical to their source
    425 #: includes/Admin/class-issues-service.php:340
     437#: includes/Admin/class-issues-service.php:367
    426438msgid "%s translation is identical to its source"
    427439msgid_plural "%s translations are identical to their source"
    … …  
    429441msgstr[1] ""
    430442
    431 #: includes/Admin/class-issues-service.php:360
     443#: includes/Admin/class-issues-service.php:387
    432444msgid "Show these rows"
    433445msgstr ""
    434446
    435 #: includes/Admin/class-issues-service.php:399
     447#: includes/Admin/class-issues-service.php:426
    436448msgid "Translated pages are not using the fast path"
    437449msgstr ""
    438450
    439 #: includes/Admin/class-issues-service.php:413
     451#: includes/Admin/class-issues-service.php:440
    440452msgid "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."
    441453msgstr ""
    442454
    443 #: includes/Admin/class-issues-service.php:417
     455#: includes/Admin/class-issues-service.php:444
    444456msgid "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."
    445457msgstr ""
    446458
    447 #: includes/Admin/class-issues-service.php:420
     459#: includes/Admin/class-issues-service.php:447
    448460msgid "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."
    449461msgstr ""
    450462
    451 #: includes/Admin/class-issues-service.php:423
     463#: includes/Admin/class-issues-service.php:450
    452464msgid "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."
    453465msgstr ""
    454466
    455 #: includes/Admin/class-issues-service.php:427
     467#: includes/Admin/class-issues-service.php:454
    456468msgid "Gloty could not write its translation cache file. This usually means the uploads directory is not writable by WordPress."
    457469msgstr ""
    458470
    459 #: includes/Admin/class-issues-service.php:430
     471#: includes/Admin/class-issues-service.php:457
    460472msgid "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."
    461473msgstr ""
    462474
    463 #: includes/Admin/class-issues-service.php:433
     475#: includes/Admin/class-issues-service.php:460
    464476msgid "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."
    465477msgstr ""
    466478
    467479#. translators: %d: number of stuck jobs
    468 #: includes/Admin/class-issues-service.php:469
     480#: includes/Admin/class-issues-service.php:496
    469481msgid "%d job stuck processing"
    470482msgid_plural "%d jobs stuck processing"
    … …  
    472484msgstr[1] ""
    473485
    474 #: includes/Admin/class-issues-service.php:477
     486#: includes/Admin/class-issues-service.php:504
    475487msgid "These jobs have been in the processing state for more than 10 minutes. They may be waiting on a webhook that never arrived."
    476488msgstr ""
    477489
    478 #: includes/Admin/class-issues-service.php:482
     490#: includes/Admin/class-issues-service.php:509
    479491msgid "View jobs"
    480492msgstr ""
    481493
    482494#. translators: %d: number of failed jobs
    483 #: includes/Admin/class-issues-service.php:494
     495#: includes/Admin/class-issues-service.php:521
    484496msgid "%d job failed in the last 24 hours"
    485497msgid_plural "%d jobs failed in the last 24 hours"
    … …  
    487499msgstr[1] ""
    488500
    489 #: includes/Admin/class-issues-service.php:502
     501#: includes/Admin/class-issues-service.php:529
    490502msgid "Check the sync events log to see why these jobs failed, and retry them when the root cause is fixed."
    491503msgstr ""
    492504
    493 #: includes/Admin/class-issues-service.php:507
    494 #: includes/Admin/class-issues-service.php:529
     505#: includes/Admin/class-issues-service.php:534
     506#: includes/Admin/class-issues-service.php:556
    495507msgid "Open sync screen"
    496508msgstr ""
    497509
    498 #: includes/Admin/class-issues-service.php:523
     510#: includes/Admin/class-issues-service.php:550
    499511msgid "Automatic translation is delayed"
    500512msgstr ""
    501513
    502 #: includes/Admin/class-issues-service.php:524
     514#: includes/Admin/class-issues-service.php:551
    503515msgid "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”."
    504516msgstr ""
    … …  
    868880
    869881#: src/admin/App.js:422
    870 #: src/admin/LicensePanel.js:453
     882#: src/admin/LicensePanel.js:464
    871883msgid "License key"
    872884msgstr ""
    … …  
    11721184#: src/admin/App.js:1761
    11731185#: src/admin/DesignSystemScreen.js:518
    1174 #: src/admin/LicensePanel.js:468
     1186#: src/admin/LicensePanel.js:479
    11751187#: src/admin/SyncScreen.js:480
    11761188#: src/admin/SyncScreen.js:938
    … …  
    17341746#: src/admin/DesignSystemScreen.js:146
    17351747#: src/admin/HealthPill.js:24
    1736 #: src/admin/LicensePanel.js:591
     1748#: src/admin/LicensePanel.js:602
    17371749msgid "Checking…"
    17381750msgstr ""
    … …  
    23152327msgstr ""
    23162328
    2317 #: src/admin/LicensePanel.js:179
     2329#: src/admin/LicensePanel.js:188
    23182330msgid "License provisioned and activated."
    23192331msgstr ""
    23202332
    2321 #: src/admin/LicensePanel.js:186
    2322 #: src/admin/LicensePanel.js:192
     2333#: src/admin/LicensePanel.js:195
     2334#: src/admin/LicensePanel.js:201
    23232335msgid "Provisioning failed."
    23242336msgstr ""
    23252337
    2326 #: src/admin/LicensePanel.js:218
     2338#: src/admin/LicensePanel.js:228
    23272339msgid "License activated."
    23282340msgstr ""
    23292341
    2330 #: src/admin/LicensePanel.js:224
    2331 #: src/admin/LicensePanel.js:230
     2342#: src/admin/LicensePanel.js:234
     2343#: src/admin/LicensePanel.js:240
    23322344msgid "Activation failed."
    23332345msgstr ""
    23342346
    2335 #: src/admin/LicensePanel.js:249
     2347#: src/admin/LicensePanel.js:260
    23362348msgid "License deactivated."
    23372349msgstr ""
    23382350
    2339 #: src/admin/LicensePanel.js:254
     2351#: src/admin/LicensePanel.js:265
    23402352msgid "Deactivation failed."
    23412353msgstr ""
    23422354
    2343 #: src/admin/LicensePanel.js:296
     2355#: src/admin/LicensePanel.js:307
    23442356msgid "No billing portal is available for this license — there’s no Stripe subscription to manage. This is normal for free or manually-granted plans."
    23452357msgstr ""
    23462358
    2347 #: src/admin/LicensePanel.js:305
     2359#: src/admin/LicensePanel.js:316
    23482360msgid "Could not open the billing portal."
    23492361msgstr ""
    23502362
    2351 #: src/admin/LicensePanel.js:333
     2363#: src/admin/LicensePanel.js:344
    23522364msgid "License"
    23532365msgstr ""
    23542366
    2355 #: src/admin/LicensePanel.js:352
     2367#: src/admin/LicensePanel.js:363
    23562368msgid "Get started with Gloty translation credits, or enter an existing license key."
    23572369msgstr ""
    23582370
    2359 #: src/admin/LicensePanel.js:375
     2371#: src/admin/LicensePanel.js:386
    23602372msgid "Get Started"
    23612373msgstr ""
    23622374
    2363 #: src/admin/LicensePanel.js:386
     2375#: src/admin/LicensePanel.js:397
    23642376msgid "I have a license key"
    23652377msgstr ""
    23662378
    2367 #: src/admin/LicensePanel.js:394
     2379#: src/admin/LicensePanel.js:405
    23682380msgid "Email"
    23692381msgstr ""
    23702382
    2371 #: src/admin/LicensePanel.js:403
     2383#: src/admin/LicensePanel.js:414
    23722384msgid "Name"
    23732385msgstr ""
    23742386
    2375 #: src/admin/LicensePanel.js:419
     2387#: src/admin/LicensePanel.js:430
    23762388msgid "Get Free License"
    23772389msgstr ""
    23782390
    2379 #: src/admin/LicensePanel.js:428
     2391#: src/admin/LicensePanel.js:439
    23802392msgid "License Key"
    23812393msgstr ""
    23822394
    2383 #: src/admin/LicensePanel.js:441
     2395#: src/admin/LicensePanel.js:452
     2396#: src/admin/LicensePanel.js:691
    23842397msgid "Activate"
    23852398msgstr ""
    23862399
    2387 #: src/admin/LicensePanel.js:462
     2400#: src/admin/LicensePanel.js:473
    23882401msgid "Plan"
    23892402msgstr ""
    23902403
    2391 #: src/admin/LicensePanel.js:474
     2404#: src/admin/LicensePanel.js:485
    23922405msgid "Sites"
    23932406msgstr ""
    23942407
    2395 #: src/admin/LicensePanel.js:482
     2408#: src/admin/LicensePanel.js:493
    23962409msgid "Usage"
    23972410msgstr ""
    23982411
    2399 #: src/admin/LicensePanel.js:494
     2412#: src/admin/LicensePanel.js:505
    24002413msgid "You’re approaching your monthly limit. Translation pauses at 100% until the limit resets or you upgrade — existing translations keep serving."
    24012414msgstr ""
    24022415
    2403 #: src/admin/LicensePanel.js:498
     2416#: src/admin/LicensePanel.js:509
    24042417msgid "Translation pauses when you reach your monthly limit, then resumes after it resets or you upgrade. Already-stored translations always keep serving."
    24052418msgstr ""
    24062419
    2407 #: src/admin/LicensePanel.js:507
     2420#: src/admin/LicensePanel.js:518
    24082421msgid "Resets"
    24092422msgstr ""
    24102423
    2411 #: src/admin/LicensePanel.js:520
    2412 #: src/admin/LicensePanel.js:557
     2424#: src/admin/LicensePanel.js:531
     2425#: src/admin/LicensePanel.js:568
    24132426msgid "Upgrade"
    24142427msgstr ""
    24152428
    2416 #: src/admin/LicensePanel.js:537
     2429#: src/admin/LicensePanel.js:548
    24172430msgid "1 site"
    24182431msgstr ""
    24192432
    24202433#. translators: %d: number of sites
    2421 #: src/admin/LicensePanel.js:540
     2434#: src/admin/LicensePanel.js:551
    24222435msgid "Up to %d sites"
    24232436msgstr ""
    24242437
    2425 #: src/admin/LicensePanel.js:558
     2438#: src/admin/LicensePanel.js:569
    24262439msgid "Buy"
    24272440msgstr ""
    24282441
    2429 #: src/admin/LicensePanel.js:580
     2442#: src/admin/LicensePanel.js:591
    24302443msgid "Manage Subscription"
    24312444msgstr ""
    24322445
    2433 #: src/admin/LicensePanel.js:592
     2446#: src/admin/LicensePanel.js:603
    24342447msgid "Refresh status"
    24352448msgstr ""
    24362449
    2437 #: src/admin/LicensePanel.js:600
    2438 #: src/admin/LicensePanel.js:619
     2450#: src/admin/LicensePanel.js:611
     2451#: src/admin/LicensePanel.js:630
    24392452msgid "Deactivate"
    24402453msgstr ""
    24412454
    2442 #: src/admin/LicensePanel.js:604
     2455#: src/admin/LicensePanel.js:615
    24432456msgid "Deactivating frees this license for another site. Your translations stay in place — nothing is deleted."
    24442457msgstr ""
    24452458
    2446 #: src/admin/LicensePanel.js:614
     2459#: src/admin/LicensePanel.js:625
    24472460msgid "Deactivate license on this site?"
    24482461msgstr ""
    24492462
    2450 #: src/admin/LicensePanel.js:615
     2463#: src/admin/LicensePanel.js:626
    24512464msgid "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."
    24522465msgstr ""
    24532466
    2454 #: src/admin/LicensePanel.js:639
     2467#: src/admin/LicensePanel.js:656
     2468msgid "This license key is no longer accepted."
     2469msgstr ""
     2470
     2471#: src/admin/LicensePanel.js:663
     2472msgid "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."
     2473msgstr ""
     2474
     2475#: src/admin/LicensePanel.js:672
     2476msgid "Open your WP Shelf licenses"
     2477msgstr ""
     2478
     2479#: src/admin/LicensePanel.js:678
     2480msgid "Replacement license key"
     2481msgstr ""
     2482
     2483#: src/admin/LicensePanel.js:706
    24552484msgid "License key is configured but the license server could not be reached."
    24562485msgstr ""
    24572486
    2458 #: src/admin/LicensePanel.js:652
     2487#: src/admin/LicensePanel.js:719
    24592488msgid "Retrying…"
    24602489msgstr ""
    24612490
    2462 #: src/admin/LicensePanel.js:653
     2491#: src/admin/LicensePanel.js:720
    24632492#: src/admin/SyncScreen.js:991
    24642493msgid "Retry"
    … …  
    34833512#. translators: %s: a number of views.
    34843513#: src/admin/TrendChart.js:340
     3514msgctxt "tooltip readout"
    34853515msgid "%s views"
    34863516msgstr ""
  • gloty/tags/1.64.0/package.json

    r3723660 r3748411  
    11{
    22  "name": "@wp-shelf/gloty",
    3   "version": "1.63.3",
     3  "version": "1.64.0",
    44  "description": "Gloty - AI-powered translation plugin for WordPress.",
    55  "private": true,
  • gloty/tags/1.64.0/readme.txt

    r3723660 r3748411  
    55Tested up to: 7.1
    66Requires PHP: 8.1
    7 Stable tag: 1.63.3
     7Stable tag: 1.64.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    196196== Changelog ==
    197197
     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
    198202= 1.63.3 =
    199203* 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  
    313313}
    314314
    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. */
     322table.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);
    317327        font-size: var(--wpshelf-text-sm);
    318328        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;
    320332}
    321333
    … …  
    384396}
    385397
     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
    386411/* Declared even though it is the default: a column may state `align: 'left'`
    387412   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  
    1414} from '@wordpress/element';
    1515import { 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.
     19const collator = new Intl.Collator(undefined, {
     20        numeric: true,
     21        sensitivity: 'base',
     22});
    1623
    1724export function tableText(node) {
    … …  
    109116                matching.sort(
    110117                        (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])
    117121                                ) * sort.direction
    118122                );
  • gloty/tags/1.64.0/shared-js/design-system/src/style.css

    r3688478 r3748411  
    9797        color: var(--wpshelf-ink-soft);
    9898}
     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  
    148148 * @return {number} Comparator result.
    149149 */
     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 */
     159const collator = new Intl.Collator(undefined, {
     160        numeric: true,
     161        sensitivity: 'base',
     162});
     163
    150164export function compareRows(a, b, column, direction) {
    151165        const pick = column.sortValue ? column.sortValue : (row) => row[column.key];
    … …  
    161175        }
    162176
    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;
    169178}
    170179
  • gloty/tags/1.64.0/src/admin/LicensePanel.js

    r3723648 r3748411  
    8888        const [hasKey, setHasKey] = useState(boot?.license?.hasKey || false);
    8989        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        );
    9098        const [busy, setBusy] = useState(false);
    9199        const [refreshing, setRefreshing] = useState(false);
    … …  
    123131                        setHasKey(res?.has_key || false);
    124132                        setStatus(res?.status || null);
     133                        setKeyRefused(res?.key_refused || false);
    125134                        if (res?.key_masked) {
    126135                                setKeyMasked(res.key_masked);
    … …  
    213222                        if (res?.ok) {
    214223                                setHasKey(true);
     224                                setKeyRefused(false);
    215225                                setKeyInput('');
    216226                                setNotice({
    … …  
    245255                        setHasKey(false);
    246256                        setStatus(null);
     257                        setKeyRefused(false);
    247258                        setNotice({
    248259                                status: 'info',
    … …  
    627638                                )}
    628639
    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 && (
    630697                                        <p className="wpshelf-muted">
    631698                                                {keyMasked && (
  • gloty/tags/1.64.0/src/admin/style.css

    r3723648 r3748411  
    340340 * Below the wp-admin breakpoint the sidebar stacks above the content.
    341341 *
    342  * It used to be hidden outright, and the reason given was that "the plugin's own
    343  * submenu is still in the wp-admin menu, so a second copy of the same links
     342 * 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
    344344 * above the content is noise". That stopped being true the moment every plugin
    345345 * became a single entry under WP Shelf: this sidebar is now the only way to
    … …  
    525525
    526526/* 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. */
    528529@media (prefers-reduced-motion: reduce) {
    529530
    … …  
    17461747}
    17471748
    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. */
    17491751.wpshelf-chart__grid {
    17501752        stroke: var(--wpshelf-line);
    … …  
    17581760}
    17591761
    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. */
    17611764.wpshelf-chart__area {
    17621765        fill: var(--wpshelf-accent);
    … …  
    17721775}
    17731776
    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. */
    17751779.wpshelf-chart__peak {
    17761780        fill: var(--wpshelf-ink);
  • gloty/tags/1.64.0/vendor/composer/autoload_classmap.php

    r3723648 r3748411  
    142142    'WpShelf\\Platform\\FormMarkup' => $vendorDir . '/wp-shelf/platform/src/FormMarkup.php',
    143143    'WpShelf\\Platform\\LicenseClient' => $vendorDir . '/wp-shelf/platform/src/LicenseClient.php',
     144    'WpShelf\\Platform\\LicenseRefusal' => $vendorDir . '/wp-shelf/platform/src/LicenseRefusal.php',
    144145    'WpShelf\\Platform\\LicenseTransport' => $vendorDir . '/wp-shelf/platform/src/LicenseTransport.php',
    145146    'WpShelf\\Platform\\Pager' => $vendorDir . '/wp-shelf/platform/src/Pager.php',
  • gloty/tags/1.64.0/vendor/composer/autoload_static.php

    r3723648 r3748411  
    170170        'WpShelf\\Platform\\FormMarkup' => __DIR__ . '/..' . '/wp-shelf/platform/src/FormMarkup.php',
    171171        'WpShelf\\Platform\\LicenseClient' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseClient.php',
     172        'WpShelf\\Platform\\LicenseRefusal' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseRefusal.php',
    172173        'WpShelf\\Platform\\LicenseTransport' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseTransport.php',
    173174        'WpShelf\\Platform\\Pager' => __DIR__ . '/..' . '/wp-shelf/platform/src/Pager.php',
  • gloty/tags/1.64.0/vendor/composer/installed.json

    r3723660 r3748411  
    33        {
    44            "name": "wp-shelf/html-parser",
    5             "version": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
    6             "version_normalized": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
     5            "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
     6            "version_normalized": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
    77            "dist": {
    88                "type": "path",
    … …  
    4343        {
    4444            "name": "wp-shelf/platform",
    45             "version": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
    46             "version_normalized": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
     45            "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
     46            "version_normalized": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
    4747            "dist": {
    4848                "type": "path",
  • gloty/tags/1.64.0/vendor/composer/installed.php

    r3723660 r3748411  
    22    'root' => array(
    33        'name' => 'wp-shelf/gloty',
    4         'pretty_version' => 'dev-main',
    5         'version' => 'dev-main',
    6         'reference' => '635a6dd92d2f2eb2936e79cfea23c4635ea223eb',
     4        'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     5        'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     6        'reference' => '6e5e1992bdcd2740c8e706d59d229784889aec50',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
    … …  
    1212    'versions' => array(
    1313        'wp-shelf/gloty' => array(
    14             'pretty_version' => 'dev-main',
    15             'version' => 'dev-main',
    16             'reference' => '635a6dd92d2f2eb2936e79cfea23c4635ea223eb',
     14            'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     15            'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     16            'reference' => '6e5e1992bdcd2740c8e706d59d229784889aec50',
    1717            'type' => 'wordpress-plugin',
    1818            'install_path' => __DIR__ . '/../../',
    … …  
    2121        ),
    2222        'wp-shelf/html-parser' => array(
    23             'pretty_version' => 'dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd',
    24             'version' => 'dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd',
     23            'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     24            'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
    2525            'reference' => '1c4b68cd06da61ac60b52a4a2bf25ec4cf160ca4',
    2626            'type' => 'library',
    … …  
    3030        ),
    3131        'wp-shelf/platform' => array(
    32             'pretty_version' => 'dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd',
    33             'version' => 'dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd',
     32            'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     33            'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
    3434            'reference' => '1a5dd36e91615be4855bc9481ba9bacf32bb18c8',
    3535            'type' => 'library',
  • gloty/tags/1.64.0/vendor/wp-shelf/platform/assets/admin.css

    r3723648 r3748411  
    492492        }
    493493
     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         */
    494499        .wpshelf-sidebar {
    495500                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;
    496518        }
    497519}
    … …  
    627649/* ---- Content region ---- */
    628650.wpshelf-tab-content {
     651        position: relative;
    629652        background: transparent;
    630653        border: 0;
    … …  
    632655        margin-top: 0;
    633656        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        }
    634721}
    635722
    … …  
    821908}
    822909
    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,
     930table.wpshelf-table > thead > tr > th {
    825931        padding: var(--wpshelf-cell-pad-y) var(--wpshelf-cell-pad-x);
    826932        border-bottom: 1px solid var(--wpshelf-line);
    … …  
    829935        font-size: var(--wpshelf-text-sm);
    830936        font-weight: var(--wpshelf-weight-medium);
     937        line-height: var(--wpshelf-leading-snug);
     938        overflow-wrap: break-word;
    831939}
    832940
    … …  
    9781086   ───────────────────────────────────────────────────────────────────────── */
    9791087
     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. */
    9801091.wpshelf-table {
    9811092        max-width: var(--wpshelf-measure);
     1093        border-spacing: 0;
    9821094}
    9831095
    … …  
    11281240        align-items: center;
    11291241        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;
    11301245        padding: 0;
    11311246        border: none;
    … …  
    11771292}
    11781293
     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. */
     1297table.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
    11791316/* Declared even though it is the default: a column may state `align: 'left'`
    11801317   explicitly, and a class that renders with no rule behind it is the failure
    … …  
    11911328.wpshelf-cell--center {
    11921329        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);
    11931352}
    11941353
    … …  
    18942053        font-size: var(--wpshelf-text-sm);
    18952054        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;
    18962064}
    18972065
    … …  
    23992567}
    24002568
     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
    24012583.wpshelf-field > input:focus,
    24022584.wpshelf-field > textarea:focus,
    … …  
    25272709        font-size: var(--wpshelf-text-sm);
    25282710        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);
    25292771}
    25302772
    … …  
    27542996        }
    27552997}
     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  
    1515        let request;
    1616        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');
    1723        const text = (tag, value, className) => {
    1824                const node = document.createElement(tag);
    … …  
    107113        }
    108114
     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
    109124        function tableControls(root) {
    110125                for (const table of root.querySelectorAll(
    … …  
    124139                        let sort = -1;
    125140                        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;
    126145                        const toolbar = document.createElement('div');
    127146                        toolbar.className = 'wpshelf-filters';
     147                        toolbar.hidden = !searchable;
    128148                        const search = document.createElement('input');
    129149                        search.type = 'search';
    … …  
    133153                        const summary = text('span', '', 'wpshelf-footnote');
    134154                        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);
    137165                        const pager = document.createElement('div');
    138166                        pager.className = 'wpshelf-pager';
    … …  
    141169                        previous.type = next.type = 'button';
    142170                        pager.append(previous, next);
    143                         table.after(pager);
     171                        anchor.after(pager);
    144172                        const headers = [...table.tHead.rows[0].cells];
     173                        const glyphs = [];
    145174                        function draw() {
    146175                                const terms = search.value
    … …  
    157186                                        matching.sort(
    158187                                                (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 || ''
    163191                                                        ) * direction
    164192                                        );
    … …  
    172200                                        table.tBodies[0].append(row);
    173201                                });
    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                                                : '';
    175206                                previous.disabled = page <= 1;
    176207                                next.disabled = page >= pages;
    … …  
    186217                                        )
    187218                                );
     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                                });
    188227                        }
    189228                        headers.forEach((header, index) => {
    … …  
    193232                                )
    194233                                        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.
    195236                                const button = text(
    196237                                        'button',
    197                                         `${header.textContent} ↕`,
     238                                        header.textContent.trim(),
    198239                                        'wpshelf-table__sort'
    199240                                );
     241                                const glyph = text('span', '↕', 'wpshelf-table__sort-glyph');
     242                                glyph.setAttribute('aria-hidden', 'true');
     243                                button.append(glyph);
     244                                glyphs.push([index, glyph]);
    200245                                button.type = 'button';
    201246                                header.replaceChildren(button);
    … …  
    225270        }
    226271
    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) {
    229315                const cleanups = [];
    230                 let submission;
    231316                for (const init of modules.values()) {
    232317                        const cleanup = init(root);
    233318                        if (typeof cleanup === 'function') cleanups.push(cleanup);
    234319                }
     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;
    235340                tableControls(root);
    236341                const submit = async (event) => {
    … …  
    270375                        submission = new AbortController();
    271376                        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');
    272383                        try {
    273384                                await render(url.href, root, {
    … …  
    277388                                        history: true,
    278389                                });
     390                                settle(root);
    279391                        } catch (error) {
    280392                                if (error.name === 'AbortError') return;
    281393                                // 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
    288396                                );
     397                                root.prepend(notice);
     398                                notice.focus();
    289399                        } finally {
    290400                                delete form.dataset.shelfSubmitting;
    291401                                root.removeAttribute('aria-busy');
     402                                pressed?.removeAttribute('aria-disabled');
     403                                pressed?.classList.remove('wpshelf-is-saving');
    292404                        }
    293405                };
    … …  
    312424                root.addEventListener('change', change);
    313425                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);
    323427        }
    324428
    … …  
    417521                tableControls,
    418522                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,
    419527        };
     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
    420553        if (labels.standalone) {
    421554                document.addEventListener('click', (event) => {
    … …  
    448581                        if (currentUrl !== location.href) navigate(location.href, true);
    449582                });
    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                 };
    460583                if (document.readyState !== 'complete')
    461584                        window.addEventListener('load', boot, { once: true });
    462585                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();
    463596        }
    464597})();
  • gloty/tags/1.64.0/vendor/wp-shelf/platform/src/AdminAssets.php

    r3723648 r3748411  
    4545 * cards computed `border: none`.
    4646 *
    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.
    5766 *
    5867 * The class API is a different matter and cannot be fixed this way — the winning
    … …  
    149158         * stylesheet for a day with a one-year max-age.
    150159         *
    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.
    153165         *
    154166         * @param string $fallback Used when the file cannot be stat'd.
    … …  
    156168         */
    157169        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 );
    160183
    161184                return false !== $mtime ? (string) $mtime : $fallback;
    … …  
    201224
    202225        /**
    203          * The most recently modified of a list of paths.
     226         * The newest of a list of copies: highest revision stamp, then latest mtime.
    204227         *
    205228         * Split out from the glob so it can be tested: the decision is the part with
    … …  
    208231         * mid-update whose file is briefly gone cannot win by being unstat-able.
    209232         *
     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         *
    210240         * @param list<string> $paths Absolute paths, any of which may not exist.
    211241         *
    … …  
    213243         */
    214244        private static function newest( array $paths ): string {
    215                 $best  = '';
    216                 $mtime = -1;
     245                $best     = '';
     246                $revision = -1;
     247                $mtime    = -1;
    217248
    218249                foreach ( $paths as $path ) {
    … …  
    221252                        }
    222253
    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;
    228264                        }
    229265                }
    230266
    231267                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 ];
    232306        }
    233307
  • gloty/tags/1.64.0/vendor/wp-shelf/platform/src/AsyncScreens.php

    r3688478 r3748411  
    4242            'next' => \__('Next', 'default'),
    4343            'loaded' => \__('Search and sort apply to the loaded rows.', 'default'),
     44            'dismiss' => \__('Dismiss this notice.', 'default'),
    4445        ], $labels));
    4546    }
  • gloty/tags/1.64.0/vendor/wp-shelf/platform/src/LicenseClient.php

    r3723648 r3748411  
    133133                        $this->store_license_key( $key );
    134134                        $this->cache_status( $response );
     135                        LicenseRefusal::clear( $this->config );
    135136                }
    136137
    … …  
    183184         * response: a licensing outage must not stop a paying customer working.
    184185         *
     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         *
    185199         * The key is tested before the server URL is resolved, and the order is the
    186200         * point. Resolving reads the server-URL option, which SnippetGrove and
    … …  
    217231                $response = ( $post['ok'] && isset( $post['data'] ) ) ? $post['data'] : null;
    218232
     233                if ( LicenseRefusal::is_refusal( $response ) ) {
     234                        LicenseRefusal::record( $this->config, $key );
     235                        \delete_transient( $this->config->status_transient );
     236                        return null;
     237                }
     238
    219239                if ( ! is_array( $response ) || empty( $response['ok'] ) ) {
    220240                        return $this->cached_status();
    … …  
    222242
    223243                $this->cache_status( $response );
     244                LicenseRefusal::clear( $this->config );
    224245
    225246                return $response;
    … …  
    368389                $this->store_license_key( '' );
    369390                \delete_transient( $this->config->status_transient );
     391                LicenseRefusal::clear( $this->config );
    370392        }
    371393
  • 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. */
    22(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 */
    1212(0,l.__)("%s / yr","gloty"),s):(0,l.sprintf)(/* translators: %s: price, e.g. $29 */ /* translators: %s: price, e.g. $29 */
    1313(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 */
    1515(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 */
    2424(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)
    2626// translators: %d is a number of minutes.
    2727return(0,l.sprintf)((0,l._n)("%d minute ago","%d minutes ago",a,"gloty"),a);const n=Math.round(a/60);if(n<24)
    … …  
    2929return(0,l.sprintf)((0,l._n)("%d hour ago","%d hours ago",n,"gloty"),n);const i=Math.round(n/24);
    3030// 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)(
     31return(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)(
    3232// translators: %s is a relative time, e.g. "2 minutes ago".
    3333// 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 */
    3636(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 */
    3939(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 */
    4343(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 */
    4747(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 */
    4848(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 */
    4949(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 */
    5050(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}
    22.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}
    22.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  
    99        {
    1010            "name": "wp-shelf/html-parser",
    11             "version": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
     11            "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
    1212            "dist": {
    1313                "type": "path",
    … …  
    4646        {
    4747            "name": "wp-shelf/platform",
    48             "version": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
     48            "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
    4949            "dist": {
    5050                "type": "path",
  • gloty/trunk/gloty.php

    r3723660 r3748411  
    44 * Plugin URI: https://wp-shelf.com/gloty
    55 * 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.63.3
     6 * Version: 1.64.0
    77 * Author: WP Shelf
    88 * Author URI: https://wp-shelf.com
    … …  
    6161 * Plugin constants.
    6262 */
    63 define( 'GLOTY_VERSION', '1.63.3' );
     63define( 'GLOTY_VERSION', '1.64.0' );
    6464define( 'GLOTY_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
    6565define( 'GLOTY_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
  • gloty/trunk/includes/API/class-admin-rest-routes.php

    r3723648 r3748411  
    19491949                                        if ( null === $status ) {
    19501950                                                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(),
    19551959                                                ] );
    19561960                                        }
    19571961                                        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,
    19621967                                        ] );
    19631968                                },
  • gloty/trunk/includes/Admin/class-admin-boot-data.php

    r3692917 r3748411  
    249249                        'serverUrl'  => $server_url,
    250250                        '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(),
    251254                ];
    252255        }
  • gloty/trunk/includes/Admin/class-issues-service.php

    r3723648 r3748411  
    179179
    180180                $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
    181208                if ( null === $status ) {
    182209                        return [
  • gloty/trunk/includes/Licensing/class-license-client.php

    r3635518 r3748411  
    2121
    2222use WpShelf\Platform\LicenseClient as PlatformLicenseClient;
     23use WpShelf\Platform\LicenseRefusal;
    2324use WpShelf\Platform\ProductConfig;
    2425
    … …  
    3940         */
    4041        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';
    4149
    4250        private static ?PlatformLicenseClient $client = null;
    … …  
    109117         */
    110118        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;
    112129        }
    113130
    … …  
    118135         */
    119136        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() );
    121161        }
    122162
  • gloty/trunk/languages/gloty.pot

    r3723648 r3748411  
    196196msgstr ""
    197197
    198 #: includes/API/class-admin-rest-routes.php:2113
    199 #: includes/API/class-admin-rest-routes.php:2150
     198#: includes/API/class-admin-rest-routes.php:2118
     199#: includes/API/class-admin-rest-routes.php:2155
    200200msgid "Email and name are required."
    201201msgstr ""
    202202
    203 #: includes/API/class-admin-rest-routes.php:2200
     203#: includes/API/class-admin-rest-routes.php:2205
    204204msgid "Could not create your license."
    205205msgstr ""
    206206
    207 #: includes/API/class-admin-rest-routes.php:2217
     207#: includes/API/class-admin-rest-routes.php:2222
    208208msgid "Could not register this site with the translator service."
    209209msgstr ""
    … …  
    358358msgstr ""
    359359
    360 #: includes/Admin/class-issues-service.php:186
     360#: includes/Admin/class-issues-service.php:195
     361msgid "License key no longer accepted"
     362msgstr ""
     363
     364#: includes/Admin/class-issues-service.php:196
     365msgid "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."
     366msgstr ""
     367
     368#: includes/Admin/class-issues-service.php:201
     369msgid "Enter the new key"
     370msgstr ""
     371
     372#: includes/Admin/class-issues-service.php:213
    361373msgid "License server is unreachable"
    362374msgstr ""
    363375
    364 #: includes/Admin/class-issues-service.php:187
     376#: includes/Admin/class-issues-service.php:214
    365377msgid "We could not check your plan status. Translations still work; this will resolve automatically when the server is reachable."
    366378msgstr ""
    367379
    368 #: includes/Admin/class-issues-service.php:202
     380#: includes/Admin/class-issues-service.php:229
    369381msgid "Character quota exceeded"
    370382msgstr ""
    371383
    372384#. translators: 1: characters used, 2: character limit
    373 #: includes/Admin/class-issues-service.php:205
     385#: includes/Admin/class-issues-service.php:232
    374386msgid "Used %1$s of %2$s characters. Dispatching is blocked until you upgrade or the period resets."
    375387msgstr ""
    376388
    377 #: includes/Admin/class-issues-service.php:210
    378 #: includes/Admin/class-issues-service.php:235
     389#: includes/Admin/class-issues-service.php:237
     390#: includes/Admin/class-issues-service.php:262
    379391msgid "Upgrade plan"
    380392msgstr ""
    381393
    382394#. translators: %d: percentage used
    383 #: includes/Admin/class-issues-service.php:225
     395#: includes/Admin/class-issues-service.php:252
    384396msgid "Character quota at %d%%"
    385397msgstr ""
    386398
    387399#. translators: 1: characters used, 2: character limit
    388 #: includes/Admin/class-issues-service.php:230
     400#: includes/Admin/class-issues-service.php:257
    389401msgid "Used %1$s of %2$s characters this billing period."
    390402msgstr ""
    391403
    392 #: includes/Admin/class-issues-service.php:245
     404#: includes/Admin/class-issues-service.php:272
    393405msgid "License expired"
    394406msgstr ""
    395407
    396 #: includes/Admin/class-issues-service.php:246
     408#: includes/Admin/class-issues-service.php:273
    397409msgid "Your subscription has expired. Renew to resume translation dispatch."
    398410msgstr ""
    399411
    400 #: includes/Admin/class-issues-service.php:251
     412#: includes/Admin/class-issues-service.php:278
    401413msgid "Manage billing"
    402414msgstr ""
    403415
    404416#. translators: %d: days remaining in the billing period
    405 #: includes/Admin/class-issues-service.php:265
     417#: includes/Admin/class-issues-service.php:292
    406418msgid "Billing period resets in %d day"
    407419msgid_plural "Billing period resets in %d days"
    … …  
    409421msgstr[1] ""
    410422
    411 #: includes/Admin/class-issues-service.php:273
     423#: includes/Admin/class-issues-service.php:300
    412424msgid "Usage will roll over automatically. No action required."
    413425msgstr ""
    414426
    415 #: includes/Admin/class-issues-service.php:321
     427#: includes/Admin/class-issues-service.php:348
    416428msgid "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."
    417429msgstr ""
    418430
    419431#. translators: %s: comma-separated list of language codes with counts, e.g. "de (1,204), sl (980)"
    420 #: includes/Admin/class-issues-service.php:329
     432#: includes/Admin/class-issues-service.php:356
    421433msgid "Most affected: %s."
    422434msgstr ""
    423435
    424436#. translators: %s: number of translations identical to their source
    425 #: includes/Admin/class-issues-service.php:340
     437#: includes/Admin/class-issues-service.php:367
    426438msgid "%s translation is identical to its source"
    427439msgid_plural "%s translations are identical to their source"
    … …  
    429441msgstr[1] ""
    430442
    431 #: includes/Admin/class-issues-service.php:360
     443#: includes/Admin/class-issues-service.php:387
    432444msgid "Show these rows"
    433445msgstr ""
    434446
    435 #: includes/Admin/class-issues-service.php:399
     447#: includes/Admin/class-issues-service.php:426
    436448msgid "Translated pages are not using the fast path"
    437449msgstr ""
    438450
    439 #: includes/Admin/class-issues-service.php:413
     451#: includes/Admin/class-issues-service.php:440
    440452msgid "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."
    441453msgstr ""
    442454
    443 #: includes/Admin/class-issues-service.php:417
     455#: includes/Admin/class-issues-service.php:444
    444456msgid "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."
    445457msgstr ""
    446458
    447 #: includes/Admin/class-issues-service.php:420
     459#: includes/Admin/class-issues-service.php:447
    448460msgid "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."
    449461msgstr ""
    450462
    451 #: includes/Admin/class-issues-service.php:423
     463#: includes/Admin/class-issues-service.php:450
    452464msgid "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."
    453465msgstr ""
    454466
    455 #: includes/Admin/class-issues-service.php:427
     467#: includes/Admin/class-issues-service.php:454
    456468msgid "Gloty could not write its translation cache file. This usually means the uploads directory is not writable by WordPress."
    457469msgstr ""
    458470
    459 #: includes/Admin/class-issues-service.php:430
     471#: includes/Admin/class-issues-service.php:457
    460472msgid "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."
    461473msgstr ""
    462474
    463 #: includes/Admin/class-issues-service.php:433
     475#: includes/Admin/class-issues-service.php:460
    464476msgid "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."
    465477msgstr ""
    466478
    467479#. translators: %d: number of stuck jobs
    468 #: includes/Admin/class-issues-service.php:469
     480#: includes/Admin/class-issues-service.php:496
    469481msgid "%d job stuck processing"
    470482msgid_plural "%d jobs stuck processing"
    … …  
    472484msgstr[1] ""
    473485
    474 #: includes/Admin/class-issues-service.php:477
     486#: includes/Admin/class-issues-service.php:504
    475487msgid "These jobs have been in the processing state for more than 10 minutes. They may be waiting on a webhook that never arrived."
    476488msgstr ""
    477489
    478 #: includes/Admin/class-issues-service.php:482
     490#: includes/Admin/class-issues-service.php:509
    479491msgid "View jobs"
    480492msgstr ""
    481493
    482494#. translators: %d: number of failed jobs
    483 #: includes/Admin/class-issues-service.php:494
     495#: includes/Admin/class-issues-service.php:521
    484496msgid "%d job failed in the last 24 hours"
    485497msgid_plural "%d jobs failed in the last 24 hours"
    … …  
    487499msgstr[1] ""
    488500
    489 #: includes/Admin/class-issues-service.php:502
     501#: includes/Admin/class-issues-service.php:529
    490502msgid "Check the sync events log to see why these jobs failed, and retry them when the root cause is fixed."
    491503msgstr ""
    492504
    493 #: includes/Admin/class-issues-service.php:507
    494 #: includes/Admin/class-issues-service.php:529
     505#: includes/Admin/class-issues-service.php:534
     506#: includes/Admin/class-issues-service.php:556
    495507msgid "Open sync screen"
    496508msgstr ""
    497509
    498 #: includes/Admin/class-issues-service.php:523
     510#: includes/Admin/class-issues-service.php:550
    499511msgid "Automatic translation is delayed"
    500512msgstr ""
    501513
    502 #: includes/Admin/class-issues-service.php:524
     514#: includes/Admin/class-issues-service.php:551
    503515msgid "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”."
    504516msgstr ""
    … …  
    868880
    869881#: src/admin/App.js:422
    870 #: src/admin/LicensePanel.js:453
     882#: src/admin/LicensePanel.js:464
    871883msgid "License key"
    872884msgstr ""
    … …  
    11721184#: src/admin/App.js:1761
    11731185#: src/admin/DesignSystemScreen.js:518
    1174 #: src/admin/LicensePanel.js:468
     1186#: src/admin/LicensePanel.js:479
    11751187#: src/admin/SyncScreen.js:480
    11761188#: src/admin/SyncScreen.js:938
    … …  
    17341746#: src/admin/DesignSystemScreen.js:146
    17351747#: src/admin/HealthPill.js:24
    1736 #: src/admin/LicensePanel.js:591
     1748#: src/admin/LicensePanel.js:602
    17371749msgid "Checking…"
    17381750msgstr ""
    … …  
    23152327msgstr ""
    23162328
    2317 #: src/admin/LicensePanel.js:179
     2329#: src/admin/LicensePanel.js:188
    23182330msgid "License provisioned and activated."
    23192331msgstr ""
    23202332
    2321 #: src/admin/LicensePanel.js:186
    2322 #: src/admin/LicensePanel.js:192
     2333#: src/admin/LicensePanel.js:195
     2334#: src/admin/LicensePanel.js:201
    23232335msgid "Provisioning failed."
    23242336msgstr ""
    23252337
    2326 #: src/admin/LicensePanel.js:218
     2338#: src/admin/LicensePanel.js:228
    23272339msgid "License activated."
    23282340msgstr ""
    23292341
    2330 #: src/admin/LicensePanel.js:224
    2331 #: src/admin/LicensePanel.js:230
     2342#: src/admin/LicensePanel.js:234
     2343#: src/admin/LicensePanel.js:240
    23322344msgid "Activation failed."
    23332345msgstr ""
    23342346
    2335 #: src/admin/LicensePanel.js:249
     2347#: src/admin/LicensePanel.js:260
    23362348msgid "License deactivated."
    23372349msgstr ""
    23382350
    2339 #: src/admin/LicensePanel.js:254
     2351#: src/admin/LicensePanel.js:265
    23402352msgid "Deactivation failed."
    23412353msgstr ""
    23422354
    2343 #: src/admin/LicensePanel.js:296
     2355#: src/admin/LicensePanel.js:307
    23442356msgid "No billing portal is available for this license — there’s no Stripe subscription to manage. This is normal for free or manually-granted plans."
    23452357msgstr ""
    23462358
    2347 #: src/admin/LicensePanel.js:305
     2359#: src/admin/LicensePanel.js:316
    23482360msgid "Could not open the billing portal."
    23492361msgstr ""
    23502362
    2351 #: src/admin/LicensePanel.js:333
     2363#: src/admin/LicensePanel.js:344
    23522364msgid "License"
    23532365msgstr ""
    23542366
    2355 #: src/admin/LicensePanel.js:352
     2367#: src/admin/LicensePanel.js:363
    23562368msgid "Get started with Gloty translation credits, or enter an existing license key."
    23572369msgstr ""
    23582370
    2359 #: src/admin/LicensePanel.js:375
     2371#: src/admin/LicensePanel.js:386
    23602372msgid "Get Started"
    23612373msgstr ""
    23622374
    2363 #: src/admin/LicensePanel.js:386
     2375#: src/admin/LicensePanel.js:397
    23642376msgid "I have a license key"
    23652377msgstr ""
    23662378
    2367 #: src/admin/LicensePanel.js:394
     2379#: src/admin/LicensePanel.js:405
    23682380msgid "Email"
    23692381msgstr ""
    23702382
    2371 #: src/admin/LicensePanel.js:403
     2383#: src/admin/LicensePanel.js:414
    23722384msgid "Name"
    23732385msgstr ""
    23742386
    2375 #: src/admin/LicensePanel.js:419
     2387#: src/admin/LicensePanel.js:430
    23762388msgid "Get Free License"
    23772389msgstr ""
    23782390
    2379 #: src/admin/LicensePanel.js:428
     2391#: src/admin/LicensePanel.js:439
    23802392msgid "License Key"
    23812393msgstr ""
    23822394
    2383 #: src/admin/LicensePanel.js:441
     2395#: src/admin/LicensePanel.js:452
     2396#: src/admin/LicensePanel.js:691
    23842397msgid "Activate"
    23852398msgstr ""
    23862399
    2387 #: src/admin/LicensePanel.js:462
     2400#: src/admin/LicensePanel.js:473
    23882401msgid "Plan"
    23892402msgstr ""
    23902403
    2391 #: src/admin/LicensePanel.js:474
     2404#: src/admin/LicensePanel.js:485
    23922405msgid "Sites"
    23932406msgstr ""
    23942407
    2395 #: src/admin/LicensePanel.js:482
     2408#: src/admin/LicensePanel.js:493
    23962409msgid "Usage"
    23972410msgstr ""
    23982411
    2399 #: src/admin/LicensePanel.js:494
     2412#: src/admin/LicensePanel.js:505
    24002413msgid "You’re approaching your monthly limit. Translation pauses at 100% until the limit resets or you upgrade — existing translations keep serving."
    24012414msgstr ""
    24022415
    2403 #: src/admin/LicensePanel.js:498
     2416#: src/admin/LicensePanel.js:509
    24042417msgid "Translation pauses when you reach your monthly limit, then resumes after it resets or you upgrade. Already-stored translations always keep serving."
    24052418msgstr ""
    24062419
    2407 #: src/admin/LicensePanel.js:507
     2420#: src/admin/LicensePanel.js:518
    24082421msgid "Resets"
    24092422msgstr ""
    24102423
    2411 #: src/admin/LicensePanel.js:520
    2412 #: src/admin/LicensePanel.js:557
     2424#: src/admin/LicensePanel.js:531
     2425#: src/admin/LicensePanel.js:568
    24132426msgid "Upgrade"
    24142427msgstr ""
    24152428
    2416 #: src/admin/LicensePanel.js:537
     2429#: src/admin/LicensePanel.js:548
    24172430msgid "1 site"
    24182431msgstr ""
    24192432
    24202433#. translators: %d: number of sites
    2421 #: src/admin/LicensePanel.js:540
     2434#: src/admin/LicensePanel.js:551
    24222435msgid "Up to %d sites"
    24232436msgstr ""
    24242437
    2425 #: src/admin/LicensePanel.js:558
     2438#: src/admin/LicensePanel.js:569
    24262439msgid "Buy"
    24272440msgstr ""
    24282441
    2429 #: src/admin/LicensePanel.js:580
     2442#: src/admin/LicensePanel.js:591
    24302443msgid "Manage Subscription"
    24312444msgstr ""
    24322445
    2433 #: src/admin/LicensePanel.js:592
     2446#: src/admin/LicensePanel.js:603
    24342447msgid "Refresh status"
    24352448msgstr ""
    24362449
    2437 #: src/admin/LicensePanel.js:600
    2438 #: src/admin/LicensePanel.js:619
     2450#: src/admin/LicensePanel.js:611
     2451#: src/admin/LicensePanel.js:630
    24392452msgid "Deactivate"
    24402453msgstr ""
    24412454
    2442 #: src/admin/LicensePanel.js:604
     2455#: src/admin/LicensePanel.js:615
    24432456msgid "Deactivating frees this license for another site. Your translations stay in place — nothing is deleted."
    24442457msgstr ""
    24452458
    2446 #: src/admin/LicensePanel.js:614
     2459#: src/admin/LicensePanel.js:625
    24472460msgid "Deactivate license on this site?"
    24482461msgstr ""
    24492462
    2450 #: src/admin/LicensePanel.js:615
     2463#: src/admin/LicensePanel.js:626
    24512464msgid "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."
    24522465msgstr ""
    24532466
    2454 #: src/admin/LicensePanel.js:639
     2467#: src/admin/LicensePanel.js:656
     2468msgid "This license key is no longer accepted."
     2469msgstr ""
     2470
     2471#: src/admin/LicensePanel.js:663
     2472msgid "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."
     2473msgstr ""
     2474
     2475#: src/admin/LicensePanel.js:672
     2476msgid "Open your WP Shelf licenses"
     2477msgstr ""
     2478
     2479#: src/admin/LicensePanel.js:678
     2480msgid "Replacement license key"
     2481msgstr ""
     2482
     2483#: src/admin/LicensePanel.js:706
    24552484msgid "License key is configured but the license server could not be reached."
    24562485msgstr ""
    24572486
    2458 #: src/admin/LicensePanel.js:652
     2487#: src/admin/LicensePanel.js:719
    24592488msgid "Retrying…"
    24602489msgstr ""
    24612490
    2462 #: src/admin/LicensePanel.js:653
     2491#: src/admin/LicensePanel.js:720
    24632492#: src/admin/SyncScreen.js:991
    24642493msgid "Retry"
    … …  
    34833512#. translators: %s: a number of views.
    34843513#: src/admin/TrendChart.js:340
     3514msgctxt "tooltip readout"
    34853515msgid "%s views"
    34863516msgstr ""
  • gloty/trunk/package.json

    r3723660 r3748411  
    11{
    22  "name": "@wp-shelf/gloty",
    3   "version": "1.63.3",
     3  "version": "1.64.0",
    44  "description": "Gloty - AI-powered translation plugin for WordPress.",
    55  "private": true,
  • gloty/trunk/readme.txt

    r3723660 r3748411  
    55Tested up to: 7.1
    66Requires PHP: 8.1
    7 Stable tag: 1.63.3
     7Stable tag: 1.64.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    196196== Changelog ==
    197197
     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
    198202= 1.63.3 =
    199203* 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  
    313313}
    314314
    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. */
     322table.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);
    317327        font-size: var(--wpshelf-text-sm);
    318328        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;
    320332}
    321333
    … …  
    384396}
    385397
     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
    386411/* Declared even though it is the default: a column may state `align: 'left'`
    387412   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  
    1414} from '@wordpress/element';
    1515import { 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.
     19const collator = new Intl.Collator(undefined, {
     20        numeric: true,
     21        sensitivity: 'base',
     22});
    1623
    1724export function tableText(node) {
    … …  
    109116                matching.sort(
    110117                        (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])
    117121                                ) * sort.direction
    118122                );
  • gloty/trunk/shared-js/design-system/src/style.css

    r3688478 r3748411  
    9797        color: var(--wpshelf-ink-soft);
    9898}
     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  
    148148 * @return {number} Comparator result.
    149149 */
     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 */
     159const collator = new Intl.Collator(undefined, {
     160        numeric: true,
     161        sensitivity: 'base',
     162});
     163
    150164export function compareRows(a, b, column, direction) {
    151165        const pick = column.sortValue ? column.sortValue : (row) => row[column.key];
    … …  
    161175        }
    162176
    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;
    169178}
    170179
  • gloty/trunk/src/admin/LicensePanel.js

    r3723648 r3748411  
    8888        const [hasKey, setHasKey] = useState(boot?.license?.hasKey || false);
    8989        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        );
    9098        const [busy, setBusy] = useState(false);
    9199        const [refreshing, setRefreshing] = useState(false);
    … …  
    123131                        setHasKey(res?.has_key || false);
    124132                        setStatus(res?.status || null);
     133                        setKeyRefused(res?.key_refused || false);
    125134                        if (res?.key_masked) {
    126135                                setKeyMasked(res.key_masked);
    … …  
    213222                        if (res?.ok) {
    214223                                setHasKey(true);
     224                                setKeyRefused(false);
    215225                                setKeyInput('');
    216226                                setNotice({
    … …  
    245255                        setHasKey(false);
    246256                        setStatus(null);
     257                        setKeyRefused(false);
    247258                        setNotice({
    248259                                status: 'info',
    … …  
    627638                                )}
    628639
    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 && (
    630697                                        <p className="wpshelf-muted">
    631698                                                {keyMasked && (
  • gloty/trunk/src/admin/style.css

    r3723648 r3748411  
    340340 * Below the wp-admin breakpoint the sidebar stacks above the content.
    341341 *
    342  * It used to be hidden outright, and the reason given was that "the plugin's own
    343  * submenu is still in the wp-admin menu, so a second copy of the same links
     342 * 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
    344344 * above the content is noise". That stopped being true the moment every plugin
    345345 * became a single entry under WP Shelf: this sidebar is now the only way to
    … …  
    525525
    526526/* 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. */
    528529@media (prefers-reduced-motion: reduce) {
    529530
    … …  
    17461747}
    17471748
    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. */
    17491751.wpshelf-chart__grid {
    17501752        stroke: var(--wpshelf-line);
    … …  
    17581760}
    17591761
    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. */
    17611764.wpshelf-chart__area {
    17621765        fill: var(--wpshelf-accent);
    … …  
    17721775}
    17731776
    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. */
    17751779.wpshelf-chart__peak {
    17761780        fill: var(--wpshelf-ink);
  • gloty/trunk/vendor/composer/autoload_classmap.php

    r3723648 r3748411  
    142142    'WpShelf\\Platform\\FormMarkup' => $vendorDir . '/wp-shelf/platform/src/FormMarkup.php',
    143143    'WpShelf\\Platform\\LicenseClient' => $vendorDir . '/wp-shelf/platform/src/LicenseClient.php',
     144    'WpShelf\\Platform\\LicenseRefusal' => $vendorDir . '/wp-shelf/platform/src/LicenseRefusal.php',
    144145    'WpShelf\\Platform\\LicenseTransport' => $vendorDir . '/wp-shelf/platform/src/LicenseTransport.php',
    145146    'WpShelf\\Platform\\Pager' => $vendorDir . '/wp-shelf/platform/src/Pager.php',
  • gloty/trunk/vendor/composer/autoload_static.php

    r3723648 r3748411  
    170170        'WpShelf\\Platform\\FormMarkup' => __DIR__ . '/..' . '/wp-shelf/platform/src/FormMarkup.php',
    171171        'WpShelf\\Platform\\LicenseClient' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseClient.php',
     172        'WpShelf\\Platform\\LicenseRefusal' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseRefusal.php',
    172173        'WpShelf\\Platform\\LicenseTransport' => __DIR__ . '/..' . '/wp-shelf/platform/src/LicenseTransport.php',
    173174        'WpShelf\\Platform\\Pager' => __DIR__ . '/..' . '/wp-shelf/platform/src/Pager.php',
  • gloty/trunk/vendor/composer/installed.json

    r3723660 r3748411  
    33        {
    44            "name": "wp-shelf/html-parser",
    5             "version": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
    6             "version_normalized": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
     5            "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
     6            "version_normalized": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
    77            "dist": {
    88                "type": "path",
    … …  
    4343        {
    4444            "name": "wp-shelf/platform",
    45             "version": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
    46             "version_normalized": "dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd",
     45            "version": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
     46            "version_normalized": "dev-6e5e1992bdcd2740c8e706d59d229784889aec50",
    4747            "dist": {
    4848                "type": "path",
  • gloty/trunk/vendor/composer/installed.php

    r3723660 r3748411  
    22    'root' => array(
    33        'name' => 'wp-shelf/gloty',
    4         'pretty_version' => 'dev-main',
    5         'version' => 'dev-main',
    6         'reference' => '635a6dd92d2f2eb2936e79cfea23c4635ea223eb',
     4        'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     5        'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     6        'reference' => '6e5e1992bdcd2740c8e706d59d229784889aec50',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
    … …  
    1212    'versions' => array(
    1313        'wp-shelf/gloty' => array(
    14             'pretty_version' => 'dev-main',
    15             'version' => 'dev-main',
    16             'reference' => '635a6dd92d2f2eb2936e79cfea23c4635ea223eb',
     14            'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     15            'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     16            'reference' => '6e5e1992bdcd2740c8e706d59d229784889aec50',
    1717            'type' => 'wordpress-plugin',
    1818            'install_path' => __DIR__ . '/../../',
    … …  
    2121        ),
    2222        'wp-shelf/html-parser' => array(
    23             'pretty_version' => 'dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd',
    24             'version' => 'dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd',
     23            'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     24            'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
    2525            'reference' => '1c4b68cd06da61ac60b52a4a2bf25ec4cf160ca4',
    2626            'type' => 'library',
    … …  
    3030        ),
    3131        'wp-shelf/platform' => array(
    32             'pretty_version' => 'dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd',
    33             'version' => 'dev-e4bedc789bed392c81e083a5b22d932d6a8fecdd',
     32            'pretty_version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
     33            'version' => 'dev-6e5e1992bdcd2740c8e706d59d229784889aec50',
    3434            'reference' => '1a5dd36e91615be4855bc9481ba9bacf32bb18c8',
    3535            'type' => 'library',
  • gloty/trunk/vendor/wp-shelf/platform/assets/admin.css

    r3723648 r3748411  
    492492        }
    493493
     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         */
    494499        .wpshelf-sidebar {
    495500                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;
    496518        }
    497519}
    … …  
    627649/* ---- Content region ---- */
    628650.wpshelf-tab-content {
     651        position: relative;
    629652        background: transparent;
    630653        border: 0;
    … …  
    632655        margin-top: 0;
    633656        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        }
    634721}
    635722
    … …  
    821908}
    822909
    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,
     930table.wpshelf-table > thead > tr > th {
    825931        padding: var(--wpshelf-cell-pad-y) var(--wpshelf-cell-pad-x);
    826932        border-bottom: 1px solid var(--wpshelf-line);
    … …  
    829935        font-size: var(--wpshelf-text-sm);
    830936        font-weight: var(--wpshelf-weight-medium);
     937        line-height: var(--wpshelf-leading-snug);
     938        overflow-wrap: break-word;
    831939}
    832940
    … …  
    9781086   ───────────────────────────────────────────────────────────────────────── */
    9791087
     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. */
    9801091.wpshelf-table {
    9811092        max-width: var(--wpshelf-measure);
     1093        border-spacing: 0;
    9821094}
    9831095
    … …  
    11281240        align-items: center;
    11291241        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;
    11301245        padding: 0;
    11311246        border: none;
    … …  
    11771292}
    11781293
     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. */
     1297table.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
    11791316/* Declared even though it is the default: a column may state `align: 'left'`
    11801317   explicitly, and a class that renders with no rule behind it is the failure
    … …  
    11911328.wpshelf-cell--center {
    11921329        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);
    11931352}
    11941353
    … …  
    18942053        font-size: var(--wpshelf-text-sm);
    18952054        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;
    18962064}
    18972065
    … …  
    23992567}
    24002568
     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
    24012583.wpshelf-field > input:focus,
    24022584.wpshelf-field > textarea:focus,
    … …  
    25272709        font-size: var(--wpshelf-text-sm);
    25282710        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);
    25292771}
    25302772
    … …  
    27542996        }
    27552997}
     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  
    1515        let request;
    1616        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');
    1723        const text = (tag, value, className) => {
    1824                const node = document.createElement(tag);
    … …  
    107113        }
    108114
     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
    109124        function tableControls(root) {
    110125                for (const table of root.querySelectorAll(
    … …  
    124139                        let sort = -1;
    125140                        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;
    126145                        const toolbar = document.createElement('div');
    127146                        toolbar.className = 'wpshelf-filters';
     147                        toolbar.hidden = !searchable;
    128148                        const search = document.createElement('input');
    129149                        search.type = 'search';
    … …  
    133153                        const summary = text('span', '', 'wpshelf-footnote');
    134154                        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);
    137165                        const pager = document.createElement('div');
    138166                        pager.className = 'wpshelf-pager';
    … …  
    141169                        previous.type = next.type = 'button';
    142170                        pager.append(previous, next);
    143                         table.after(pager);
     171                        anchor.after(pager);
    144172                        const headers = [...table.tHead.rows[0].cells];
     173                        const glyphs = [];
    145174                        function draw() {
    146175                                const terms = search.value
    … …  
    157186                                        matching.sort(
    158187                                                (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 || ''
    163191                                                        ) * direction
    164192                                        );
    … …  
    172200                                        table.tBodies[0].append(row);
    173201                                });
    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                                                : '';
    175206                                previous.disabled = page <= 1;
    176207                                next.disabled = page >= pages;
    … …  
    186217                                        )
    187218                                );
     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                                });
    188227                        }
    189228                        headers.forEach((header, index) => {
    … …  
    193232                                )
    194233                                        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.
    195236                                const button = text(
    196237                                        'button',
    197                                         `${header.textContent} ↕`,
     238                                        header.textContent.trim(),
    198239                                        'wpshelf-table__sort'
    199240                                );
     241                                const glyph = text('span', '↕', 'wpshelf-table__sort-glyph');
     242                                glyph.setAttribute('aria-hidden', 'true');
     243                                button.append(glyph);
     244                                glyphs.push([index, glyph]);
    200245                                button.type = 'button';
    201246                                header.replaceChildren(button);
    … …  
    225270        }
    226271
    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) {
    229315                const cleanups = [];
    230                 let submission;
    231316                for (const init of modules.values()) {
    232317                        const cleanup = init(root);
    233318                        if (typeof cleanup === 'function') cleanups.push(cleanup);
    234319                }
     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;
    235340                tableControls(root);
    236341                const submit = async (event) => {
    … …  
    270375                        submission = new AbortController();
    271376                        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');
    272383                        try {
    273384                                await render(url.href, root, {
    … …  
    277388                                        history: true,
    278389                                });
     390                                settle(root);
    279391                        } catch (error) {
    280392                                if (error.name === 'AbortError') return;
    281393                                // 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
    288396                                );
     397                                root.prepend(notice);
     398                                notice.focus();
    289399                        } finally {
    290400                                delete form.dataset.shelfSubmitting;
    291401                                root.removeAttribute('aria-busy');
     402                                pressed?.removeAttribute('aria-disabled');
     403                                pressed?.classList.remove('wpshelf-is-saving');
    292404                        }
    293405                };
    … …  
    312424                root.addEventListener('change', change);
    313425                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);
    323427        }
    324428
    … …  
    417521                tableControls,
    418522                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,
    419527        };
     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
    420553        if (labels.standalone) {
    421554                document.addEventListener('click', (event) => {
    … …  
    448581                        if (currentUrl !== location.href) navigate(location.href, true);
    449582                });
    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                 };
    460583                if (document.readyState !== 'complete')
    461584                        window.addEventListener('load', boot, { once: true });
    462585                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();
    463596        }
    464597})();
  • gloty/trunk/vendor/wp-shelf/platform/src/AdminAssets.php

    r3723648 r3748411  
    4545 * cards computed `border: none`.
    4646 *
    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.
    5766 *
    5867 * The class API is a different matter and cannot be fixed this way — the winning
    … …  
    149158         * stylesheet for a day with a one-year max-age.
    150159         *
    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.
    153165         *
    154166         * @param string $fallback Used when the file cannot be stat'd.
    … …  
    156168         */
    157169        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 );
    160183
    161184                return false !== $mtime ? (string) $mtime : $fallback;
    … …  
    201224
    202225        /**
    203          * The most recently modified of a list of paths.
     226         * The newest of a list of copies: highest revision stamp, then latest mtime.
    204227         *
    205228         * Split out from the glob so it can be tested: the decision is the part with
    … …  
    208231         * mid-update whose file is briefly gone cannot win by being unstat-able.
    209232         *
     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         *
    210240         * @param list<string> $paths Absolute paths, any of which may not exist.
    211241         *
    … …  
    213243         */
    214244        private static function newest( array $paths ): string {
    215                 $best  = '';
    216                 $mtime = -1;
     245                $best     = '';
     246                $revision = -1;
     247                $mtime    = -1;
    217248
    218249                foreach ( $paths as $path ) {
    … …  
    221252                        }
    222253
    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;
    228264                        }
    229265                }
    230266
    231267                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 ];
    232306        }
    233307
  • gloty/trunk/vendor/wp-shelf/platform/src/AsyncScreens.php

    r3688478 r3748411  
    4242            'next' => \__('Next', 'default'),
    4343            'loaded' => \__('Search and sort apply to the loaded rows.', 'default'),
     44            'dismiss' => \__('Dismiss this notice.', 'default'),
    4445        ], $labels));
    4546    }
  • gloty/trunk/vendor/wp-shelf/platform/src/LicenseClient.php

    r3723648 r3748411  
    133133                        $this->store_license_key( $key );
    134134                        $this->cache_status( $response );
     135                        LicenseRefusal::clear( $this->config );
    135136                }
    136137
    … …  
    183184         * response: a licensing outage must not stop a paying customer working.
    184185         *
     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         *
    185199         * The key is tested before the server URL is resolved, and the order is the
    186200         * point. Resolving reads the server-URL option, which SnippetGrove and
    … …  
    217231                $response = ( $post['ok'] && isset( $post['data'] ) ) ? $post['data'] : null;
    218232
     233                if ( LicenseRefusal::is_refusal( $response ) ) {
     234                        LicenseRefusal::record( $this->config, $key );
     235                        \delete_transient( $this->config->status_transient );
     236                        return null;
     237                }
     238
    219239                if ( ! is_array( $response ) || empty( $response['ok'] ) ) {
    220240                        return $this->cached_status();
    … …  
    222242
    223243                $this->cache_status( $response );
     244                LicenseRefusal::clear( $this->config );
    224245
    225246                return $response;
    … …  
    368389                $this->store_license_key( '' );
    369390                \delete_transient( $this->config->status_transient );
     391                LicenseRefusal::clear( $this->config );
    370392        }
    371393
Note: See TracChangeset for help on using the changeset viewer.