{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "password-strength",
  "type": "registry:ui",
  "title": "PasswordStrength",
  "description": "قدرت رمز عبور با نوار چهارقسمتی و فهرست شرط‌ها؛ زیر فیلد رمز بگذارید و با id به آن وصل کنید",
  "dependencies": [
    "@kashi-ui/persian@^1.8.0"
  ],
  "registryDependencies": [
    "https://kashi.sepantapouya.com/r/cx.json",
    "https://kashi.sepantapouya.com/r/kashi-provider.json"
  ],
  "files": [
    {
      "path": "registry/kashi/PasswordStrength.tsx",
      "type": "registry:ui",
      "target": "components/kashi/PasswordStrength.tsx",
      "content": "\"use client\";\n\nimport { faMessages, toFaDigits, type KashiMessages } from \"@kashi-ui/persian\";\nimport { cx } from \"./cx\";\nimport { useKashi } from \"./KashiProvider\";\n\nexport interface PasswordRule {\n  label: string;\n  test: (password: string) => boolean;\n}\n\n/** شرط‌های پیش‌فرض با متن‌های زبان فعلی */\nconst rulesFor = (m: KashiMessages[\"password\"], n: (v: number) => string): PasswordRule[] => [\n  { label: m.length(n(8)), test: (p) => p.length >= 8 },\n  { label: m.cases, test: (p) => /[a-z]/.test(p) && /[A-Z]/.test(p) },\n  { label: m.digit, test: (p) => /\\d/.test(p) },\n  { label: m.symbol, test: (p) => /[^A-Za-z0-9\\s؀-ۿ]/.test(p) },\n];\n\n/** شرط‌های پیش‌فرض به فارسی؛ بدون rules، کامپوننت همین‌ها را به زبان KashiProvider نشان می‌دهد */\nexport const defaultPasswordRules: PasswordRule[] = rulesFor(faMessages.password, (v) => toFaDigits(v));\n\nexport interface PasswordStrengthProps {\n  password: string;\n  rules?: PasswordRule[];\n  /** نمایش فهرست شرط‌ها @default true */\n  showRules?: boolean;\n  /** هشدار وقتی رمز حروف فارسی دارد (صفحه‌کلید فارسی مانده) @default true */\n  warnPersian?: boolean;\n  /** شناسهٔ این بخش، برای aria-describedby فیلد رمز */\n  id?: string;\n  className?: string;\n  labels?: { title?: string; levels?: [string, string, string, string]; persian?: string };\n}\n\nconst Check = () => <svg viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"m5 10.5 3.2 3L15 7\" /></svg>;\nconst Dot = () => <svg viewBox=\"0 0 20 20\" aria-hidden=\"true\"><circle cx=\"10\" cy=\"10\" r=\"2.5\" fill=\"currentColor\" /></svg>;\n\n/** قدرت رمز عبور با نوار چهارقسمتی و فهرست شرط‌ها؛ زیر فیلد رمز بگذارید و با id به آن وصل کنید */\nexport function PasswordStrength({ password, rules, showRules = true, warnPersian = true, id, className, labels = {} }: PasswordStrengthProps) {\n  const { messages: M, n: N } = useKashi();\n  rules ??= rulesFor(M.password, N);\n  const { title = M.password.title, levels = M.password.levels, persian = M.password.persian } = labels;\n  const met = rules.map((r) => r.test(password));\n  const n = met.filter(Boolean).length;\n  // امتیاز ۰ تا ۴ به نسبت شرط‌های برآورده‌شده\n  const score = password ? Math.max(1, Math.round((n / rules.length) * 4)) : 0;\n  const persianTyped = warnPersian && /[؀-ۿ]/.test(password);\n  return (\n    <div id={id} className={cx(\"k-strength\", className)} data-score={score}>\n      <div className=\"k-strength__bars\" aria-hidden=\"true\">\n        {[0, 1, 2, 3].map((i) => <span key={i} className=\"k-strength__bar\" />)}\n      </div>\n      <p className=\"k-strength__label\" aria-live=\"polite\" style={{ margin: 0 }}>\n        {score > 0 && <>{title}: <strong>{levels[score - 1]}</strong></>}\n      </p>\n      {persianTyped && <p className=\"k-hint k-hint--error\" role=\"alert\">{persian}</p>}\n      {showRules && (\n        <ul className=\"k-strength__rules\">\n          {rules.map((r, i) => (\n            <li key={r.label} className=\"k-strength__rule\" data-met={met[i] ? \"\" : undefined}>\n              {met[i] ? <Check /> : <Dot />}\n              <span>{r.label}<span className=\"k-sr-only\">{met[i] ? M.password.met : M.password.unmet}</span></span>\n            </li>\n          ))}\n        </ul>\n      )}\n    </div>\n  );\n}\n"
    }
  ]
}