[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 2\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto\n\n* vue eol=lf encoding=UTF-8\n*.css eol=lf encoding=UTF-8\n*.html eol=lf encoding=UTF-8\n*.js eol=lf encoding=UTF-8\n*.jsx eol=lf encoding=UTF-8\n*.md eol=lf encoding=UTF-8\n*.scss eol=lf encoding=UTF-8\n*.ts eol=lf encoding=UTF-8\n*.tsx eol=lf encoding=UTF-8\n*.txt eol=lf encoding=UTF-8\n*.xml eol=lf encoding=UTF-8\n\n# Images\n*.gif binary\n*.ico binary\n*.jpg binary\n*.png binary\n*.svg eol=lf encoding=UTF-8\n*.webp binary\n\n# Fonts\n*.eot binary\n*.otf binary\n*.ttf binary\n*.woff binary\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "# Generated by CODEOWNERS.com\n\n"
  },
  {
    "path": ".github/copilot-instructions.md",
    "content": "# Vue-CodeMirror6 Workspace Instructions\n\n**Project**: A Vue 2 & 3 compatible CodeMirror 6 component library\n**Tech Stack**: TypeScript, Vue 3 (with vue-demi for Vue 2 support), Vite, Vitest, CodeMirror 6\n**Language**: Primarily TypeScript with Vue SFC components\n\n## Essential Commands\n\n| Task                   | Command                                            |\n| ---------------------- | -------------------------------------------------- |\n| **Development server** | `pnpm dev`                                         |\n| **Build library**      | `pnpm build` (includes type checking)              |\n| **Build docs**         | `pnpm build:docs` then `pnpm preview`              |\n| **Run tests**          | `pnpm test` (watch mode) or `pnpm test:run` (once) |\n| **Test coverage**      | `pnpm test:coverage`                               |\n| **All linting**        | `pnpm lint` (oxlint, eslint, prettier)             |\n| **Type check**         | `pnpm type-check` (vue-tsc)                        |\n\n## Architecture & Key Patterns\n\n### Main Component (`src/index.ts`, `src/Meta.ts`)\n\n- **Vue Composition API** with `vue-demi` for Vue 2/3 compatibility\n- **Core Props**: `modelValue`, `lang`, `extensions`, `linter`, `keymap`, `dark`, `readonly`, `disabled`, etc.\n- **Exposed Methods**: `getView()`, `focus()`, `getRange()`, `setCursor()`, `getSelection()` (CodeMirror5 API compatibility layer)\n- **Event Emitters**: `ready`, `update`, `change`, `destroy`\n- **Two Setup Modes**: `basic` (basicSetup) or `minimal` (minimalSetup)\n\n### Design Principles\n\n1. **Unidirectional + v-model binding**: Text content updates flow via v-model\n2. **Optional ChainING on `view.value`**: All CodeMirror view access uses `view.value?.` to handle SSR\n3. **Props over Extensions**: Explicit props (`lang`, `linter`, `keymap`) separate from generic `extensions[]` for better type safety and DX\n4. **Lazy Initialization**: Editor only initializes in browser (client-side), SSR-safe with `onMounted` checks\n\n### Testing Strategy (`src/__tests__/`)\n\n- **`CodeMirror.spec.ts`**: Component functionality (rendering, props, v-model, events, slots, public methods)\n- **`CodeMirror.ssr.spec.ts`**: SSR compatibility (server-side rendering, safe method calls, hydration, cleanup)\n- **Framework**: Vitest with happy-dom environment\n- **Setup**: Uses Vue Test Utils for component mounting\n- **Coverage Targets**: All public methods and critical code paths (see vitest.config.ts for exclusions)\n\n## Code Quality Standards\n\n### Linting & Formatting\n\n- **Oxlint**: Fast, Rust-based linting (primary)\n- **ESLint**: Vue plugin + TypeScript rules + accessibility checks\n- **Prettier**: Code formatting\n- **vue-tsc**: Type checking before build\n\nRun all checks: `pnpm lint` (automatically fixes most issues)\n\n### TypeScript\n\n- **Strict Mode**: Enabled\n- **Vue Support**: `@vue/eslint-config-typescript`\n- **Type Declarations**: Auto-generated via `vite-plugin-dts` during build\n- **Aliases**: `@` → `src/`, `vue-codemirror6` → `src/`\n\n## Important Context\n\n### SSR Compatibility (Critical)\n\nThe component must work in SSR environments (Nuxt.js, etc.):\n\n- `view.value` may be `undefined` on server ⚠️\n- Always use optional chaining: `view.value?.method()`\n- Browser-only code wrapped in `if (typeof window !== 'undefined')`\n- See [SSR_FIX_SUMMARY.md](../SSR_FIX_SUMMARY.md) for detailed changes\n\n### Build Outputs\n\n### Generated Metadata\n\n- `src/Meta.ts` is generated automatically when starting the dev server or running the library build.\n- If `src/Meta.ts` is missing in a fresh checkout, run `pnpm dev` or `pnpm build` before treating it as a broken import.\n\nMultiple formats in `dist/`:\n\n- ES modules: `index.es.js`\n- CommonJS: `index.cjs.js`\n- UMD: `index.umd.js`\n- IIFE: `index.iife.js`\n- Types: `index.d.ts`\n\n### Peer Dependencies\n\nCodeMirror 6 packages are peer deps (not bundled):\n\n```text\n@codemirror/{commands,language,lint,search,state,view}\n@codemirror/autocomplete\ncodemirror (state/view core)\nstyle-mod\nvue: ^2.7.14 || ^3.3.4\n```\n\nUsers must install these separately to avoid duplication.\n\n### Common Development Tasks\n\n**Adding a new prop**: Add to interface → component props → applicable compartment/state → test it\n\n**Adding language support demo**: Add to `src-docs/components/` and import in `App.vue`\n\n**Fixing a bug**: Create test first in `__tests__/`, implement fix in `src/`, verify with `pnpm test`\n\n**Updating themes or extensions**: Use the `extensions` prop or create a helper function in `src/helpers/`\n\n## Key Files Reference\n\n| File                                                                            | Purpose                                         |\n| ------------------------------------------------------------------------------- | ----------------------------------------------- |\n| [src/index.ts](../src/index.ts)                                                 | Main component definition                       |\n| [src/Meta.ts](../src/Meta.ts)                                                   | Component metadata and type definitions         |\n| [src/**tests**/CodeMirror.spec.ts](../src/__tests__/CodeMirror.spec.ts)         | Component tests                                 |\n| [src/**tests**/CodeMirror.ssr.spec.ts](../src/__tests__/CodeMirror.ssr.spec.ts) | SSR tests                                       |\n| [vite.config.ts](../vite.config.ts)                                             | Build config (outputs, plugins, DTS generation) |\n| [vitest.config.ts](../vitest.config.ts)                                         | Test config (happy-dom, coverage)               |\n| [eslint.config.ts](../eslint.config.ts)                                         | Linting config                                  |\n\n## Common Pitfalls to Avoid\n\n1. **Direct `view` access without optional chaining** → SSR will break\n2. **Importing `@codemirror` modules in component** → May cause bundling issues; prefer `extensions` prop\n3. **Mutating props directly** → Use emitted events or expose methods instead\n4. **Async state changes without `nextTick`** → Can cause race conditions in updates\n5. **Forgetting to test SSR mode** → Use `pnpm test` to run all tests including SSR\n\n## Workspace Conventions\n\n- **Vue 3 syntax throughout** (vue-demi handles Vue 2 compatibility)\n- **TypeScript strict mode**\n- **Composition API only** (no Options API)\n- **Kebab-case for component props** (auto-converted from camelCase)\n- **PascalCase for type names**, camelCase for variables/functions\n- **Comments for complex CodeMirror API usage** (document non-obvious patterns)\n"
  },
  {
    "path": ".github/workflows/build-docs.yml",
    "content": "name: NodeJS with Vite\n\non:\n  push:\n    branches: ['master']\n  pull_request:\n    branches: ['master']\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node-version: [22.x]\n\n    steps:\n      - name: Checkout ✅\n        uses: actions/checkout@v4.2.2\n\n      - name: Use Node.js ${{ matrix.node-version }} ⚡\n        uses: actions/setup-node@v4.1.0\n        with:\n          node-version: ${{ matrix.node-version }}\n\n      - name: Install pnpm 🎁\n        uses: pnpm/action-setup@v4\n\n      - name: Build 🔧\n        run: |\n          pnpm install\n          pnpm run build:docs\n\n      - name: Deploy to gh-pages 🚀\n        uses: JamesIves/github-pages-deploy-action@v4.6.8\n        with:\n          branch: gh-pages # The branch the action should deploy to.\n          folder: docs # The folder the action should deploy.\n"
  },
  {
    "path": ".gitignore",
    "content": "/.yarn/*\n# !/.yarn/patches\n# !/.yarn/plugins\n!/.yarn/releases\n# !/.yarn/sdks\n# !/.yarn/cache\n/.vscode/*\nnode_modules\n.DS_Store\ndist\ndist-ssr\n*.local\n/src/Meta.ts\ndocs/\nstats.html\n*.tsbuildinfo\n"
  },
  {
    "path": ".nvmrc",
    "content": "24.14.1\n"
  },
  {
    "path": ".oxlintrc.json",
    "content": "{\n  \"$schema\": \"./node_modules/oxlint/configuration_schema.json\",\n  \"plugins\": [\"eslint\", \"typescript\", \"unicorn\", \"oxc\", \"vue\"],\n  \"env\": {\n    \"browser\": true\n  },\n  \"categories\": {\n    \"correctness\": \"error\"\n  }\n}\n"
  },
  {
    "path": ".prettierignore",
    "content": ".husky/\n.vscode/\n.yarn/\ndist/\npublic/assets/\ndocs/\nstats.html\n"
  },
  {
    "path": ".prettierrc.yaml",
    "content": "printWidth: 80\ntabWidth: 2\nuseTabs: false\nsemi: true\nsingleQuote: true\ntrailingComma: es5\nbracketSpacing: true\nbracketSameLine: false\narrowParens: avoid\nhtmlWhitespaceSensitivity: ignore\nendOfLine: lf\n"
  },
  {
    "path": "AGENT.md",
    "content": "# AGENT.md\n\nThis file provides guidance for AI coding agents (GitHub Copilot, Claude, Cursor, etc.) working in this repository.\n\n---\n\n## Project Overview\n\nCodeMirror component for Vue2 and Vue3.\n\n- **Framework**: Vue 3 (`<script setup>` SFC only)\n- **Build tool**: Vite 8\n- **Language**: TypeScript (strict)\n- **Package manager**: pnpm (do not use npm or yarn)\n- **Node version**: `^20.19.0 || >=22.12.0`\n\n---\n\n## Commands\n\n```bash\npnpm dev              # Start dev server (http://localhost:5173)\npnpm build            # Type-check + production build\npnpm lint             # Run all linters (oxlint → eslint → prettier → stylelint)\npnpm type-check       # vue-tsc type check only\npnpm test:unit        # Vitest unit tests\npnpm test:coverage    # Vitest with coverage report\npnpm test:e2e         # Playwright E2E tests\npnpm build:analyze    # Bundle size analysis (rollup-plugin-visualizer)\npnpm clean            # Clear Vite dev cache\n```\n\nAlways run `pnpm lint` and `pnpm type-check` before committing. These are also enforced by husky pre-commit hooks via lint-staged.\n\n---\n\n## TypeScript Rules\n\n- **No `any`** — use `unknown` and narrow with type guards.\n- **Explicit return types** on exported functions (Pinia stores are exempt due to setup-style inference).\n- **Use `type` over `interface`** for object shapes; extend via intersection (`&`).\n- **Union literal types** instead of magic strings:\n  ```ts\n  type Status = 'active' | 'inactive' | 'pending';\n  ```\n- **Underscore prefix** for intentionally unused variables: `_value`, `_error`.\n- **Array type syntax**: `string[]` not `Array<string>`.\n- **Generic constructors**: left-hand side style — `const map: Map<string, User> = new Map()`.\n\n---\n\n## Vue SFC Rules\n\n### Script\n\n- Always use `<script setup lang=\"ts\">` — Options API is prohibited.\n- `defineProps` and `defineEmits` must use **type-based declarations** (runtime declarations are prohibited):\n\n  ```ts\n  // OK\n  const props = defineProps<{ title: string; count?: number }>();\n  const emit = defineEmits<{ change: [value: string]; close: [] }>();\n\n  // NG\n  const props = defineProps({ title: String });\n  ```\n\n- Return values from composables as individual `ref`s (not `reactive`) to enable destructuring.\n- Internal state exposed from composables should be wrapped in `readonly()`.\n\n### Template\n\n- **Self-closing void elements**: `<br />`, `<img />`, `<input />`.\n- **Attribute order** (enforced by `vue/attributes-order`):\n  `DEFINITION` → `LIST_RENDERING` → `CONDITIONALS` → `RENDER_MODIFIERS` → `UNIQUE` → `TWO_WAY_BINDING` → `OTHER_DIRECTIVES` → `ATTR_DYNAMIC` → `ATTR_STATIC` → `ATTR_SHORTHAND_BOOL` → `EVENTS` → `CONTENT`\n- Run `pnpm lint` to auto-fix attribute order.\n\n### Style\n\n- Always use `<style lang=\"scss\" scoped>` — unscoped styles are prohibited.\n- CSS custom properties (design tokens) must be defined in a shared file (e.g., `src/styles/variables.scss`) and not duplicated per component.\n- CSS property order is enforced by stylelint-order — run `pnpm lint:style` to auto-fix.\n\n---\n\n## Component Naming\n\n- Component files: **PascalCase**, multi-word required (e.g., `UserCard.vue`, `AppHeader.vue`).\n  - `src/components/**/*.vue` — `error`\n  - `src/pages/**/*.vue` and `src/layouts/**/*.vue` — `warn` (file-based routing constraint)\n- Do not create single-word components like `Header.vue` or `Card.vue` outside of pages/layouts.\n\n---\n\n## Import Rules\n\n- **Always use the `@/` alias** for internal imports — relative parent traversal (`../`) is prohibited in application code:\n\n  ```ts\n  // OK\n  import { useUserStore } from '@/stores/user';\n  import type { User } from '@/types';\n\n  // NG\n  import { useUserStore } from '../../../stores/user';\n  ```\n\n  > **Exception**: test files under `src/**/__tests__/` may use `../` to import the component under test (e.g., `import MyComponent from '../MyComponent.vue'`). This is intentional and the ESLint rule is disabled for that scope.\n\n- The `~` alias maps to `node_modules` (e.g., `~/some-lib/style.css`).\n- **Import order** (enforced by `import-x/order`, auto-fixed by `pnpm lint:eslint`):\n  1. Node built-ins\n  2. Vue core (`vue`, `vue-router`, `pinia`, `@vue/*`, `@vitejs/*`)\n  3. External packages\n  4. Internal (`@/**`)\n  5. Sibling / index\n  6. Type imports\n     A blank line is required between each group.\n\n---\n\n## Pinia Store Rules\n\n- Use **setup-store style** exclusively (not options-store style):\n  ```ts\n  // OK\n  export const useUserStore = defineStore('user', () => {\n    const user = ref<User | null>(null);\n    function setUser(u: User) {\n      user.value = u;\n    }\n    return { user, setUser };\n  });\n  ```\n- Store ID must match the file name (e.g., `defineStore('user', ...)` in `stores/user.ts`).\n- Persist state via `pinia-plugin-persistedstate` — do not manually read/write `localStorage`.\n\n---\n\n## Accessibility (a11y)\n\nRules are enforced by `eslint-plugin-vuejs-accessibility`. Key points:\n\n- `<a>` elements must have text content (`vuejs-accessibility/anchor-has-content: error`).\n- Avoid `autofocus` (`vuejs-accessibility/no-autofocus: warn`).\n- For **single input** → use `<label for=\"id\">` or nesting.\n- For **compound UI** (e.g., slider + number input sharing a label) → use `aria-labelledby` or `<fieldset>` + `<legend>`:\n\n  ```vue\n  <!-- Compound: aria-labelledby -->\n  <p id=\"volume-label\">Volume</p>\n  <input type=\"range\" v-model=\"volume\" aria-labelledby=\"volume-label\" />\n  <input type=\"number\" v-model=\"volume\" aria-labelledby=\"volume-label\" />\n\n  <!-- Or: fieldset + legend -->\n  <fieldset>\n    <legend>Volume</legend>\n    <input type=\"range\" v-model=\"volume\" />\n    <input type=\"number\" v-model=\"volume\" />\n  </fieldset>\n  ```\n\n- `vuejs-accessibility/label-has-for` is set to `warn` for compound UI patterns. When disabling intentionally, add a description comment (required by `eslint-comments/require-description`):\n  ```vue\n  <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -- compound slider+input UI -->\n  ```\n\n---\n\n## ESLint Disable Policy\n\n`eslint-comments/require-description` is set to `error`. Every `eslint-disable` comment **must** include a reason:\n\n```ts\n// OK\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- third-party type gap, no @types available\n\n// NG\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n```\n\n---\n\n## Testing\n\n### Unit tests (Vitest)\n\n- Test files: `src/**/__tests__/*.ts`\n- Follow **Arrange / Act / Assert** structure.\n- Mock external dependencies (API, DB, browser APIs) — tests must not make real network calls.\n- Coverage threshold: **80%** lines and functions (enforced in CI).\n\n### E2E tests (Playwright)\n\n- Test files: `e2e/**/*.{test,spec}.{js,ts}`\n- Test user-visible behavior, not implementation details.\n\n---\n\n## Git & PR Rules\n\n- Commit messages follow **Conventional Commits**:\n  ```\n  feat(auth): add JWT refresh token rotation\n  fix(api): handle 429 rate limit with exponential backoff\n  docs: update README setup instructions\n  ```\n- PRs should be focused on a single purpose; aim for diffs under ~400 lines.\n- Minimum **1 approving review** required before merging to `master`.\n- PR description must include: what changed, how to test, and screenshots if UI is affected.\n\n---\n\n## Environment Variables\n\n- All client-side env vars must be prefixed with `VITE_APP_`:\n  ```\n  VITE_APP_TITLE=My App\n  VITE_APP_API_BASE_URL=https://api.example.com\n  ```\n- Copy `.env.example` to `.env` before running the dev server.\n- Never commit `.env` — it is in `.gitignore`.\n- Access via `import.meta.env.VITE_APP_*` (typed in `env.d.ts`).\n\n---\n\n## What NOT to Do\n\n- Do not use `any` — use `unknown` with type guards.\n- Do not use Options API (`defineComponent`, `data()`, `methods:`).\n- Do not use runtime `defineProps({ title: String })` declarations.\n- Do not write `../` relative imports that traverse parent directories (exception: `src/**/__tests__/` may use `../` to reach the component under test).\n- Do not use `<style>` without `scoped`.\n- Do not write bare `localStorage` / `sessionStorage` access — use `pinia-plugin-persistedstate`.\n- Do not add `eslint-disable` comments without a description.\n- Do not install packages with `npm` or `yarn` — use `pnpm` only.\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "### Changelog\n\nAll notable changes to this project will be documented in this file. Dates are displayed in UTC.\n\nGenerated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).\n\n#### [1.5.2](https://github.com/logue/vue-codemirror6.git/compare/1.5.1...1.5.2)\n\n- Add AGENT.md. [`5514bf3`](https://github.com/logue/vue-codemirror6.git/commit/5514bf3664c4d1f5fdab926449780079362bc03b)\n- Vulnerability response [`461d0b1`](https://github.com/logue/vue-codemirror6.git/commit/461d0b1e82c49088ffb0775310f01b2fb63b991c)\n- Update dependencies. [`c8ef924`](https://github.com/logue/vue-codemirror6.git/commit/c8ef9247ec878390640c050c7e499ef508091354)\n\n#### [1.5.1](https://github.com/logue/vue-codemirror6.gitcompare/1.5.0...1.5.1)\n\n> 3 April 2026\n\n- Fixed index.d.ts path. [`eed7df2`](https://github.com/logue/vue-codemirror6.git/commit/eed7df2e5dfc2310415e4b6c9e1f1a9cb3e32b3f)\n\n#### [1.5.0](https://github.com/logue/vue-codemirror6.git/compare/1.4.3...1.5.0)\n\n> 30 March 2026\n\n- Add AI instructions. [`75fecba`](https://github.com/logue/vue-codemirror6.git/commit/75fecba1d79bbd308864dbbfb5884026c1c20be6)\n- Fixed warnings output during the build process. [`4721a8d`](https://github.com/logue/vue-codemirror6.git/commit/4721a8d94faf0a32c5a7b2459f989e361acb0a27)\n- Update Dependencies. [`c8c3d2a`](https://github.com/logue/vue-codemirror6.git/commit/c8c3d2a23ef8eecc6ab28d42d53bdc7f457ceac5)\n\n#### [1.4.3](https://github.com/logue/vue-codemirror6.git/compare/1.4.2...1.4.3)\n\n> 5 March 2026\n\n- Replace eslint-plugin-import to eslint-plugin-x. [`e46491a`](https://github.com/logue/vue-codemirror6.git/commit/e46491a24270f8ea392a3354bbecbaf7092f8ef9)\n- Add Japanese Readme. [`e279cc0`](https://github.com/logue/vue-codemirror6.git/commit/e279cc0e1b23bba6c1dd690fb6a963b82e8508f6)\n- Update ChangeLog/ [`8648633`](https://github.com/logue/vue-codemirror6.git/commit/86486330c50af4c4c13eeabcc3b6a498ab8a65d1)\n\n#### [1.4.2](https://github.com/logue/vue-codemirror6.git/compare/1.4.0...1.4.2)\n\n> 17 February 2026\n\n- Move the contents of Codemirror.ts to index.ts. [`d9a624b`](https://github.com/logue/vue-codemirror6.git/commit/d9a624bbe61034b2a5abe553b0e362818ea8e91b)\n- Fixed dark mode in demo program. [`dd54015`](https://github.com/logue/vue-codemirror6.git/commit/dd54015c8ebb11cf24dd8d5b38e1e35e00ed56b5)\n- Add oxilint. [`abb115e`](https://github.com/logue/vue-codemirror6.git/commit/abb115edd0bcafd641c4a7b35af566bdb1630334)\n\n#### [1.4.0](https://github.com/logue/vue-codemirror6.gi/compare/1.3.13...1.4.0)\n\n> 17 October 2025\n\n- fix: full example link [`#58`](https://github.com/logue/vue-codemirror6.git/pull/58)\n- Update dependencies. [`985f36f`](https://github.com/logue/vue-codemirror6.git/commit/985f36f23c4fc1b562b53b664deb7ff1eec79989)\n- Reviewed dependencies. Moved them to peerDependencies and relaxed the version requirements. [`1ffab22`](https://github.com/logue/vue-codemirror6.git/commit/1ffab224a4274e142449e74abc71a988f6ad8d1c)\n- Update vue, codemirror. [`bfbd153`](https://github.com/logue/vue-codemirror6.git/commit/bfbd153eeec6c718b95bb719117ad5a02dcf6a37)\n\n#### [1.3.13](https://github.com/logue/vue-codemirror6.git/compare/1.3.8...1.3.13)\n\n> 31 March 2025\n\n- Rewrite to eslint.config.ts [`841f686`](https://github.com/logue/vue-codemirror6.git/commit/841f686ebab5f542a5b7bc1569660ce58a21af65)\n- Fixed types path. [`2b86b2c`](https://github.com/logue/vue-codemirror6.git/commit/2b86b2c4da906f4591e13221e5c41e52b8792523)\n- Update @codemirror/language, @codemirror/lint, @codemirror/state, @codemirror/view. [`916fa98`](https://github.com/logue/vue-codemirror6.git/commit/916fa9899e7c3806199f53bddb210d3cba9e7517)\n\n#### [1.3.8](https://github.com/logue/vue-codemirror6.git/compare/1.1.16...1.3.8)\n\n> 22 November 2024\n\n- Fix sample code syntax error [`#47`](https://github.com/logue/vue-codemirror6.git/pull/47)\n- chore: demo docs [`#43`](https://github.com/logue/vue-codemirror6.git/pull/43)\n- fix: editor not update content when `modelValue` change and selection is out of range [`#44`](https://github.com/logue/vue-codemirror6.git/pull/44)\n- chore: props and readme doc [`#31`](https://github.com/logue/vue-codemirror6.git/pull/31)\n- Reduce unnecessary updates [`#22`](https://github.com/logue/vue-codemirror6.git/pull/22)\n- fix: coalescing-operator [`#20`](https://github.com/logue/vue-codemirror6.git/pull/20)\n- Migrate to pnpm. [`6d83aec`](https://github.com/logue/vue-codemirror6.git/commit/6d83aec625d50228cbfb248bc5811b6f83975219)\n- Update dependencies. [`992f209`](https://github.com/logue/vue-codemirror6.git/commit/992f209c5e4c269b72be119f693b0d0376d529bb)\n- Update dependencies. [`b839a33`](https://github.com/logue/vue-codemirror6.git/commit/b839a33569fadf3a9bb5e2a8f972c377fc1fce88)\n\n#### [1.1.16](https://github.com/logue/vue-codemirror6.git/compare/1.1.13...1.1.16)\n\n> 18 March 2023\n\n- Expose `view`. #16 [`daf3e6b`](https://github.com/logue/vue-codemirror6.git/commit/daf3e6b17a161a5c0c5a35ea2442d85421f05d82)\n- Fixed Maximum call stack size exceeded error. [`f10eaae`](https://github.com/logue/vue-codemirror6.git/commit/f10eaaea9145bc1d7a6605ab3cb8a82c0ca12df6)\n- Partially fixed the problem that the values defined in props disappeared under certain conditions. [`1cc4468`](https://github.com/logue/vue-codemirror6.git/commit/1cc4468e35e39ee8eaae1b2f007e3425a757217f)\n\n#### [1.1.13](https://github.com/logue/vue-codemirror6.git/compare/1.1.12...1.1.13)\n\n> 13 March 2023\n\n- Changed minimum Vue version requirement to 2.7.14. [`5b8b255`](https://github.com/logue/vue-codemirror6.git/commit/5b8b2558967f9fb6f6d9e83a0181afa50f182b98)\n- Add allow-multiple-selections prop. [`ced91ed`](https://github.com/logue/vue-codemirror6.git/commit/ced91edab8fc25f8f1299341489f6bbbdace9ce8)\n- Update CHANGELOG.md [`51d30e2`](https://github.com/logue/vue-codemirror6.git/commit/51d30e2f6370847ef888ab2b39ff6e1c8e3ec851)\n\n#### [1.1.12](https://github.com/logue/vue-codemirror6.git/compare/1.1.11...1.1.12)\n\n> 10 March 2023\n\n- chore(CODEOWNERS): CODEOWNERS.com Bot, at your service! [`#14`](https://github.com/logue/vue-codemirror6.git/pull/14)\n- Update demo code. (Replaced @codemirror/html to @codemirror/vue.) [`8da1a8a`](https://github.com/logue/vue-codemirror6.git/commit/8da1a8a4e37d713cc78281ce9c304c42a06940dc)\n- Changed implementation to generate \\*.d.ts with vite-plugin-dts. [`1caaa20`](https://github.com/logue/vue-codemirror6.git/commit/1caaa20b1423a3d252a6c770a630fb60e2e3440d)\n- Update README.md. [`f8dd493`](https://github.com/logue/vue-codemirror6.git/commit/f8dd4934a7b9cc089cd830473db5250d28b3389b)\n\n#### [1.1.11](https://github.com/logue/vue-codemirror6.git/compare/1.1.3...1.1.11)\n\n> 4 February 2023\n\n- [SECURITY FIX] CWE-1333: Inefficient Regular Expression Complexity #13 [`fc63a9f`](https://github.com/logue/vue-codemirror6.git/commit/fc63a9f14b5307089e9551157b011072971b112f)\n- Fix for #11 [`c634b55`](https://github.com/logue/vue-codemirror6.git/commit/c634b555ffff93bb30da2f501ec366289fc86ec1)\n- Add forceReconfigure() function. [`bbfa8ad`](https://github.com/logue/vue-codemirror6.git/commit/bbfa8adb5bd5cdb56a53bd69337a4e0313e52033)\n\n#### [1.1.3](https://github.com/logue/vue-codemirror6.git/compare/1.1.2...1.1.3)\n\n> 9 January 2023\n\n- Bump json5 from 1.0.1 to 1.0.2 [`#10`](https://github.com/logue/vue-codemirror6.git/pull/10)\n- Consolidated demo code generation settings into a single vite.config.ts [`7fe3ad2`](https://github.com/logue/vue-codemirror6.git/commit/7fe3ad25676eb34844b7bfe64b5dc73f30211a5b)\n- Update dependencies. [`75b984e`](https://github.com/logue/vue-codemirror6.git/commit/75b984e38c13114ce30b853fba64493c55368be3)\n\n#### [1.1.2](https://github.com/logue/vue-codemirror6.git/compare/1.1.1...1.1.2)\n\n> 24 December 2022\n\n- Update CHANGELOG.md. [`72efba5`](https://github.com/logue/vue-codemirror6.git/commit/72efba5e9e272da2dcb3bd941079ee415d1b4c53)\n- Minor fix. [`d1e3118`](https://github.com/logue/vue-codemirror6.git/commit/d1e3118ca2f2efe4d63f64e505d8a01a7c29a104)\n- Update dependencies. [`d747a21`](https://github.com/logue/vue-codemirror6.git/commit/d747a21778b42ed12921dd468a91a910895925e8)\n\n#### [1.1.1](https://github.com/logue/vue-codemirror6.git/compare/1.1.0...1.1.1)\n\n> 7 November 2022\n\n- Fixed Markdown demo. [`399f32c`](https://github.com/logue/vue-codemirror6.git/commit/399f32c95440b24c253110670d46811673cf38bd)\n- Fix cross-binding not works. [`137765b`](https://github.com/logue/vue-codemirror6.git/commit/137765b23c0b27ba3c4784d0708ee7172c94083a)\n- Fixed taking URL class from other than node when building docs. [`fbf1d56`](https://github.com/logue/vue-codemirror6.git/commit/fbf1d56296b4b739b7ff84107ec33eb3681a0398)\n\n#### [1.1.0](https://github.com/logue/vue-codemirror6.git/compare/1.0.3...1.1.0)\n\n> 31 October 2022\n\n- Rewrite the demo code with Vue3 setup. [`fdc7e3c`](https://github.com/logue/vue-codemirror6.git/commit/fdc7e3c172ff8f1710a74459b1ed7da70420b732)\n- Fixed wrong typing of computed value. [`9b5a572`](https://github.com/logue/vue-codemirror6.git/commit/9b5a572c5a18bfd3cf9cd5f4c0b0866efab9e893)\n- Add CHANGELOG.md. [`1de388f`](https://github.com/logue/vue-codemirror6.git/commit/1de388f5126a6afeaec250adefc82bc709251bbd)\n\n#### [1.0.3](https://github.com/logue/vue-codemirror6.git/compare/1.0.2...1.0.3)\n\n> 12 October 2022\n\n- Update dependencies. [`7f096da`](https://github.com/logue/vue-codemirror6.git/commit/7f096da24bfc50c9f2932cac6ad023d3982281bf)\n- Update demo code. [`ac33441`](https://github.com/logue/vue-codemirror6.git/commit/ac33441c2886664c11a91b5b838db74220f0b565)\n- Fixed vite.config.docs.ts. [`b13628a`](https://github.com/logue/vue-codemirror6.git/commit/b13628aeaa29df6c525b899776ae7706cdf800bc)\n\n#### [1.0.2](https://github.com/logue/vue-codemirror6.git/compare/1.0.1...1.0.2)\n\n> 15 September 2022\n\n- Enabled to specify HTML tags used in components. [`9b9eecd`](https://github.com/logue/vue-codemirror6.git/commit/9b9eecdb4da434295bf176c4c17d832871aba927)\n\n#### [1.0.1](https://github.com/logue/vue-codemirror6.git/compare/1.0.0...1.0.1)\n\n> 8 September 2022\n\n- Update dependencies. [`f3631d0`](https://github.com/logue/vue-codemirror6.git/commit/f3631d0c3c00a07ba8e69916116db1d611397fb9)\n- Disable drop console. [`e27b9ef`](https://github.com/logue/vue-codemirror6.git/commit/e27b9efea75180b3c6031c8e3a06c2bd5cee228b)\n\n### [1.0.0](https://github.com/logue/vue-codemirror6.git/compare/0.6.8...1.0.0)\n\n> 20 August 2022\n\n- Fixed editable and readonly toggle. [`97ac1bf`](https://github.com/logue/vue-codemirror6.git/commit/97ac1bf8b24775daefb58af91c318771ea355c8d)\n- 1.0 [`4493c74`](https://github.com/logue/vue-codemirror6.git/commit/4493c744d38002fbca943f43b14985a3ae2c592c)\n\n#### [0.6.8](https://github.com/logue/vue-codemirror6.git/compare/0.6.5...0.6.8)\n\n> 1 August 2022\n\n- Unify props monitoring process. [`15b8a17`](https://github.com/logue/vue-codemirror6.git/commit/15b8a171cec652a03800fc9b53c9f3c5b78f74bf)\n- Fixed an error around linter. [`b2fe3db`](https://github.com/logue/vue-codemirror6.git/commit/b2fe3dba9f6edd3167edeeff08f34139e444ecd7)\n- Fixed dispatch may be executed multiple times when the value of prop is changed. [`2e19316`](https://github.com/logue/vue-codemirror6.git/commit/2e193168876e7e0da06695e68176433fd328c0b7)\n\n#### [0.6.5](https://github.com/logue/vue-codemirror6.git/compare/0.6.4...0.6.5)\n\n> 4 July 2022\n\n- Remove banner from source code. [`043e0ed`](https://github.com/logue/vue-codemirror6.git/commit/043e0ed0769c0b3bf52777e0d64199e713377418)\n- Delete unnecessary cursor movement processing and assignment processing. [`c89fd00`](https://github.com/logue/vue-codemirror6.git/commit/c89fd0020e241dca2d8292511a2b55ffbece5a82)\n\n#### [0.6.4](https://github.com/logue/vue-codemirror6.git/compare/0.6.0...0.6.4)\n\n> 28 June 2022\n\n- Fixed a bug that the cursor may move to a strange place when inputting. [`9977976`](https://github.com/logue/vue-codemirror6.git/commit/9977976678fda8a268a5c998f6bb95bdf0b86a1e)\n- Changed the logic when assigning text values to CodeMirror. [`313e701`](https://github.com/logue/vue-codemirror6.git/commit/313e70196573f9365519a7558cbc0f05c193a000)\n- Fixed the problem that the definition file was omitted because the binary output by analyze was given to npm. [`503a52e`](https://github.com/logue/vue-codemirror6.git/commit/503a52ef7c5077241b72909ee27afb262b52312e)\n\n#### [0.6.0](https://github.com/logue/vue-codemirror6.git/compare/0.5.5...0.6.0)\n\n> 9 June 2022\n\n- Added minimal prop. [`d454d25`](https://github.com/logue/vue-codemirror6.git/commit/d454d257c1fd04b765f5fdb555b240395fe030b5)\n- Migrate to CodeMirror 6.0.0. [`50cb696`](https://github.com/logue/vue-codemirror6.git/commit/50cb696dcc3af61d77a7e74ef37041d20bfb71fc)\n- Add methods jsdoc and manual. [`44975eb`](https://github.com/logue/vue-codemirror6.git/commit/44975ebedf76d1179ab2c1835e9f16b8e583a64a)\n\n#### [0.5.5](https://github.com/logue/vue-codemirror6.git/compare/0.5.4...0.5.5)\n\n> 8 June 2022\n\n- Urgent release. [`7db9007`](https://github.com/logue/vue-codemirror6.git/commit/7db9007886b5daeea94f7986d256291911b7a55c)\n\n#### [0.5.4](https://github.com/logue/vue-codemirror6.git/compare/0.5.3...0.5.4)\n\n> 31 May 2022\n\n- Fixed a bug that the cursor goes to a strange place when inputting. [`81af5b2`](https://github.com/logue/vue-codemirror6.git/commit/81af5b2e950cd972bfe540621fb75a6a8e18d544)\n\n#### [0.5.3](https://github.com/logue/vue-codemirror6.git/compare/0.5.2...0.5.3)\n\n> 31 May 2022\n\n- Fixed an issue where parent-to-child binding did not work properly. [`d355f2c`](https://github.com/logue/vue-codemirror6.git/commit/d355f2c7de4437360fdbf021029506d6cce4adba)\n- Changed the implementation to call the extension directly with a function. [`98d338f`](https://github.com/logue/vue-codemirror6.git/commit/98d338f05a48922529f15f9d706f9614447ff1cb)\n- The initial value of linter is set to simple undefined. [`6cec8b0`](https://github.com/logue/vue-codemirror6.git/commit/6cec8b000ce18a44a4077c375285a45df2993931)\n\n#### [0.5.2](https://github.com/logue/vue-codemirror6.git/compare/0.5.1...0.5.2)\n\n> 30 May 2022\n\n- Simplify extension processing. [`cd875ff`](https://github.com/logue/vue-codemirror6.git/commit/cd875ffdeffa072c6abb5b4e3964298bd490b582)\n- Since lintGutter is displayed even for components for which linter is not specified, lintGutter is made an option. [`ab16cbb`](https://github.com/logue/vue-codemirror6.git/commit/ab16cbb1472a5b29c572279a303a4baa593f4eb3)\n- Fixed innerText is undefined error. [`6466784`](https://github.com/logue/vue-codemirror6.git/commit/64667849779d0511a472cf8d116ecef8e51f1db8)\n\n#### [0.5.1](https://github.com/logue/vue-codemirror6.git/compare/0.5.0...0.5.1)\n\n> 28 May 2022\n\n- Fixed linter bug. [`03013b4`](https://github.com/logue/vue-codemirror6.git/commit/03013b44ce89ba455acafaceac68b2084fe364cf)\n\n#### [0.5.0](https://github.com/logue/vue-codemirror6.git/compare/0.3.7...0.5.0)\n\n> 27 May 2022\n\n- The output program is compatible with both Vue2 and Vue3.☺ [`7571423`](https://github.com/logue/vue-codemirror6.git/commit/7571423b0b4f6150300b184b3fc765cb3bf2e21b)\n\n#### [0.3.7](https://github.com/logue/vue-codemirror6.git/compare/0.3.6...0.3.7)\n\n> 26 May 2022\n\n- Change the formatting settings. [`42188a5`](https://github.com/logue/vue-codemirror6.git/commit/42188a5de4ddf1163789cdc2fbd255ed19487fad)\n- Update documents. [`5a78106`](https://github.com/logue/vue-codemirror6.git/commit/5a7810681c786020afdac8f5d8da8d15f8ad802c)\n- Update docs. [`15d7f8e`](https://github.com/logue/vue-codemirror6.git/commit/15d7f8e7e1edda995420485160cb9cfd4980fe74)\n\n#### [0.3.6](https://github.com/logue/vue-codemirror6.git/compare/0.3.2...0.3.6)\n\n> 19 May 2022\n\n- Rename serve.vue to DemoPage.vue. [`3ba582b`](https://github.com/logue/vue-codemirror6.git/commit/3ba582b6fa24259b49d1f123b79db185ab7e077a)\n- Fixed an issue where CodeMirror may not work properly during initial display. [`8092b64`](https://github.com/logue/vue-codemirror6.git/commit/8092b64039e9a3340624ca4e347151609c933a12)\n- Add basic and tab props. [`54eace6`](https://github.com/logue/vue-codemirror6.git/commit/54eace641678967163fdf93d051181f701167e0e)\n\n#### [0.3.2](https://github.com/logue/vue-codemirror6.git/compare/0.3.0...0.3.2)\n\n> 6 April 2022\n\n- When building with vue3, it doesn't work with vue2, so build with vue2. [`87be702`](https://github.com/logue/vue-codemirror6.git/commit/87be702b278df9cf0f5b26bb8307f7a6d592fd73)\n- Rewrite the wrapper part. [`1e77661`](https://github.com/logue/vue-codemirror6.git/commit/1e776619bb5f711a789bbe758d10142725de39aa)\n- Update sample. [`f7ed0a5`](https://github.com/logue/vue-codemirror6.git/commit/f7ed0a507175b6c0d79cf6be55fbd317c5c999b6)\n\n#### [0.3.0](https://github.com/logue/vue-codemirror6.git/compare/0.1.7...0.3.0)\n\n> 29 March 2022\n\n#### [0.1.7](https://github.com/logue/vue-codemirror6.git/compare/0.1.6...0.1.7)\n\n> 26 May 2022\n\n- Change Lint settings. [`89558c1`](https://github.com/logue/vue-codemirror6.git/commit/89558c1ad3a11bc5bd4ee55a11d6bd58022c99eb)\n\n#### [0.1.6](https://github.com/logue/vue-codemirror6.git/compare/0.1.2...0.1.6)\n\n> 19 May 2022\n\n- Follow changes in the master branch [`d7a9e3f`](https://github.com/logue/vue-codemirror6.git/commit/d7a9e3f9cfd7580bb78c29f96e1f2c84d77d5801)\n- Follow Vue3 version. [`1867c6c`](https://github.com/logue/vue-codemirror6.git/commit/1867c6c18fdc10f331e1dace37c5773242069150)\n- Since past values may be included, nextTick processing was added to onMouted. [`dac2bdd`](https://github.com/logue/vue-codemirror6.git/commit/dac2bdd1ea935141ed25b93c9882f6ecc871099e)\n\n#### [0.1.2](https://github.com/logue/vue-codemirror6.git/compare/0.1.0...0.1.2)\n\n> 6 April 2022\n\n- Squashed commit of the following: [`db4abdd`](https://github.com/logue/vue-codemirror6.git/commit/db4abdddda262a7fa4f69f028b423d13442cec68)\n- When building with vue3, it doesn't work with vue2, so build with vue2. [`87be702`](https://github.com/logue/vue-codemirror6.git/commit/87be702b278df9cf0f5b26bb8307f7a6d592fd73)\n- Rewrite the wrapper part. [`1e77661`](https://github.com/logue/vue-codemirror6.git/commit/1e776619bb5f711a789bbe758d10142725de39aa)\n\n#### [0.1.0](https://github.com/logue/vue-codemirror6.git/compare/0.0.6...0.1.0)\n\n> 18 March 2022\n\n- Update Samples. (run `yarn run dev`) [`f658c65`](https://github.com/logue/vue-codemirror6.git/commit/f658c654f2910a133914f2fa0fdc8206dadb7232)\n- Fixed IME probrem. [`7a42e63`](https://github.com/logue/vue-codemirror6.git/commit/7a42e63f75748039ebb082732fe46cd7967f32d7)\n\n#### [0.0.6](https://github.com/logue/vue-codemirror6.git/compare/0.0.5...0.0.6)\n\n> 17 March 2022\n\n- Fixed d.ts file destination. [`2cd9cdf`](https://github.com/logue/vue-codemirror6.git/commit/2cd9cdf3f0658d62ae434600e4e8cda14c407a47)\n\n#### [0.0.5](https://github.com/logue/vue-codemirror6.git/compare/0.0.4...0.0.5)\n\n> 17 March 2022\n\n- Fixed a bug that the cursor position may be at the top when entering a key. [`e7f5407`](https://github.com/logue/vue-codemirror6.git/commit/e7f5407c76185cc805c10fc0366c5e6dff5f44f6)\n\n#### [0.0.4](https://github.com/logue/vue-codemirror6.git/compare/0.0.2...0.0.4)\n\n> 16 February 2022\n\n- Update demo code. [`599fa5f`](https://github.com/logue/vue-codemirror6.git/commit/599fa5f4d87cc7783c98f56a9436a314b368fb64)\n- Removed code that depends on other libraries from the output code. [`7d9e383`](https://github.com/logue/vue-codemirror6.git/commit/7d9e383c17f31ed8721f94711e7cd1dc595f9e07)\n- Add demo code. [`3e06ef7`](https://github.com/logue/vue-codemirror6.git/commit/3e06ef70f5ed30fce5a6cb72add2b41fea2745fe)\n\n#### [0.0.2](https://github.com/logue/vue-codemirror6.git/compare/0.0.1...0.0.2)\n\n> 14 February 2022\n\n- Update package.json. Fixed typing settings. [`12ead23`](https://github.com/logue/vue-codemirror6.git/commit/12ead23c53c0a5ebc5a68c3bee7b192b587efafc)\n\n#### 0.0.1\n\n> 10 February 2022\n\n- Initial commit. [`b410884`](https://github.com/logue/vue-codemirror6.git/commit/b41088482f82615e9380e6231a59a39387d172a2)\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2022-2026 Masashi Yoshikawa\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.ja.md",
    "content": "# vue-codemirror6\n\n[English](README.md) | 日本語\n\n<p align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/480173/224358008-6ffad05d-1d97-4c18-8554-7d41b03f88ab.png\" alt=\"logo\" width=\"300\" height=\"300\" />\n</p>\n\n[![jsdelivr CDN](https://data.jsdelivr.com/v1/package/npm/vue-codemirror6/badge)](https://www.jsdelivr.com/package/npm/vue-codemirror6)\n[![NPM Downloads](https://img.shields.io/npm/dm/vue-codemirror6.svg?style=flat)](https://www.npmjs.com/package/vue-codemirror6)\n[![Open in unpkg](https://img.shields.io/badge/Open%20in-unpkg-blue)](https://uiwjs.github.io/npm-unpkg/#/pkg/vue-codemirror6/file/README.md)\n[![npm version](https://img.shields.io/npm/v/vue-codemirror6.svg)](https://www.npmjs.com/package/vue-codemirror6)\n[![Open in Gitpod](https://shields.io/badge/Open%20in-Gitpod-green?logo=Gitpod)](https://gitpod.io/#https://github.com/logue/vue-codemirror6)\n[![Twitter Follow](https://img.shields.io/twitter/follow/logue256?style=plastic)](https://twitter.com/logue256)\n\nVueで[CodeMirror6](https://codemirror.net/6/)を使用するためのコンポーネントです。このコンポーネントはVue2とVue3の両方で動作します。\n\n- [変更履歴](./CHANGELOG.md)\n\n## 使い方\n\n```sh\nyarn add vue-codemirror6 codemirror\n```\n\nVue 2.7以下の場合は、[@vue/composition-api](https://www.npmjs.com/package/@vue/composition-api)が別途必要です。\n\n```sh\nyarn add vue-codemirror6 @vue/composition-api\n```\n\nこのコンポーネントは、一般的なVueコンポーネントと同様に`v-model`で双方向バインディングを処理できます。\n\n## Props\n\n| Props                     | Type                              | 説明                                                                                                                                                                                                                 |\n| ------------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| model-value               | string \\| Text                    | テキスト値。(`value`ではありません)                                                                                                                                                                                  |\n| basic                     | boolean                           | [basicSetup](https://codemirror.net/docs/ref/#codemirror.basicSetup)を使用します。                                                                                                                                   |\n| minimal                   | boolean                           | [miniSetup](https://codemirror.net/docs/ref/#codemirror.minimalSetup)を使用します。`basic` propも指定されている場合は、そちらの設定が優先されます。                                                                  |\n| dark                      | boolean                           | ダークモードの切り替え。                                                                                                                                                                                             |\n| placeholder               | string                            | 空白の場合にプレースホルダーテキスト（またはHTML DOM）を追加します。                                                                                                                                                 |\n| wrap                      | boolean                           | テキストの行折り返し。[lineWrapping](https://codemirror.net/6/docs/ref/#view.EditorView.lineWrapping)を参照してください。                                                                                            |\n| tab                       | boolean                           | タブインデントを有効にします。                                                                                                                                                                                       |\n| allow-multiple-selections | boolean                           | 複数選択を許可します。[allowMultipleSelections](https://codemirror.net/docs/ref/#state.EditorState^allowMultipleSelections)を参照してください。                                                                      |\n| tab-size                  | number                            | この状態で使用するタブサイズを設定します。                                                                                                                                                                           |\n| line-separator            | string                            | 改行（区切り文字）を設定します。（デフォルトは`\\n`です。）                                                                                                                                                           |\n| theme                     | { [selector: string]: StyleSpec } | テーマを指定します。例えば、[@codemirror/theme-one-dark](https://github.com/codemirror/theme-one-dark)を使用する場合は、`oneDark`をインポートしてこのpropに設定します。                                              |\n| readonly                  | boolean                           | カーソルを表示したり、テキストをドラッグできますが、値を編集することはできません。                                                                                                                                   |\n| disabled                  | boolean                           | CodeMirrorのeditableの逆の値です。`readonly`に似ていますが、この値をtrueに設定するとドラッグも無効になります。                                                                                                       |\n| lang                      | LanguageSupport                   | 構文ハイライトを使用したい言語。<https://codemirror.net/6/#languages>を参照してください。                                                                                                                            |\n| phrases                   | Record&lt;string, string&gt;      | 表示される文字列を多言語化したい場合はここで指定します。<https://codemirror.net/6/examples/translate/>を参照してください。                                                                                           |\n| extensions                | Extension[]                       | CodeMirrorを拡張する機能拡張が含まれます。                                                                                                                                                                           |\n| linter                    | LintSource                        | リンターを設定します。`@codemirror/lang-javascript`の場合は`esLint([任意のルール])`関数、`@codemirror/json`の場合は`jsonParseLinter()`関数を入力します。詳細については、各言語ライブラリのソースを参照してください。 |\n| linterConfig              | Object                            | <https://codemirror.net/docs/ref/#lint.linter^config>を参照してください。                                                                                                                                            |\n| forceLinting              | boolean                           | <https://codemirror.net/docs/ref/#lint.forceLinting>を参照してください。                                                                                                                                             |\n| gutter                    | boolean                           | `linter`が指定されている場合、エラーがあった行に🔴を表示します。`linter`が指定されていない場合は機能しません。                                                                                                       |\n| gutterConfig              | Object                            | <https://codemirror.net/docs/ref/#lint.lintGutter^config>を参照してください。                                                                                                                                        |\n| tag                       | string                            | コンポーネントで使用されるHTMLタグ。（デフォルトは`div`タグです。）                                                                                                                                                  |\n| scrollIntoView            | boolean                           | 外部更新でフォームをスクロールできるようにします。（デフォルトは`true`です。）                                                                                                                                       |\n| preserveScrollPosition    | boolean                           | `modelValue` が外部から更新されたときにエディタのスクロール位置を保持します。追記更新時に先頭へ戻る挙動の抑止に使えます。（デフォルトは`false`です。）                                                               |\n| keymap                    | KeyBinding[]                      | キーバインディングは、キー名をコマンドスタイルの関数に関連付けます。<https://codemirror.net/docs/ref/#view.KeyBinding>を参照してください。                                                                           |\n\n⚠ 注意: `lang`と`linter`は、`extensions`にまとめて設定することもできます。これらは、以前のバージョンのCodeMirror設定との互換性とpropsの型付けのために分離されています。\n\n### サポートされている言語\n\n#### 公式\n\n- [`@codemirror/lang-angular`](https://www.npmjs.com/package/@codemirror/lang-angular)\n- [`@codemirror/lang-cpp`](https://www.npmjs.com/package/@codemirror/lang-cpp)\n- [`@codemirror/lang-css`](https://www.npmjs.com/package/@codemirror/lang-css)\n- [`@codemirror/lang-html`](https://www.npmjs.com/package/@codemirror/lang-html)\n- [`@codemirror/lang-java`](https://www.npmjs.com/package/@codemirror/lang-java)\n- [`@codemirror/lang-javascript`](https://www.npmjs.com/package/@codemirror/lang-javascript)\n- [`@codemirror/lang-json`](https://www.npmjs.com/package/@codemirror/lang-json)\n- [`@codemirror/lang-lezer`](https://www.npmjs.com/package/@codemirror/lang-lezer)\n- [`@codemirror/lang-markdown`](https://www.npmjs.com/package/@codemirror/lang-markdown)\n- [`@codemirror/lang-php`](https://www.npmjs.com/package/@codemirror/lang-php)\n- [`@codemirror/lang-python`](https://www.npmjs.com/package/@codemirror/lang-python)\n- [`@codemirror/lang-rust`](https://www.npmjs.com/package/@codemirror/lang-rust)\n- [`@codemirror/lang-sql`](https://www.npmjs.com/package/@codemirror/lang-sql)\n- [`@codemirror/lang-vue`](https://www.npmjs.com/package/@codemirror/lang-vue)\n- [`@codemirror/lang-west`](https://www.npmjs.com/package/@codemirror/lang-west)\n- [`@codemirror/lang-xml`](https://www.npmjs.com/package/@codemirror/lang-xml)\n\n### 非公式\n\n- [`@phoenix-plugin-registry/petetnt.brackets-codemirror-fortran`](https://www.npmjs.com/package/@phoenix-plugin-registry/petetnt.brackets-codemirror-fortran)\n- [`@phoenix-plugin-registry/petetnt.brackets-codemirror-go`](https://www.npmjs.com/package/@phoenix-plugin-registry/petetnt.brackets-codemirror-go)\n- [`@acarl005/lang-sql`](https://www.npmjs.com/package/@acarl005/lang-sql)\n- [`@ark-us/codemirror-lang-taylor`](https://www.npmjs.com/package/@ark-us/codemirror-lang-taylor)\n- [`@formulavize/lang-fiz`](https://www.npmjs.com/package/@formulavize/lang-fiz)\n- [`@gravitywiz/codemirror-lang-gfcalc`](https://www.npmjs.com/package/@gravitywiz/codemirror-lang-gfcalc)\n- [`@nextjournal/lang-clojure`](https://www.npmjs.com/package/@nextjournal/lang-clojure)\n- [`@plutojl/lang-julia`](https://www.npmjs.com/package/@plutojl/lang-julia)\n- [`@polybase/codemirror-lang-javascript`](https://www.npmjs.com/package/@polybase/codemirror-lang-javascript)\n- [`@replit/codemirror-lang-nix`](https://www.npmjs.com/package/@replit/codemirror-lang-nix)\n- [`@replit/codemirror-lang-csharp`](https://www.npmjs.com/package/@replit/codemirror-lang-csharp)\n- [`@replit/codemirror-lang-solidity`](https://www.npmjs.com/package/@replit/codemirror-lang-solidity)\n- [`@replit/codemirror-lang-svelte`](https://www.npmjs.com/package/@replit/codemirror-lang-svelte)\n- [`@zhijiu/lang-sql`](https://www.npmjs.com/package/@zhijiu/lang-sql)\n- [`codemirror-lang-bool`](https://www.npmjs.com/package/codemirror-lang-bool)\n- [`codemirror-lang-brainfuck`](https://www.npmjs.com/package/codemirror-lang-brainfuck)\n- [`codemirror-lang-cherry`](https://www.npmjs.com/package/codemirror-lang-cherry)\n- [`codemirror-lang-chordpro`](https://www.npmjs.com/package/codemirror-lang-chordpro)\n- [`codemirror-lang-circom`](https://www.npmjs.com/package/codemirror-lang-circom)\n- [`codemirror-lang-edn`](https://www.npmjs.com/package/codemirror-lang-edn)\n- [`codemirror-lang-ejs`](https://www.npmjs.com/package/codemirror-lang-ejs)\n- [`codemirror-lang-fsl`](https://www.npmjs.com/package/codemirror-lang-fsl)\n- [`codemirror-lang-gml`](https://www.npmjs.com/package/codemirror-lang-gml)\n- [`codemirror-lang-golfscript`](https://www.npmjs.com/package/codemirror-lang-golfscript)\n- [`codemirror-lang-homescript`](https://www.npmjs.com/package/codemirror-lang-homescript)\n- [`codemirror-lang-html-n8n`](https://www.npmjs.com/package/codemirror-lang-html-n8n)\n- [`codemirror-lang-inform7`](https://www.npmjs.com/package/codemirror-lang-inform7)\n- [`codemirror-lang-j`](https://www.npmjs.com/package/codemirror-lang-j)\n- [`codemirror-lang-janet`](https://www.npmjs.com/package/codemirror-lang-janet)\n- [`codemirror-lang-k`](https://www.npmjs.com/package/codemirror-lang-k)\n- [`codemirror-lang-karol`](https://www.npmjs.com/package/codemirror-lang-karol)\n- [`codemirror-lang-mermaid`](https://www.npmjs.com/package/codemirror-lang-mermaid)\n- [`codemirror-lang-n8n-expression`](https://www.npmjs.com/package/codemirror-lang-n8n-expression)\n- [`codemirror-lang-prolog`](https://www.npmjs.com/package/codemirror-lang-prolog)\n- [`codemirror-lang-qpen`](https://www.npmjs.com/package/codemirror-lang-qpen)\n- [`codemirror-lang-qtam`](https://www.npmjs.com/package/codemirror-lang-qtam)\n- [`codemirror-lang-r`](https://www.npmjs.com/package/codemirror-lang-r)\n- [`codemirror-lang-rome-ast`](https://www.npmjs.com/package/codemirror-lang-rome-ast)\n- [`codemirror-lang-rome`](https://www.npmjs.com/package/codemirror-lang-rome)\n- [`codemirror-lang-rush`](https://www.npmjs.com/package/codemirror-lang-rush)\n- [`codemirror-lang-scopescript`](https://www.npmjs.com/package/codemirror-lang-scopescript)\n- [`codemirror-lang-statement`](https://www.npmjs.com/package/codemirror-lang-statement)\n- [`gcode-lang-codemirror`](https://www.npmjs.com/package/gcode-lang-codemirror)\n- [`gmail-lang`](https://www.npmjs.com/package/gmail-lang)\n- [`lang-bqn`](https://www.npmjs.com/package/lang-bqn)\n- [`lang-clojure`](https://www.npmjs.com/package/lang-clojure)\n- [`lang-d`](https://www.npmjs.com/package/lang-d)\n- [`lang-feel`](https://www.npmjs.com/package/lang-feel)\n- [`lang-firestore`](https://www.npmjs.com/package/lang-firestore)\n\n### サポートされているテーマ\n\n- [`@codemirror/theme-one-dark`](https://github.com/codemirror/theme-one-dark)\n- [`upleveled/theme-vs-code-dark-plus`](https://github.com/upleveled/theme-vs-code-dark-plus)\n- [`codemirror6-bootstrap-theme`](https://github.com/logue/codemirror6-bootstrap-theme)\n\n## 例\n\n最小限で動作させるには、以下のようにマークアップします。\n\n```vue\n<template>\n  <code-mirror v-model=\"value\" />\n</template>\n\n<script>\nimport { ref, defineComponent } from 'vue';\n\nimport CodeMirror from 'vue-codemirror6';\n\nexport default defineComponent({\n  components: {\n    CodeMirror,\n  },\n  setup() {\n    const value = ref('Cozy lummox gives smart squid who asks for job pen.');\n\n    return { value };\n  },\n});\n</script>\n```\n\n### スロットを使用した例\n\nスロットの内容は既存の`v-model`を上書きします。このため、`v-model`を使用せずに`readonly` propで単に表示する場合に使用することをお勧めします。\n\nまた、スロット内のテキストが自動的にフォーマットされないように、`<pre>`タグを挿入します。\n\n```vue\n<template>\n  <code-mirror :lang=\"lang\" :linter=\"linter\">\n    <pre>\n{\n  \"key\": \"value\"\n}</pre\n    >\n  </code-mirror>\n</template>\n\n<script>\nimport { ref, defineComponent } from 'vue';\n\nimport { json, jsonParseLinter } from '@codemirror/lang-json';\n\nimport CodeMirror from 'vue-codemirror6';\n\nexport default defineComponent({\n  components: {\n    CodeMirror,\n  },\n  setup() {\n    const lang = json();\n    const linter = jsonParseLinter();\n    return { lang, linter };\n  },\n});\n</script>\n```\n\n### SSR（Nuxt.jsなど）での使用\n\nこのコンポーネントはSSR互換になりました。CodeMirrorはクライアント側でのみ初期化され、サーバー側レンダリング中にコンポーネントがエラーなく安全にレンダリングされます。\n\nNuxt 3を使用している場合は、コンポーネントを直接使用できます：\n\n```vue\n<template>\n  <code-mirror v-model=\"value\" :lang=\"lang\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport CodeMirror from 'vue-codemirror6';\nimport { javascript } from '@codemirror/lang-javascript';\n\nconst value = ref('console.log(\"Hello, World!\");');\nconst lang = javascript();\n</script>\n```\n\nNuxt 2を使用している場合や問題が発生した場合は、コンポーネントを`<ClientOnly>`でラップできます：\n\n```vue\n<template>\n  <client-only>\n    <code-mirror v-model=\"value\" :lang=\"lang\" />\n  </client-only>\n</template>\n```\n\n### 完全な例\n\n[vite-vue3-ts-starter](https://github.com/logue/vite-vue3-ts-starter)でMarkdownエディターとして使用する場合。\n\n```vue\n<script lang=\"ts\" setup>\nimport { ref, defineComponent, type Ref } from 'vue';\n\n// コンポーネントの読み込み\nimport CodeMirror from 'vue-codemirror6';\n\n// CodeMirror拡張機能\nimport { markdown as md } from '@codemirror/lang-markdown';\nimport type { LanguageSupport } from '@codemirror/language';\nimport type { Extension } from '@codemirror/state';\nimport type { ViewUpdate } from '@codemirror/view';\n\n/** テキスト */\nconst value: Ref<string> = ref('');\n\n/** ダークモード **/\nconst dark: Ref<boolean> = ref(\n  window.matchMedia('(prefers-color-scheme: dark)').matches\n);\n\n/**\n * CodeMirror言語\n *\n * @see {@link https://codemirror.net/6/docs/ref/#language | @codemirror/language}\n */\nconst lang: LanguageSupport = md();\n\n/**\n * 国際化設定。\n * この例では、表示言語を日本語にしています。\n * vue-i18nと組み合わせて使用する場合は、リアクティブである必要があります。\n *\n * @see {@link https://codemirror.net/6/examples/translate/ | Example: Internationalization}\n */\nconst phrases: Record<string, string> = {\n  // @codemirror/view\n  'Control character': '制御文字',\n  // @codemirror/commands\n  'Selection deleted': '選択を削除',\n  // @codemirror/language\n  'Folded lines': '折り畳まれた行',\n  'Unfolded lines': '折り畳める行',\n  to: '行き先',\n  'folded code': '折り畳まれたコード',\n  unfold: '折り畳みを解除',\n  'Fold line': '行を折り畳む',\n  'Unfold line': '行の折り畳む解除',\n  // @codemirror/search\n  'Go to line': '行き先の行',\n  go: 'OK',\n  Find: '検索',\n  Replace: '置き換え',\n  next: '▼',\n  previous: '▲',\n  all: 'すべて',\n  'match case': '一致条件',\n  'by word': '全文検索',\n  regexp: '正規表現',\n  replace: '置き換え',\n  'replace all': 'すべてを置き換え',\n  close: '閉じる',\n  'current match': '現在の一致',\n  'replaced $ matches': '$ 件の一致を置き換え',\n  'replaced match on line $': '$ 行の一致を置き換え',\n  'on line': 'した行',\n  // @codemirror/autocomplete\n  Completions: '自動補完',\n  // @codemirror/lint\n  Diagnostics: 'エラー',\n  'No diagnostics': 'エラーなし',\n};\n</script>\n\n<template>\n  <code-mirror\n    v-model=\"value\"\n    basic\n    :dark=\"dark\"\n    :lang=\"lang\"\n    :phrases=\"phrases\"\n  />\n</template>\n```\n\n## イベント\n\n| イベント | 説明                                                                                                                     |\n| -------- | ------------------------------------------------------------------------------------------------------------------------ |\n| ready    | CodeMirrorが読み込まれたとき。                                                                                           |\n| focus    | フォーカスが変更されたとき。                                                                                             |\n| update   | CodeMirrorの状態が変更されたとき。[ViewUpdate](https://codemirror.net/docs/ref/#view.ViewUpdate)オブジェクトを返します。 |\n| change   | 値が変更されたとき。[EditorState](https://codemirror.net/docs/ref/#state.EditorState)を返します。                        |\n\n## パラメータ / 関数\n\n```vue\n<script setup lang=\"ts\">\nimport { ref, onMounted, type Ref, type PropType } from 'vue';\nimport CodeMirror from 'vue-codemirror6';\n\nconst cm: Ref<InstanceType<typeof CodeMirror> | undefined> = ref();\n\nonMounted(() => {\n  console.log(cm.value?.json);\n});\n</script>\n<template>\n  <code-mirror ref=\"cm\" />\n</template>\n```\n\n| 関数 / パラメータ  | 説明                                                                                                          |\n| ------------------ | ------------------------------------------------------------------------------------------------------------- |\n| view               | [EditorView](https://codemirror.net/docs/ref/#view.EditorView)を取得および設定します。                        |\n| selection          | [EditorSelection](https://codemirror.net/docs/ref/#state.EditorSelection)インスタンスを取得および設定します。 |\n| cursor             | [Cursor](https://codemirror.net/docs/ref/#state.EditorSelection^cursor)の位置を取得および設定します。         |\n| json               | 状態をJSON直列化可能なオブジェクトとして取得および設定します。                                                |\n| focus              | [Focus](https://codemirror.net/docs/ref/#view.EditorView.focus)を取得および設定します。                       |\n| lint()             | リンターを強制実行します（`linter`propが指定されている場合のみ）。                                            |\n| forceReconfigure() | すべての拡張機能を再登録します。                                                                              |\n\n### CodeMirror5の後方互換関数\n\n以下の説明は、[codemirror5](https://codemirror.net/5/)に精通している方向けの互換メソッドです。\n通常、上記のメソッドで十分であるため、**積極的な使用は推奨されません**。\n\n| 関数                                                                | 説明                                                                                     |\n| ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |\n| getRange(from?: number, to?: number)                                | エディター内の指定されたポイント間のテキストを取得します。                               |\n| getLine(number: number)                                             | 行の内容を取得します。                                                                   |\n| lineCount()                                                         | エディターの行数を取得します。                                                           |\n| getCursor()                                                         | 主選択の一方の端を取得します。                                                           |\n| listSelections()                                                    | 現在のすべての選択のリストを取得します。                                                 |\n| getSelection()                                                      | 現在選択されているコードを取得します。                                                   |\n| getSelections()                                                     | 指定された配列の長さは、アクティブな選択の数と同じである必要があります。                 |\n| somethingSelected()                                                 | テキストが選択されている場合はtrueを返します。                                           |\n| replaceRange(replacement: string \\| Text, from: number, to: number) | fromからtoまでのドキュメントの部分を指定された文字列で置き換えます。                     |\n| replaceSelection(replacement: string \\| Text)                       | 選択を指定された文字列で置き換えます。                                                   |\n| setCursor(position: number)                                         | カーソル位置を設定します。                                                               |\n| setSelection(anchor: number, head?: number)                         | 単一の選択範囲を設定します。                                                             |\n| setSelections(ranges: readonly SelectionRange[], primary?: number)  | 新しい選択のセットを設定します。                                                         |\n| extendSelectionsBy(f: Function)                                     | すべての既存の選択に指定された関数を適用し、結果に対してextendSelectionsを呼び出します。 |\n\n## 推奨事項\n\nCodeMirrorは比較的大容量であるため、[vite](https://vitejs.dev)を使用する場合は、ビルド時に以下のように[`manualChunks`](https://vitejs.dev/guide/build.html#chunking-strategy)オプションを使用して別ファイルとして出力するように設定することをお勧めします。\n\n```ts\nconst config: UserConfig = {\n  // ...\n  build: {\n    rollupOptions: {\n      output: {\n        manualChunks: {\n          // ...\n          codemirror: ['vue-codemirror6'],\n          'codemirror-lang': [\n            // 必要に応じて以下を追加してください。\n            '@codemirror/lang-html',\n            '@codemirror/lang-javascript',\n            '@codemirror/lang-markdown',\n          ],\n          // ...\n        },\n      },\n    },\n  },\n  // ...\n};\n```\n\n## 開発\n\n### テスト\n\nこのプロジェクトは、ユニットテストに[Vitest](https://vitest.dev/)を使用しています。\n\n```bash\n# テストを実行\npnpm test\n\n# ウォッチモードでテストを実行\npnpm test:watch\n\n# UIを使用してテストを実行\npnpm test:ui\n\n# カバレッジを使用してテストを実行\npnpm test:coverage\n```\n\nテストスイートには以下が含まれます：\n\n- **コンポーネントテスト**: 基本的なレンダリング、props、イベント、v-modelバインディングのテスト\n- **SSRテスト**: Nuxt.jsやその他のSSRフレームワークの適切なサーバー側レンダリング互換性の確保\n- **メソッドテスト**: 公開されているすべてのメソッドが正しく動作することを検証\n- **エッジケース**: エラー処理と異常なシナリオのテスト\n\n## ライセンス\n\n©2022-2026 by Logue.\n[MITライセンス](LICENSE)の下でライセンスされています。\n\n## 🎨 開発者のために作られました\n\nこのライブラリは、**最新の開発者体験**に焦点を当てて構築されています。これを維持するには、すべてがシームレスに動作することを確認するための継続的なテストと更新が必要です。\n\nこのプロジェクトの細部へのこだわりを評価していただける場合は、Vue.jsとMetaverseエコシステム全体での私の仕事をサポートするために、小額のスポンサーシップをいただければ幸いです。\n\n[![GitHub Sponsors](https://img.shields.io/github/sponsors/logue?label=Sponsor&logo=github&color=ea4aaa)](https://github.com/sponsors/logue)\n"
  },
  {
    "path": "README.md",
    "content": "# vue-codemirror6\n\nEnglish | [日本語](README.ja.md)\n\n<p align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/480173/224358008-6ffad05d-1d97-4c18-8554-7d41b03f88ab.png\" alt=\"logo\" width=\"300\" height=\"300\" />\n</p>\n\n[![jsdelivr CDN](https://data.jsdelivr.com/v1/package/npm/vue-codemirror6/badge)](https://www.jsdelivr.com/package/npm/vue-codemirror6)\n[![NPM Downloads](https://img.shields.io/npm/dm/vue-codemirror6.svg?style=flat)](https://www.npmjs.com/package/vue-codemirror6)\n[![Open in unpkg](https://img.shields.io/badge/Open%20in-unpkg-blue)](https://uiwjs.github.io/npm-unpkg/#/pkg/vue-codemirror6/file/README.md)\n[![npm version](https://img.shields.io/npm/v/vue-codemirror6.svg)](https://www.npmjs.com/package/vue-codemirror6)\n[![Open in Gitpod](https://shields.io/badge/Open%20in-Gitpod-green?logo=Gitpod)](https://gitpod.io/#https://github.com/logue/vue-codemirror6)\n[![Twitter Follow](https://img.shields.io/twitter/follow/logue256?style=plastic)](https://twitter.com/logue256)\n\nA component for using [CodeMirror6](https://codemirror.net/6/) with Vue. This component works in both Vue2 and Vue3.\n\n- [CHANGELOG](./CHANGELOG.md)\n\n## Usage\n\n```sh\nyarn add vue-codemirror6 codemirror\n```\n\nFor Vue 2.7 or below, [@vue/composition-api](https://www.npmjs.com/package/@vue/composition-api) is required separately.\n\n```sh\nyarn add vue-codemirror6 @vue/composition-api\n```\n\nThis component can handle bidirectional binding by `v-model` like a general Vue component.\n\n## Props\n\n| Props                     | Type                              | Information                                                                                                                                                                                                                    |\n| ------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| model-value               | string \\| Text                    | Text value. (Not `value`)                                                                                                                                                                                                      |\n| basic                     | boolean                           | Use [basicSetup](https://codemirror.net/docs/ref/#codemirror.basicSetup).                                                                                                                                                      |\n| minimal                   | boolean                           | Use [miniSetup](https://codemirror.net/docs/ref/#codemirror.minimalSetup). If a `basic` prop is also specified, that setting will take precedence.                                                                             |\n| dark                      | boolean                           | Toggle Darkmode.                                                                                                                                                                                                               |\n| placeholder               | string                            | Add placeholder text (or HTML DOM) when blank                                                                                                                                                                                  |\n| wrap                      | boolean                           | Line text wrapping. see [lineWrapping](https://codemirror.net/6/docs/ref/#view.EditorView.lineWrapping).                                                                                                                       |\n| tab                       | boolean                           | Enables tab indentation.                                                                                                                                                                                                       |\n| allow-multiple-selections | boolean                           | Allow Multiple Selection. See [allowMultipleSelections](https://codemirror.net/docs/ref/#state.EditorState^allowMultipleSelections)                                                                                            |\n| tab-size                  | number                            | Configures the tab size to use in this state.                                                                                                                                                                                  |\n| line-separator            | string                            | Set line break (separetor) char. (Default is `\\n`.)                                                                                                                                                                            |\n| theme                     | { [selector: string]: StyleSpec } | Specify the theme. For example, if you use [@codemirror/theme-one-dark](https://github.com/codemirror/theme-one-dark), import `oneDark` and put it in this prop.                                                               |\n| readonly                  | boolean                           | Makes the cursor visible or you can drag the text but not edit the value.                                                                                                                                                      |\n| disabled                  | boolean                           | This is the reversed value of the CodeMirror editable. Similar to `readonly`, but setting this value to true disables dragging.                                                                                                |\n| lang                      | LanguageSupport                   | The language you want to have syntax highlighting. see <https://codemirror.net/6/#languages>                                                                                                                                   |\n| phrases                   | Record&lt;string, string&gt;      | Specify here if you want to make the displayed character string multilingual. see <https://codemirror.net/6/examples/translate/>                                                                                               |\n| extensions                | Extension[]                       | Includes enhancements to extend CodeMirror.                                                                                                                                                                                    |\n| linter                    | LintSource                        | Set Linter. Enter a linter (eg `esLint([arbitrary rule])` function for `@codemirror/lang-javascript`, `jsonParseLinter()`function for`@codemirror/json`). See the sources for various language libraries for more information. |\n| linterConfig              | Object                            | see <https://codemirror.net/docs/ref/#lint.linter^config>                                                                                                                                                                      |\n| forceLinting              | boolean                           | see <https://codemirror.net/docs/ref/#lint.forceLinting>                                                                                                                                                                       |\n| gutter                    | boolean                           | Display 🔴 on the line where there was an error when `linter` was specified. It will not work if `linter` is not specified.                                                                                                    |\n| gutterConfig              | Object                            | see <https://codemirror.net/docs/ref/#lint.lintGutter^config>                                                                                                                                                                  |\n| tag                       | string                            | HTML tags used in the component. (Default is `div` tag.)                                                                                                                                                                       |\n| scrollIntoView            | boolean                           | Allows an external update to scroll the form. (Default is `true`)                                                                                                                                                              |\n| preserveScrollPosition    | boolean                           | Preserves the editor scroll position when `modelValue` is updated externally. Useful to prevent jumping to the top during appended updates. (Default is `false`)                                                               |\n| keymap                    | KeyBinding[]                      | Key bindings associate key names with command-style functions. See <https://codemirror.net/docs/ref/#view.KeyBinding>                                                                                                          |\n\n⚠ Notice: `lang` and `linter` can also be set together in `extensions`. These are separated for compatibility with previous versions of CodeMirror settings and for typing props.\n\n### Supported Languages\n\n#### Official\n\n- [`@codemirror/lang-angular`](https://www.npmjs.com/package/@codemirror/lang-angular)\n- [`@codemirror/lang-cpp`](https://www.npmjs.com/package/@codemirror/lang-cpp)\n- [`@codemirror/lang-css`](https://www.npmjs.com/package/@codemirror/lang-css)\n- [`@codemirror/lang-html`](https://www.npmjs.com/package/@codemirror/lang-html)\n- [`@codemirror/lang-java`](https://www.npmjs.com/package/@codemirror/lang-java)\n- [`@codemirror/lang-javascript`](https://www.npmjs.com/package/@codemirror/lang-javascript)\n- [`@codemirror/lang-json`](https://www.npmjs.com/package/@codemirror/lang-json)\n- [`@codemirror/lang-lezer`](https://www.npmjs.com/package/@codemirror/lang-lezer)\n- [`@codemirror/lang-markdown`](https://www.npmjs.com/package/@codemirror/lang-markdown)\n- [`@codemirror/lang-php`](https://www.npmjs.com/package/@codemirror/lang-php)\n- [`@codemirror/lang-python`](https://www.npmjs.com/package/@codemirror/lang-python)\n- [`@codemirror/lang-rust`](https://www.npmjs.com/package/@codemirror/lang-rust)\n- [`@codemirror/lang-sql`](https://www.npmjs.com/package/@codemirror/lang-sql)\n- [`@codemirror/lang-vue`](https://www.npmjs.com/package/@codemirror/lang-vue)\n- [`@codemirror/lang-west`](https://www.npmjs.com/package/@codemirror/lang-west)\n- [`@codemirror/lang-xml`](https://www.npmjs.com/package/@codemirror/lang-xml)\n\n### Unofficial\n\n- [`@phoenix-plugin-registry/petetnt.brackets-codemirror-fortran`](https://www.npmjs.com/package/@phoenix-plugin-registry/petetnt.brackets-codemirror-fortran)\n- [`@phoenix-plugin-registry/petetnt.brackets-codemirror-go`](https://www.npmjs.com/package/@phoenix-plugin-registry/petetnt.brackets-codemirror-go)\n- [`@acarl005/lang-sql`](https://www.npmjs.com/package/@acarl005/lang-sql)\n- [`@ark-us/codemirror-lang-taylor`](https://www.npmjs.com/package/@ark-us/codemirror-lang-taylor)\n- [`@formulavize/lang-fiz`](https://www.npmjs.com/package/@formulavize/lang-fiz)\n- [`@gravitywiz/codemirror-lang-gfcalc`](https://www.npmjs.com/package/@gravitywiz/codemirror-lang-gfcalc)\n- [`@nextjournal/lang-clojure`](https://www.npmjs.com/package/@nextjournal/lang-clojure)\n- [`@plutojl/lang-julia`](https://www.npmjs.com/package/@plutojl/lang-julia)\n- [`@polybase/codemirror-lang-javascript`](https://www.npmjs.com/package/@polybase/codemirror-lang-javascript) -[`@replit/codemirror-lang-nix`](https://www.npmjs.com/package/@replit/codemirror-lang-nix)\n- [`@replit/codemirror-lang-csharp`](https://www.npmjs.com/package/@replit/codemirror-lang-csharp)\n- [`@replit/codemirror-lang-solidity`](https://www.npmjs.com/package/@replit/codemirror-lang-solidity)\n- [`@replit/codemirror-lang-svelte`](https://www.npmjs.com/package/@replit/codemirror-lang-svelte)\n- [`@zhijiu/lang-sql`](https://www.npmjs.com/package/@zhijiu/lang-sql)\n- [`codemirror-lang-bool`](https://www.npmjs.com/package/codemirror-lang-bool)\n- [`codemirror-lang-brainfuck`](https://www.npmjs.com/package/codemirror-lang-brainfuck)\n- [`codemirror-lang-cherry`](https://www.npmjs.com/package/codemirror-lang-cherry)\n- [`codemirror-lang-chordpro`](https://www.npmjs.com/package/codemirror-lang-chordpro)\n- [`codemirror-lang-circom`](https://www.npmjs.com/package/codemirror-lang-circom)\n- [`codemirror-lang-edn`](https://www.npmjs.com/package/codemirror-lang-edn)\n- [`codemirror-lang-ejs`](https://www.npmjs.com/package/codemirror-lang-ejs)\n- [`codemirror-lang-fsl`](https://www.npmjs.com/package/codemirror-lang-fsl)\n- [`codemirror-lang-gml`](https://www.npmjs.com/package/codemirror-lang-gml)\n- [`codemirror-lang-golfscript`](https://www.npmjs.com/package/codemirror-lang-golfscript)\n- [`codemirror-lang-homescript`](https://www.npmjs.com/package/codemirror-lang-homescript)\n- [`codemirror-lang-html-n8n`](https://www.npmjs.com/package/codemirror-lang-html-n8n)\n- [`codemirror-lang-inform7`](https://www.npmjs.com/package/codemirror-lang-inform7)\n- [`codemirror-lang-j`](https://www.npmjs.com/package/codemirror-lang-j)\n- [`codemirror-lang-janet`](https://www.npmjs.com/package/codemirror-lang-janet)\n- [`codemirror-lang-k`](https://www.npmjs.com/package/codemirror-lang-k)\n- [`codemirror-lang-karol`](https://www.npmjs.com/package/codemirror-lang-karol)\n- [`codemirror-lang-mermaid`](https://www.npmjs.com/package/codemirror-lang-mermaid)\n- [`codemirror-lang-n8n-expression`](https://www.npmjs.com/package/codemirror-lang-n8n-expression)\n- [`codemirror-lang-prolog`](https://www.npmjs.com/package/codemirror-lang-prolog)\n- [`codemirror-lang-qpen`](https://www.npmjs.com/package/codemirror-lang-qpen)\n- [`codemirror-lang-qtam`](https://www.npmjs.com/package/codemirror-lang-qtam)\n- [`codemirror-lang-r`](https://www.npmjs.com/package/codemirror-lang-r)\n- [`codemirror-lang-rome-ast`](https://www.npmjs.com/package/codemirror-lang-rome-ast)\n- [`codemirror-lang-rome`](https://www.npmjs.com/package/codemirror-lang-rome)\n- [`codemirror-lang-rush`](https://www.npmjs.com/package/codemirror-lang-rush)\n- [`codemirror-lang-scopescript`](https://www.npmjs.com/package/codemirror-lang-scopescript)\n- [`codemirror-lang-statement`](https://www.npmjs.com/package/codemirror-lang-statement)\n- [`gcode-lang-codemirror`](https://www.npmjs.com/package/gcode-lang-codemirror)\n- [`gmail-lang`](https://www.npmjs.com/package/gmail-lang)\n- [`lang-bqn`](https://www.npmjs.com/package/lang-bqn)\n- [`lang-clojure`](https://www.npmjs.com/package/lang-clojure)\n- [`lang-d`](https://www.npmjs.com/package/lang-d)\n- [`lang-feel`](https://www.npmjs.com/package/lang-feel)\n- [`lang-firestore`](https://www.npmjs.com/package/lang-firestore)\n\n### Supported Themes\n\n- [`@codemirror/theme-one-dark`](https://github.com/codemirror/theme-one-dark)\n- [`upleveled/theme-vs-code-dark-plus`](https://github.com/upleveled/theme-vs-code-dark-plus)\n- [`codemirror6-bootstrap-theme`](https://github.com/logue/codemirror6-bootstrap-theme)\n\n## Example\n\nMark up as follows to make it work at a minimum.\n\n```vue\n<template>\n  <code-mirror v-model=\"value\" />\n</template>\n\n<script>\nimport { ref, defineComponent } from 'vue';\n\nimport CodeMirror from 'vue-codemirror6';\n\nexport default defineComponent({\n  components: {\n    CodeMirror,\n  },\n  setup() {\n    const value = ref('Cozy lummox gives smart squid who asks for job pen.');\n\n    return { value };\n  },\n});\n</script>\n```\n\n### Example using Slots\n\nThe contents of the slot will overwrite the existing `v-model`. For this reason, it is recommended to use it when simply displaying with a `readonly` prop without using `v-model`.\n\nAlso, insert a `<pre>` tag to prevent the text in the slot from being automatically formatted.\n\n```vue\n<template>\n  <code-mirror :lang=\"lang\" :linter=\"linter\">\n    <pre>\n{\n  \"key\": \"value\"\n}</pre\n    >\n  </code-mirror>\n</template>\n\n<script>\nimport { ref, defineComponent } from 'vue';\n\nimport { json, jsonParseLinter } from '@codemirror/lang-json';\n\nimport CodeMirror from 'vue-codemirror6';\n\nexport default defineComponent({\n  components: {\n    CodeMirror,\n  },\n  setup() {\n    const lang = json();\n    const linter = jsonParseLinter();\n    return { lang, linter };\n  },\n});\n</script>\n```\n\n### Using with SSR (Nuxt.js, etc.)\n\nThis component is now SSR-compatible. CodeMirror will only be initialized on the client side, and the component will safely render without errors during server-side rendering.\n\nIf you're using Nuxt 3, you can use the component directly:\n\n```vue\n<template>\n  <code-mirror v-model=\"value\" :lang=\"lang\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport CodeMirror from 'vue-codemirror6';\nimport { javascript } from '@codemirror/lang-javascript';\n\nconst value = ref('console.log(\"Hello, World!\");');\nconst lang = javascript();\n</script>\n```\n\nFor Nuxt 2 or if you encounter any issues, you can wrap the component with `<ClientOnly>`:\n\n```vue\n<template>\n  <client-only>\n    <code-mirror v-model=\"value\" :lang=\"lang\" />\n  </client-only>\n</template>\n```\n\n### Full Example\n\nWhen using as a Markdown editor on [vite-vue3-ts-starter](https://github.com/logue/vite-vue3-ts-starter).\n\n```vue\n<script lang=\"ts\" setup>\nimport { ref, defineComponent, type Ref } from 'vue';\n\n// Load component\nimport CodeMirror from 'vue-codemirror6';\n\n// CodeMirror extensions\nimport { markdown as md } from '@codemirror/lang-markdown';\nimport type { LanguageSupport } from '@codemirror/language';\nimport type { Extension } from '@codemirror/state';\nimport type { ViewUpdate } from '@codemirror/view';\n\n/** text */\nconst value: Ref<string> = ref('');\n\n/** Dark mode **/\nconst dark: Ref<boolean> = ref(\n  window.matchMedia('(prefers-color-scheme: dark)').matches\n);\n\n/**\n * CodeMirror Language\n *\n * @see {@link https://codemirror.net/6/docs/ref/#language | @codemirror/language}\n */\nconst lang: LanguageSupport = md();\n\n/**\n * Internationalization Config.\n * In this example, the display language to Japanese.\n * Must be reactive when used in combination with vue-i18n.\n *\n * @see {@link https://codemirror.net/6/examples/translate/ | Example: Internationalization}\n */\nconst phrases: Record<string, string> = {\n  // @codemirror/view\n  'Control character': '制御文字',\n  // @codemirror/commands\n  'Selection deleted': '選択を削除',\n  // @codemirror/language\n  'Folded lines': '折り畳まれた行',\n  'Unfolded lines': '折り畳める行',\n  to: '行き先',\n  'folded code': '折り畳まれたコード',\n  unfold: '折り畳みを解除',\n  'Fold line': '行を折り畳む',\n  'Unfold line': '行の折り畳む解除',\n  // @codemirror/search\n  'Go to line': '行き先の行',\n  go: 'OK',\n  Find: '検索',\n  Replace: '置き換え',\n  next: '▼',\n  previous: '▲',\n  all: 'すべて',\n  'match case': '一致条件',\n  'by word': '全文検索',\n  regexp: '正規表現',\n  replace: '置き換え',\n  'replace all': 'すべてを置き換え',\n  close: '閉じる',\n  'current match': '現在の一致',\n  'replaced $ matches': '$ 件の一致を置き換え',\n  'replaced match on line $': '$ 行の一致を置き換え',\n  'on line': 'した行',\n  // @codemirror/autocomplete\n  Completions: '自動補完',\n  // @codemirror/lint\n  Diagnostics: 'エラー',\n  'No diagnostics': 'エラーなし',\n};\n</script>\n\n<template>\n  <code-mirror\n    v-model=\"value\"\n    basic\n    :dark=\"dark\"\n    :lang=\"lang\"\n    :phrases=\"phrases\"\n  />\n</template>\n```\n\n## Events\n\n| Event  | Description                                                                                                   |\n| ------ | ------------------------------------------------------------------------------------------------------------- |\n| ready  | When CodeMirror loaded.                                                                                       |\n| focus  | When focus changed.                                                                                           |\n| update | When CodeMirror state changed. Returns [ViewUpdate](https://codemirror.net/docs/ref/#view.ViewUpdate) object. |\n| change | Value changed. Returns [EditorState](https://codemirror.net/docs/ref/#state.EditorState)                      |\n\n## Parameter / Function\n\n```vue\n<script setup lang=\"ts\">\nimport { ref, onMounted, type Ref, type PropType } from 'vue';\nimport CodeMirror from 'vue-codemirror6';\n\nconst cm: Ref<InstanceType<typeof CodeMirror> | undefined> = ref();\n\nonMounted(() => {\n  console.log(cm.value?.json);\n});\n</script>\n<template>\n  <code-mirror ref=\"cm\" />\n</template>\n```\n\n| Function / Parameter | Description                                                                                         |\n| -------------------- | --------------------------------------------------------------------------------------------------- |\n| view                 | Get and set [EditorView](https://codemirror.net/docs/ref/#view.EditorView).                         |\n| selection            | Get and set the [EditorSelection](https://codemirror.net/docs/ref/#state.EditorSelection) instance. |\n| cursor               | Get and set the [cursor](https://codemirror.net/docs/ref/#state.EditorSelection^cursor) location.   |\n| json                 | Get and set state to a JSON-serializable object.                                                    |\n| focus                | Get and set [focus](https://codemirror.net/docs/ref/#view.EditorView.focus).                        |\n| lint()               | Force run linter (Only if `linter` prop is specified)                                               |\n| forceReconfigure()   | Re register all extensions.                                                                         |\n\n### CodeMirror5 backward compatible functions\n\nThe instructions below are compatible methods for those familiar with [codemirror5](https://codemirror.net/5/).\nSince the above method is usually sufficient, its **active use is not recommended**.\n\n| Function                                                            | Description                                                                                      |\n| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |\n| getRange(from?: number, to?: number)                                | Get the text between the given points in the editor.                                             |\n| getLine(number: number)                                             | Get the content of line.                                                                         |\n| lineCount()                                                         | Get the number of lines in the editor.                                                           |\n| getCursor()                                                         | Retrieve one end of the primary selection.                                                       |\n| listSelections()                                                    | Retrieves a list of all current selections.                                                      |\n| getSelection()                                                      | Get the currently selected code.                                                                 |\n| getSelections()                                                     | The length of the given array should be the same as the number of active selections.             |\n| somethingSelected()                                                 | Return true if any text is selected.                                                             |\n| replaceRange(replacement: string \\| Text, from: number, to: number) | Replace the part of the document between from and to with the given string.                      |\n| replaceSelection(replacement: string \\| Text)                       | Replace the selection(s) with the given string.                                                  |\n| setCursor(position: number)                                         | Set the cursor position.                                                                         |\n| setSelection(anchor: number, head?: number)                         | Set a single selection range.                                                                    |\n| setSelections(ranges: readonly SelectionRange[], primary?: number)  | Sets a new set of selections.                                                                    |\n| extendSelectionsBy(f: Function)                                     | Applies the given function to all existing selections, and calls extendSelections on the result. |\n\n## Recommendations\n\nSince CodeMirror has a relatively large capacity, when using [vite](https://vitejs.dev), it is recommended to set it to output as a separate file using the [`manualChunks`](https://vitejs.dev/guide/build.html#chunking-strategy) option at build time as shown below.\n\n```ts\nconst config: UserConfig = {\n  // ...\n  build: {\n    rollupOptions: {\n      output: {\n        manualChunks: {\n          // ...\n          codemirror: ['vue-codemirror6'],\n          'codemirror-lang': [\n            // Add the following as needed.\n            '@codemirror/lang-html',\n            '@codemirror/lang-javascript',\n            '@codemirror/lang-markdown',\n          ],\n          // ...\n        },\n      },\n    },\n  },\n  // ...\n};\n```\n\n## Development\n\n### Testing\n\nThis project uses [Vitest](https://vitest.dev/) for unit testing.\n\n```bash\n# Run tests\npnpm test\n\n# Run tests in watch mode\npnpm test:watch\n\n# Run tests with UI\npnpm test:ui\n\n# Run tests with coverage\npnpm test:coverage\n```\n\nThe test suite includes:\n\n- **Component Tests**: Testing basic rendering, props, events, and v-model binding\n- **SSR Tests**: Ensuring proper server-side rendering compatibility for Nuxt.js and other SSR frameworks\n- **Method Tests**: Verifying all exposed methods work correctly\n- **Edge Cases**: Testing error handling and unusual scenarios\n\n## LICENSE\n\n©2022-2026 by Logue.\nLicensed under the [MIT License](LICENSE).\n\n## 🎨 Crafted for Developers\n\nThis library is built with a focus **modern developer experience**. Maintaining it involves constant testing and updates to ensure everything works seamlessly.\n\nIf you appreciate the attention to detail in this project, a small sponsorship would go a long way in supporting my work across the Vue.js and Metaverse ecosystems.\n\n[![GitHub Sponsors](https://img.shields.io/github/sponsors/logue?label=Sponsor&logo=github&color=ea4aaa)](https://github.com/sponsors/logue)\n"
  },
  {
    "path": "SSR_FIX_SUMMARY.md",
    "content": "# SSR対応の修正サマリー\n\n## 変更内容\n\nこのプルリクエストでは、Nuxt.jsなどのSSR（Server-Side Rendering）環境での動作をサポートするための修正を行いました。\n\n## 主な変更点\n\n### 1. `src/components/CodeMirror.ts`\n\n#### SSR環境のチェック\n\n- `onMounted`内でブラウザ環境をチェックし、サーバーサイドでは初期化をスキップ\n- `typeof window !== 'undefined'` でブラウザ環境を確認\n\n#### `view`の型変更\n\n- `ShallowRef<EditorView>` から `ShallowRef<EditorView | undefined>` に変更\n- サーバーサイドでは`undefined`となる可能性を考慮\n\n#### すべての`view.value`アクセスを安全に\n\n- `view.value?.` の Optional Chaining を使用\n- 各関数で`view.value`の存在をチェック\n\n#### computed プロパティの修正\n\n- `focus`: `view.value?.hasFocus ?? false` で安全にアクセス\n- `selection`: `view.value?.state.selection` でOptionalに\n- `cursor`: `view.value?.state.selection.main.head ?? 0` でデフォルト値を提供\n- `json`: `view.value?.state.toJSON()` でOptionalに\n\n#### ヘルパー関数の修正\n\nすべてのCodeMirror5互換関数を安全に修正：\n\n- `getRange()`, `getLine()`, `lineCount()`, `getCursor()`\n- `listSelections()`, `getSelection()`, `getSelections()`\n- `somethingSelected()`\n- `replaceRange()`, `replaceSelection()`\n- `setCursor()`, `setSelection()`, `setSelections()`\n- `extendSelectionsBy()`\n\n各関数で`view.value`の存在を確認し、存在しない場合は適切なデフォルト値を返すか、処理をスキップ\n\n### 2. `README.md`\n\n#### SSR使用例セクションの追加\n\n- Nuxt.jsでの使用方法を説明\n- Nuxt 3での直接使用方法\n- Nuxt 2や問題が発生した場合の`<ClientOnly>`ラッパーの使用方法\n\n## テスト方法\n\n### ローカルでのビルド確認\n\n```bash\npnpm type-check  # 型チェック成功\npnpm build       # ビルド成功\n```\n\n### Nuxtでのテスト方法\n\n#### Nuxt 3での使用例\n\n```vue\n<template>\n  <code-mirror v-model=\"value\" :lang=\"lang\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport CodeMirror from 'vue-codemirror6';\nimport { javascript } from '@codemirror/lang-javascript';\n\nconst value = ref('console.log(\"Hello, World!\");');\nconst lang = javascript();\n</script>\n```\n\n#### Nuxt 2での使用例\n\n```vue\n<template>\n  <client-only>\n    <code-mirror v-model=\"value\" :lang=\"lang\" />\n  </client-only>\n</template>\n\n<script>\nimport CodeMirror from 'vue-codemirror6';\nimport { javascript } from '@codemirror/lang-javascript';\n\nexport default {\n  components: {\n    CodeMirror,\n  },\n  data() {\n    return {\n      value: 'console.log(\"Hello, World!\");',\n      lang: javascript(),\n    };\n  },\n};\n</script>\n```\n\n## 互換性\n\n- ✅ Vue 2.7以上\n- ✅ Vue 3.3以上\n- ✅ Nuxt 2\n- ✅ Nuxt 3\n- ✅ その他のSSRフレームワーク（VitePress、Quasar SSRなど）\n\n## 破壊的変更\n\nなし。既存の使用方法はすべて互換性を維持しています。\n\n## 次のバージョンで推奨される変更\n\n次のメジャーバージョン（2.0.0）で以下を検討：\n\n- `view`、`selection`、`json`などの型を常にOptionalとして扱う\n- TypeScript strictモードでのより厳密な型チェック\n\n## 関連Issue\n\nこの修正は、NuxtやVitePressなどのSSR環境でコンポーネントが正しく動作しない問題を解決します。\n\n## ライセンス\n\n©2022-2025 by Logue.\nLicensed under the MIT License.\n"
  },
  {
    "path": "TESTING.md",
    "content": "# Testing Guide\n\nこのプロジェクトは[Vitest](https://vitest.dev/)を使用してテストを行っています。\n\n## テストの実行\n\n### 基本的なコマンド\n\n```bash\n# 全テストを実行\npnpm test:run\n\n# ウォッチモードでテストを実行（開発時に便利）\npnpm test\n\n# UIモードでテストを実行\npnpm test:ui\n\n# カバレッジレポートを生成\npnpm test:coverage\n```\n\n## テストの構成\n\n### 1. コンポーネントテスト (`CodeMirror.spec.ts`)\n\n基本的なコンポーネントの機能をテストします：\n\n- **レンダリング**: コンポーネントが正しくレンダリングされるか\n- **Props**: 各プロパティが正しく動作するか\n- **イベント**: `ready`, `update`, `change`, `destroy`などのイベントが正しく発火するか\n- **V-Model**: 双方向バインディングが正しく動作するか\n- **スロット**: スロットコンテンツが正しく表示されるか\n- **公開メソッド**: `getRange()`, `setCursor()`などのメソッドが正しく動作するか\n\n### 2. SSR互換性テスト (`CodeMirror.ssr.spec.ts`)\n\nサーバーサイドレンダリング環境での動作をテストします：\n\n- **サーバーサイドレンダリング**: SSR環境でエラーなくレンダリングされるか\n- **安全なメソッド呼び出し**: `view`が未初期化でもメソッドがエラーを投げないか\n- **クライアントサイドハイドレーション**: ブラウザでの初期化が正しく行われるか\n- **グレースフルデグラデーション**: 機能が段階的に提供されるか\n- **メモリリーク防止**: コンポーネントが正しくクリーンアップされるか\n\n## テストの追加\n\n新しい機能を追加する場合は、対応するテストも追加してください：\n\n```typescript\nimport { describe, it, expect } from 'vitest';\nimport { mount } from '@vue/test-utils';\nimport CodeMirror from '@/components/CodeMirror';\n\ndescribe('New Feature', () => {\n  it('should work correctly', async () => {\n    const wrapper = mount(CodeMirror, {\n      props: {\n        modelValue: 'test',\n        // 新機能のprops\n      },\n    });\n\n    // テストロジック\n    expect(wrapper.exists()).toBe(true);\n  });\n});\n```\n\n## テスト環境\n\n- **テストランナー**: Vitest\n- **DOM環境**: happy-dom（軽量で高速）\n- **Vueテストユーティリティ**: @vue/test-utils\n- **アサーション**: Vitest標準のexpect API\n\n## カバレッジ\n\nカバレッジレポートは以下を除外しています：\n\n- `node_modules/`\n- `src-docs/` (ドキュメントサイト)\n- `dist/` (ビルド出力)\n- `**/*.d.ts` (型定義ファイル)\n- `**/*.config.*` (設定ファイル)\n- `src/Meta.ts` (自動生成ファイル)\n- `src/helpers/h-demi.ts` (Vue 2/3互換レイヤー)\n\n## ベストプラクティス\n\n### 1. テストは独立させる\n\n各テストは他のテストに依存しないようにしてください。\n\n```typescript\nbeforeEach(() => {\n  // 各テストの前にクリーンアップ\n  document.body.innerHTML = '';\n});\n```\n\n### 2. 非同期処理を待つ\n\nコンポーネントのライフサイクルを待つために`nextTick()`を使用してください。\n\n```typescript\nawait nextTick();\nawait nextTick(); // onMountedを待つ\n```\n\n### 3. クリーンアップ\n\nテスト後はコンポーネントをアンマウントしてください。\n\n```typescript\nwrapper.unmount();\n```\n\n### 4. 意味のあるアサーション\n\nテストは何をテストしているかが明確になるようにしてください。\n\n```typescript\n// 良い例\nexpect(wrapper.props('readonly')).toBe(true);\n\n// 避けるべき例\nexpect(wrapper.props('readonly')).toBeTruthy();\n```\n\n## トラブルシューティング\n\n### テストがタイムアウトする\n\n長時間かかるテストにはタイムアウトを設定できます：\n\n```typescript\nit('long running test', { timeout: 10000 }, async () => {\n  // テストコード\n});\n```\n\n### DOMが見つからない\n\n`attachTo`オプションを使用してDOMに直接マウントしてください：\n\n```typescript\nconst wrapper = mount(CodeMirror, {\n  props: { modelValue: 'test' },\n  attachTo: document.body,\n});\n\n// 忘れずにクリーンアップ\nwrapper.unmount();\n```\n\n### メモリリーク\n\nテスト後に適切にクリーンアップされているか確認してください：\n\n```typescript\nafterEach(() => {\n  // 必要に応じてグローバルな状態をリセット\n});\n```\n\n## CI/CD\n\nGitHub ActionsなどのCI環境でテストを実行する場合は、`pnpm test:run`を使用してください。これはウォッチモードなしで一度だけテストを実行します。\n\n```yaml\n- name: Run tests\n  run: pnpm test:run\n```\n\n## 参考リンク\n\n- [Vitest Documentation](https://vitest.dev/)\n- [Vue Test Utils](https://test-utils.vuejs.org/)\n- [Happy DOM](https://github.com/capricorn86/happy-dom)\n"
  },
  {
    "path": "env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n\ndeclare module '*.vue' {\n  import Vue from 'vue';\n  export default Vue;\n}\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type -- Vite env extension point; add VITE_APP_* variable types here as needed\ninterface ImportMetaEnv {\n  // see https://vitejs.dev/guide/env-and-mode.html#env-files\n  // add .env variables.\n}\n\ninterface ImportMeta {\n  readonly env: ImportMetaEnv;\n}\n"
  },
  {
    "path": "eslint.config.ts",
    "content": "import configPrettier from '@vue/eslint-config-prettier';\nimport {\n  defineConfigWithVueTs,\n  vueTsConfigs,\n} from '@vue/eslint-config-typescript';\n\nimport markdown from '@eslint/markdown';\nimport comments from '@eslint-community/eslint-plugin-eslint-comments/configs';\nimport pluginVitest from '@vitest/eslint-plugin';\nimport { globalIgnores } from 'eslint/config';\nimport pluginImport from 'eslint-plugin-import-x';\nimport pluginOxlint from 'eslint-plugin-oxlint';\nimport pluginPlaywright from 'eslint-plugin-playwright';\n// @ts-ignore\nimport pluginSecurity from 'eslint-plugin-security';\nimport pluginVue from 'eslint-plugin-vue';\nimport pluginVueA11y from 'eslint-plugin-vuejs-accessibility';\n\nimport type { Linter } from 'eslint';\n\n// Lint policy:\n// 1) Keep oxlint + prettier as primary formatting/quick-check tools.\n// 2) Keep ESLint focused on framework/type/import correctness.\n// 3) Scope plugin presets to relevant file types to avoid cross-file crashes.\n// 4) Restrict markdown lint to workspace instruction docs under .github.\n// 5) Prefer small, explicit overrides over broad global exceptions.\nconst APP_FILES = ['**/*.{vue,ts,mts,tsx}'];\nconst VUE_FILES = ['*.vue', '**/*.vue'];\nconst MARKDOWN_FILES = ['.github/**/*.md'];\nconst E2E_FILES = ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'];\nconst UNIT_TEST_FILES = ['src/**/__tests__/*'];\nconst GLOBAL_IGNORES = ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'];\n\nconst scopeConfigsToFiles = (configs: Linter.Config[], files: string[]) =>\n  configs.map(config => (config.files ? config : { ...config, files }));\n\nconst markdownRecommendedConfigs = markdown.configs.recommended.map(config => ({\n  ...config,\n  files: MARKDOWN_FILES,\n}));\n\nconst appRules: Linter.Config['rules'] = {\n  '@eslint-community/eslint-comments/require-description': 'error',\n  'no-unused-vars': 'off',\n  // const lines: string[] = []; style\n  '@typescript-eslint/array-type': [\n    'error',\n    {\n      default: 'array',\n    },\n  ],\n  // Enable @ts-ignore etc.\n  '@typescript-eslint/ban-ts-comment': 'off',\n  // Left-hand side style\n  '@typescript-eslint/consistent-generic-constructors': [\n    'error',\n    'type-annotation',\n  ],\n  // Enable import sort order, see bellow.\n  '@typescript-eslint/consistent-type-imports': [\n    'off',\n    {\n      prefer: 'type-imports',\n    },\n  ],\n  // Fix for pinia\n  '@typescript-eslint/explicit-function-return-type': 'off',\n  // Exclude variables with leading underscores\n  '@typescript-eslint/no-unused-vars': [\n    'error',\n    {\n      args: 'all',\n      argsIgnorePattern: '^_',\n      caughtErrors: 'all',\n      caughtErrorsIgnorePattern: '^_',\n      destructuredArrayIgnorePattern: '^_',\n      varsIgnorePattern: '^_',\n      ignoreRestSiblings: true,\n    },\n  ],\n  // Fix for vite import.meta.env\n  '@typescript-eslint/strict-boolean-expressions': 'off',\n  // Fix for vite env.d.ts.\n  '@typescript-eslint/triple-slash-reference': 'off',\n  // Fix for Vue setup style\n  'import-x/default': 'off',\n  // Fix for vite\n  'import-x/namespace': 'off',\n  'import-x/no-default-export': 'off',\n  'import-x/no-named-as-default-member': 'off',\n  'import-x/no-named-as-default': 'off',\n  // Sort Import Order.\n  // see https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md#importorder-enforce-a-convention-in-module-import-order\n  'import-x/order': [\n    'error',\n    {\n      groups: [\n        'builtin',\n        'external',\n        'parent',\n        'sibling',\n        'index',\n        'object',\n        'type',\n      ],\n      pathGroups: [\n        // Vue Core\n        {\n          pattern:\n            '{vue,vue-router,vuex,@/store,vue-i18n,pinia,vite,vitest,vitest/**,@vitejs/**,@vue/**}',\n          group: 'external',\n          position: 'before',\n        },\n        // Internal Codes\n        {\n          pattern: '{@/**}',\n          group: 'internal',\n          position: 'before',\n        },\n      ],\n      pathGroupsExcludedImportTypes: ['builtin'],\n      alphabetize: {\n        order: 'asc',\n      },\n      'newlines-between': 'always',\n    },\n  ],\n  // Using `../` to navigate back to parent directories is completely prohibited (using `./foo` at the same level is OK).\n  // Alias imports like `@/` are excluded because they resolve via the configured alias, not a relative parent path.\n  'import-x/no-relative-parent-imports': ['error', { ignore: ['^@/', '^~/'] }],\n};\n\nconst appSettings = {\n  // This will do the trick\n  'import-x/parsers': {\n    espree: ['.js', '.cjs', '.mjs', '.jsx'],\n    '@typescript-eslint/parser': ['.ts', '.tsx'],\n    'vue-eslint-parser': ['.vue'],\n  },\n  'import-x/resolver': {\n    // You will also need to install and configure the TypeScript resolver\n    // See also https://github.com/import-js/eslint-import-resolver-typescript#configuration\n    typescript: true,\n    node: true,\n    'eslint-import-resolver-custom-alias': {\n      alias: {\n        '@': './src',\n        '~': './node_modules',\n      },\n      extensions: ['.js', '.ts', '.jsx', '.tsx', '.vue'],\n    },\n  },\n};\n\n// To allow more languages other than `ts` in `.vue` files, uncomment the following lines:\n// import { configureVueProject } from '@vue/eslint-config-typescript'\n// configureVueProject({ scriptLangs: ['ts', 'tsx'] })\n// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup\n\nexport default defineConfigWithVueTs(\n  ...markdownRecommendedConfigs,\n\n  globalIgnores(GLOBAL_IGNORES),\n\n  ...scopeConfigsToFiles(pluginVue.configs['flat/recommended'], VUE_FILES),\n  ...scopeConfigsToFiles(pluginVueA11y.configs['flat/recommended'], VUE_FILES),\n  vueTsConfigs.recommended,\n  comments.recommended,\n\n  {\n    ...pluginImport.flatConfigs.recommended,\n    files: APP_FILES,\n  },\n  {\n    ...pluginImport.flatConfigs.typescript,\n    files: APP_FILES,\n  },\n  {\n    ...pluginSecurity.configs.recommended,\n    files: APP_FILES,\n  },\n  {\n    name: 'app/rules',\n    files: APP_FILES,\n    settings: appSettings,\n    rules: appRules,\n  },\n  {\n    name: 'vue/rules',\n    files: VUE_FILES,\n    rules: {\n      // <script setup> required（Prohibit Options API）\n      'vue/component-api-style': ['error', ['script-setup']],\n\n      // defineProps / defineEmits only support type-based declarations (Prohibit runtime declaration style)\n      'vue/define-props-declaration': ['error', 'type-based'],\n      'vue/define-emits-declaration': ['error', 'type-based'],\n\n      // <style scoped> required（Prohibit global styles in components）\n      'vue/enforce-style-attribute': ['error', { allow: ['scoped'] }],\n      'vue/attributes-order': [\n        'warn',\n        {\n          order: [\n            'DEFINITION', // is, v-is\n            'LIST_RENDERING', // v-for\n            'CONDITIONALS', // v-if, v-else-if, v-else, v-show\n            'RENDER_MODIFIERS', // v-pre, v-once\n            'UNIQUE', // ref, key\n            'TWO_WAY_BINDING', // v-model\n            'OTHER_DIRECTIVES', // Other directives\n            'ATTR_DYNAMIC', // :prop\n            'ATTR_STATIC', // prop=\"value\"\n            'ATTR_SHORTHAND_BOOL', // disabled\n            'EVENTS', // @click\n            'CONTENT', // v-html, v-text\n          ],\n          alphabetical: false,\n        },\n      ],\n      // A tag with no content should be written like <br />.\n      'vue/html-self-closing': [\n        'error',\n        {\n          html: {\n            void: 'always',\n          },\n        },\n      ],\n      // Mitigate non-multiword component name errors to warnings.\n      'vue/multi-word-component-names': 'warn',\n      'vuejs-accessibility/label-has-for': [\n        'error',\n        {\n          components: ['VLabel'], // UI library label components are also targeted\n          controlComponents: ['VInput'], // Corresponding control components\n          required: { some: ['nesting', 'id'] },\n        },\n      ],\n      'vuejs-accessibility/no-autofocus': 'warn', // autofocus breaks screen readers and keyboard navigation\n      'vuejs-accessibility/anchor-has-content': 'error', // <a> elements must have content\n    },\n  },\n\n  {\n    name: 'vue/components-strict',\n    files: ['src/components/**/*.vue'],\n    rules: {\n      'vue/multi-word-component-names': 'error',\n    },\n  },\n\n  {\n    ...pluginPlaywright.configs['flat/recommended'],\n    files: E2E_FILES,\n  },\n\n  {\n    ...pluginVitest.configs.recommended,\n    files: UNIT_TEST_FILES,\n  },\n  {\n    // Test files intentionally import from parent directories (the component under test).\n    name: 'test/relax-parent-imports',\n    files: UNIT_TEST_FILES,\n    rules: {\n      'import-x/no-relative-parent-imports': 'off',\n    },\n  },\n\n  ...pluginOxlint.buildFromOxlintConfigFile('.oxlintrc.json'),\n  configPrettier,\n  {\n    name: 'markdown/final-overrides',\n    files: MARKDOWN_FILES,\n    language: 'markdown/gfm',\n    rules: {\n      'prettier/prettier': 'off',\n    },\n  }\n);\n"
  },
  {
    "path": "index.html",
    "content": "<!doctype html>\n<html lang=\"en\" class=\"h-100\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <meta name=\"color-scheme\" content=\"light dark\" />\n    <link rel=\"icon\" href=\"/favicon.ico\" />\n    <title>Vue CodeMirror6 Demo</title>\n    <!-- Google tag (gtag.js) -->\n    <script\n      async\n      src=\"https://www.googletagmanager.com/gtag/js?id=G-2Y2FW3QEG4\"\n    ></script>\n    <script>\n      window.dataLayer = window.dataLayer || [];\n      function gtag() {\n        dataLayer.push(arguments);\n      }\n      gtag('js', new Date());\n      gtag('config', 'G-2Y2FW3QEG4');\n    </script>\n  </head>\n\n  <body class=\"h-100 bg-body text-body\">\n    <div id=\"app\" class=\"d-flex flex-column h-100\">\n      We're sorry but this site doesn't work properly without JavaScript\n      enabled. Please enable it to continue.\n    </div>\n    <script type=\"module\" src=\"/src-docs/main.ts\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/package.json\",\n  \"name\": \"vue-codemirror6\",\n  \"version\": \"1.5.2\",\n  \"license\": \"MIT\",\n  \"description\": \"CodeMirror6 Component for vue2 and vue3.\",\n  \"keywords\": [\n    \"vuejs\",\n    \"vue\",\n    \"vue-components\",\n    \"vue-codemirror\",\n    \"code-editor\",\n    \"text-editor\",\n    \"vue2\",\n    \"vue3\",\n    \"web-editor\",\n    \"vue-plugin\",\n    \"vue-component\",\n    \"codemirror-editor\",\n    \"vue-resource\",\n    \"codemirror6\"\n  ],\n  \"type\": \"module\",\n  \"author\": {\n    \"name\": \"Logue\",\n    \"email\": \"logue@hotmail.co.jp\",\n    \"url\": \"https://logue.dev/\"\n  },\n  \"homepage\": \"https://github.com/logue/vue-codemirror6\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+ssh://git@github.com/logue/vue-codemirror6.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/logue/vue-codemirror6/issues\"\n  },\n  \"main\": \"dist/index.cjs.js\",\n  \"module\": \"dist/index.es.js\",\n  \"types\": \"dist/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"import\": \"./dist/index.es.js\",\n      \"types\": \"./dist/index.d.ts\",\n      \"require\": \"./dist/index.cjs.js\",\n      \"default\": \"./dist/index.es.js\"\n    },\n    \"./umd\": {\n      \"default\": \"./dist/index.umd.js\"\n    },\n    \"./iife\": {\n      \"default\": \"./dist/index.iife.js\"\n    }\n  },\n  \"files\": [\n    \"CHANGELOG.md\",\n    \"/dist\"\n  ],\n  \"sideEffects\": false,\n  \"engines\": {\n    \"node\": \"^20.19.0 || >=22.12.0\",\n    \"pnpm\": \">=10.3.0\"\n  },\n  \"packageManager\": \"pnpm@10.33.2\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"clean\": \"rimraf node_modules/.vite\",\n    \"build\": \"run-p type-check \\\"build-only {@}\\\" --\",\n    \"build:analyze\": \"vite build --mode=analyze\",\n    \"build:clean\": \"rimraf dist docs\",\n    \"build:docs\": \"vite build --mode=docs\",\n    \"lint\": \"run-s lint:*\",\n    \"lint:oxlint\": \"oxlint . --fix\",\n    \"lint:eslint\": \"eslint . --fix --cache --cache-location ./node_modules/.vite/eslint-cache\",\n    \"lint:prettier\": \"prettier \\\"./**/*.{js,ts,json,css,sass,scss,htm,html,vue,md}\\\" -w -u\",\n    \"preview\": \"vite preview --mode=docs\",\n    \"build-only\": \"vite build && node scripts/sync-dts-entry.mjs\",\n    \"type-check\": \"vue-tsc --declaration --emitDeclarationOnly\",\n    \"test\": \"vitest\",\n    \"test:ui\": \"vitest --ui\",\n    \"test:run\": \"vitest run\",\n    \"test:coverage\": \"vitest run --coverage\",\n    \"prepare\": \"husky\",\n    \"version\": \"auto-changelog -p && git add CHANGELOG.md\"\n  },\n  \"dependencies\": {\n    \"vue-demi\": \"latest\"\n  },\n  \"peerDependencies\": {\n    \"@codemirror/autocomplete\": \"^6.0.0\",\n    \"@codemirror/commands\": \"^6.0.0\",\n    \"@codemirror/language\": \"^6.0.0\",\n    \"@codemirror/lint\": \"^6.0.0\",\n    \"@codemirror/search\": \"^6.0.0\",\n    \"@codemirror/state\": \"^6.0.0\",\n    \"@codemirror/view\": \"^6.0.0\",\n    \"codemirror\": \"^6.0.0\",\n    \"style-mod\": \"^4.0.0\",\n    \"vue\": \"^2.7.14 || ^3.3.4\"\n  },\n  \"devDependencies\": {\n    \"@codemirror/autocomplete\": \"^6.20.1\",\n    \"@codemirror/commands\": \"^6.10.3\",\n    \"@codemirror/lang-javascript\": \"^6.2.5\",\n    \"@codemirror/lang-json\": \"^6.0.2\",\n    \"@codemirror/lang-markdown\": \"^6.5.0\",\n    \"@codemirror/lang-vue\": \"^0.1.3\",\n    \"@codemirror/language\": \"^6.12.3\",\n    \"@codemirror/lint\": \"^6.9.5\",\n    \"@codemirror/search\": \"^6.7.0\",\n    \"@codemirror/state\": \"^6.6.0\",\n    \"@codemirror/view\": \"^6.41.1\",\n    \"@eslint-community/eslint-plugin-eslint-comments\": \"^4.7.1\",\n    \"@eslint/markdown\": \"^8.0.1\",\n    \"@tsconfig/node-lts\": \"^24.0.0\",\n    \"@types/node\": \"^25.6.0\",\n    \"@vitejs/plugin-vue\": \"^6.0.6\",\n    \"@vitest/eslint-plugin\": \"^1.6.16\",\n    \"@vitest/ui\": \"^4.1.5\",\n    \"@vue/compiler-sfc\": \"^3.5.33\",\n    \"@vue/eslint-config-prettier\": \"^10.2.0\",\n    \"@vue/eslint-config-typescript\": \"^14.7.0\",\n    \"@vue/test-utils\": \"^2.4.10\",\n    \"@vue/tsconfig\": \"^0.9.1\",\n    \"@vueuse/core\": \"^14.3.0\",\n    \"bootstrap\": \"^5.3.8\",\n    \"codemirror\": \"^6.0.2\",\n    \"eslint\": \"^10.2.1\",\n    \"eslint-import-resolver-custom-alias\": \"^1.3.2\",\n    \"eslint-import-resolver-typescript\": \"^4.4.4\",\n    \"eslint-linter-browserify\": \"^10.2.1\",\n    \"eslint-plugin-import-x\": \"^4.16.2\",\n    \"eslint-plugin-oxlint\": \"^1.62.0\",\n    \"eslint-plugin-playwright\": \"^2.10.2\",\n    \"eslint-plugin-security\": \"^4.0.0\",\n    \"eslint-plugin-vue\": \"^10.9.0\",\n    \"eslint-plugin-vuejs-accessibility\": \"^2.5.0\",\n    \"happy-dom\": \"^20.9.0\",\n    \"husky\": \"^9.1.7\",\n    \"jiti\": \"^2.6.1\",\n    \"lint-staged\": \"^16.4.0\",\n    \"npm-run-all2\": \"^8.0.4\",\n    \"oxlint\": \"^1.62.0\",\n    \"prettier\": \"^3.8.3\",\n    \"rimraf\": \"^6.1.3\",\n    \"rollup-plugin-visualizer\": \"^7.0.1\",\n    \"sass-embedded\": \"^1.99.0\",\n    \"style-mod\": \"^4.1.3\",\n    \"supports-color\": \"^10.2.2\",\n    \"typescript\": \"^6.0.3\",\n    \"typescript-eslint\": \"^8.59.1\",\n    \"vite\": \"^8.0.10\",\n    \"vite-plugin-banner\": \"^0.8.1\",\n    \"vite-plugin-checker\": \"^0.13.0\",\n    \"vite-plugin-dts\": \"^5.0.0\",\n    \"vitest\": \"^4.1.5\",\n    \"vue\": \"^3.5.33\",\n    \"vue-eslint-parser\": \"^10.4.0\",\n    \"vue-markdown-wasm\": \"^1.0.1\",\n    \"vue-tsc\": \"^3.2.7\"\n  },\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"lint-staged\"\n    }\n  },\n  \"lint-staged\": {\n    \"*.{js,ts,json,htm,html,vue}\": \"eslint --fix --cache --cache-location ./node_modules/.vite/vite-plugin-eslint\",\n    \"*\": \"prettier -w -u\"\n  },\n  \"resolutions\": {\n    \"lodash\": \">=4.18.1\"\n  }\n}\n"
  },
  {
    "path": "pnpm-workspace.yaml",
    "content": "onlyBuiltDependencies:\n  - '@parcel/watcher'\n  - esbuild\n  - unrs-resolver\n  - vue-demi\n"
  },
  {
    "path": "scripts/sync-dts-entry.mjs",
    "content": "import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nconst src = resolve('dist/src/index.d.ts');\nconst dest = resolve('dist/index.d.ts');\n\nif (!existsSync(src)) {\n  console.error(`[sync-dts-entry] Source declaration not found: ${src}`);\n  process.exit(1);\n}\n\nconst content = readFileSync(src, 'utf8').replaceAll(\n  \"from '../Meta'\",\n  \"from './src/Meta'\"\n);\n\nwriteFileSync(dest, content, 'utf8');\nconsole.log(`[sync-dts-entry] Synced declaration entry: ${src} -> ${dest}`);\n"
  },
  {
    "path": "src/__tests__/CodeMirror.spec.ts",
    "content": "import { mount } from '@vue/test-utils';\nimport { describe, it, expect, beforeEach, vi } from 'vitest';\nimport { nextTick, ref } from 'vue';\n\nimport { javascript } from '@codemirror/lang-javascript';\nimport { EditorView } from '@codemirror/view';\n\nimport CodeMirror, { type CodeMirrorExposed } from '../index';\n\ndescribe('CodeMirror Component', () => {\n  beforeEach(() => {\n    // Clear any previous DOM\n    document.body.innerHTML = '';\n  });\n\n  describe('Basic Rendering', () => {\n    it('should render the component', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test code',\n        },\n      });\n\n      expect(wrapper.exists()).toBe(true);\n      expect(wrapper.classes()).toContain('vue-codemirror');\n    });\n\n    it('should use custom tag when specified', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n          tag: 'section',\n        },\n      });\n\n      expect(wrapper.element.tagName.toLowerCase()).toBe('section');\n    });\n\n    it('should apply custom class', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n        attrs: {\n          class: 'custom-class',\n        },\n      });\n\n      expect(wrapper.classes()).toContain('vue-codemirror');\n      expect(wrapper.classes()).toContain('custom-class');\n    });\n  });\n\n  describe('Props', () => {\n    it('should accept modelValue prop', () => {\n      const testValue = 'const x = 42;';\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: testValue,\n        },\n      });\n\n      expect(wrapper.props('modelValue')).toBe(testValue);\n    });\n\n    it('should accept basic setup prop', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n          basic: true,\n        },\n      });\n\n      expect(wrapper.props('basic')).toBe(true);\n    });\n\n    it('should accept minimal setup prop', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n          minimal: true,\n        },\n      });\n\n      expect(wrapper.props('minimal')).toBe(true);\n    });\n\n    it('should accept dark mode prop', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n          dark: true,\n        },\n      });\n\n      expect(wrapper.props('dark')).toBe(true);\n    });\n\n    it('should accept readonly prop', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n          readonly: true,\n        },\n      });\n\n      expect(wrapper.props('readonly')).toBe(true);\n    });\n\n    it('should accept disabled prop', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n          disabled: true,\n        },\n      });\n\n      expect(wrapper.props('disabled')).toBe(true);\n    });\n\n    it('should accept wrap prop', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n          wrap: true,\n        },\n      });\n\n      expect(wrapper.props('wrap')).toBe(true);\n    });\n\n    it('should accept tab prop', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n          tab: true,\n        },\n      });\n\n      expect(wrapper.props('tab')).toBe(true);\n    });\n\n    it('should accept placeholder prop', () => {\n      const placeholderText = 'Enter code here...';\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: '',\n          placeholder: placeholderText,\n        },\n      });\n\n      expect(wrapper.props('placeholder')).toBe(placeholderText);\n    });\n\n    it('should accept lang prop', { timeout: 10000 }, () => {\n      const lang = javascript();\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'const x = 1;',\n          lang,\n        },\n      });\n\n      // Just verify the prop is set, don't compare object identity\n      expect(wrapper.props('lang')).toBeDefined();\n      expect(wrapper.props('lang')).toHaveProperty('language');\n    });\n\n    it('should accept preserveScrollPosition prop', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n          preserveScrollPosition: true,\n        },\n      });\n\n      expect(wrapper.props('preserveScrollPosition')).toBe(true);\n    });\n  });\n\n  describe('Events', () => {\n    it('should emit ready event after mount', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      await nextTick();\n      await nextTick(); // Wait for onMounted\n\n      const readyEvents = wrapper.emitted('ready');\n      expect(readyEvents).toBeTruthy();\n      expect(readyEvents!.length).toBeGreaterThan(0);\n      const firstEvent = readyEvents![0]?.[0];\n      expect(firstEvent).toHaveProperty('view');\n      expect(firstEvent).toHaveProperty('state');\n      expect(firstEvent).toHaveProperty('container');\n    });\n\n    it('should emit update:modelValue on text change', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'initial',\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      // Simulate text change through exposed view\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      expect(vm.view).toBeDefined();\n      vm.view!.dispatch({\n        changes: { from: 0, to: vm.view!.state.doc.length, insert: 'updated' },\n      });\n\n      await nextTick();\n\n      const updateEvents = wrapper.emitted('update:modelValue');\n      expect(updateEvents).toBeTruthy();\n    });\n\n    it('should emit destroy event on unmount', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      wrapper.unmount();\n\n      const destroyEvents = wrapper.emitted('destroy');\n      expect(destroyEvents).toBeTruthy();\n    });\n  });\n\n  describe('SSR Compatibility', () => {\n    it('should handle missing window object gracefully', () => {\n      // This test ensures the component doesn't crash in SSR environment\n      // In happy-dom, window exists, but we test the defensive coding\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      expect(wrapper.exists()).toBe(true);\n    });\n\n    it('should not initialize EditorView before mount', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n        attachTo: document.body,\n      });\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      // Before nextTick, view might not be fully initialized\n      expect(vm).toBeDefined();\n      wrapper.unmount();\n    });\n\n    it('should safely handle view operations when view is undefined', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n\n      // These should not throw even if view is undefined\n      expect(() => vm.getRange()).not.toThrow();\n      expect(() => vm.getLine(0)).not.toThrow();\n      expect(() => vm.lineCount()).not.toThrow();\n      expect(() => vm.getCursor()).not.toThrow();\n      expect(() => vm.listSelections()).not.toThrow();\n      expect(() => vm.getSelection()).not.toThrow();\n      expect(() => vm.getSelections()).not.toThrow();\n      expect(() => vm.somethingSelected()).not.toThrow();\n\n      wrapper.unmount();\n    });\n  });\n\n  describe('Exposed Methods', () => {\n    it('should expose editor ref', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      expect(vm.editor).toBeDefined();\n    });\n\n    it('should expose view', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      expect(vm.view).toBeDefined();\n      expect(vm.view).toBeInstanceOf(EditorView);\n    });\n\n    it('should expose cursor getter/setter', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test code',\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      const initialCursor = vm.cursor;\n      expect(typeof initialCursor).toBe('number');\n    });\n\n    it('should expose length property', async () => {\n      const testValue = 'hello world';\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: testValue,\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      // length is updated in the update listener, so it might be 0 initially\n      expect(typeof vm.length).toBe('number');\n    });\n\n    it('should expose getRange method', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'hello world',\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      expect(vm.view).toBeDefined();\n      const range = vm.getRange(0, 5);\n      expect(range).toBe('hello');\n    });\n\n    it('should expose lineCount method', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'line1\\nline2\\nline3',\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      expect(vm.view).toBeDefined();\n      const count = vm.lineCount();\n      expect(count).toBeGreaterThan(0);\n    });\n\n    it('should expose getLine method', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'first line\\nsecond line',\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      expect(vm.view).toBeDefined();\n      const line = vm.getLine(0);\n      expect(line).toBe('first line');\n    });\n\n    it('should expose lint method', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      expect(() => vm.lint()).not.toThrow();\n    });\n\n    it('should expose forceReconfigure method', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      expect(() => vm.forceReconfigure()).not.toThrow();\n    });\n  });\n\n  describe('V-Model Binding', () => {\n    it('should update when modelValue prop changes', async () => {\n      const modelValue = ref('initial');\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: modelValue.value,\n          'onUpdate:modelValue': (\n            value?: string | import('@codemirror/state').Text\n          ) => {\n            modelValue.value =\n              typeof value === 'string' ? value : (value?.toString() ?? '');\n          },\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      // Update the prop\n      modelValue.value = 'updated';\n      await wrapper.setProps({ modelValue: modelValue.value });\n      await nextTick();\n\n      expect(wrapper.props('modelValue')).toBe('updated');\n    });\n\n    it('should preserve scroll position on external updates when enabled', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'initial',\n          preserveScrollPosition: true,\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      expect(vm.view).toBeDefined();\n\n      const scrollSnapshotSpy = vi.spyOn(\n        vm.view as EditorView,\n        'scrollSnapshot'\n      );\n\n      await wrapper.setProps({ modelValue: 'initial\\nupdated' });\n      await nextTick();\n\n      expect(scrollSnapshotSpy).toHaveBeenCalledTimes(1);\n    });\n\n    it('should not preserve scroll position on external updates by default', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'initial',\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      expect(vm.view).toBeDefined();\n\n      const scrollSnapshotSpy = vi.spyOn(\n        vm.view as EditorView,\n        'scrollSnapshot'\n      );\n\n      await wrapper.setProps({ modelValue: 'initial\\nupdated' });\n      await nextTick();\n\n      expect(scrollSnapshotSpy).not.toHaveBeenCalled();\n    });\n\n    it('should emit update:modelValue when content changes', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'initial',\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      expect(vm.view).toBeDefined();\n      vm.view!.dispatch({\n        changes: { from: 0, to: vm.view!.state.doc.length, insert: 'changed' },\n      });\n\n      await nextTick();\n\n      const updateEvents = wrapper.emitted('update:modelValue');\n      expect(updateEvents).toBeTruthy();\n      expect(updateEvents!.at(-1)?.[0]).toBe('changed');\n    });\n  });\n\n  describe('Slots', () => {\n    it('should render slot content', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: '',\n        },\n        slots: {\n          default: '<pre>Slot Content</pre>',\n        },\n      });\n\n      expect(wrapper.html()).toContain('Slot Content');\n    });\n\n    it('should hide slot content with aria-hidden', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: '',\n        },\n        slots: {\n          default: '<pre>Hidden Content</pre>',\n        },\n      });\n\n      const aside = wrapper.find('aside');\n      expect(aside.exists()).toBe(true);\n      expect(aside.attributes('aria-hidden')).toBe('true');\n    });\n  });\n\n  describe('Edge Cases', () => {\n    it('should handle empty modelValue', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: '',\n        },\n      });\n\n      expect(wrapper.props('modelValue')).toBe('');\n    });\n\n    it('should handle very long content', async () => {\n      const longContent = 'x'.repeat(10000);\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: longContent,\n        },\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      // length is a reactive value that gets updated\n      expect(typeof vm.length).toBe('number');\n      expect(vm.length).toBeGreaterThanOrEqual(0);\n    });\n\n    it('should handle special characters', () => {\n      const specialContent = '日本語\\n한글\\n中文\\n😀🎉';\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: specialContent,\n        },\n      });\n\n      expect(wrapper.props('modelValue')).toBe(specialContent);\n    });\n\n    it('should handle line separators', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'line1\\nline2',\n          lineSeparator: '\\n',\n        },\n      });\n\n      expect(wrapper.props('lineSeparator')).toBe('\\n');\n    });\n  });\n});\n"
  },
  {
    "path": "src/__tests__/CodeMirror.ssr.spec.ts",
    "content": "import { mount } from '@vue/test-utils';\nimport { describe, it, expect, beforeEach, afterEach } from 'vitest';\nimport { nextTick } from 'vue';\n\nimport CodeMirror, { type CodeMirrorExposed } from '../index';\n\ndescribe('CodeMirror SSR Compatibility', () => {\n  let originalWindow: Window & typeof globalThis;\n\n  beforeEach(() => {\n    originalWindow = globalThis.window;\n  });\n\n  afterEach(() => {\n    // Restore window\n    if (!(globalThis as Record<string, unknown>).window && originalWindow) {\n      (globalThis as Record<string, unknown>).window = originalWindow;\n    }\n  });\n\n  describe('Server-Side Rendering', () => {\n    it('should render without errors in SSR environment', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test code for SSR',\n        },\n      });\n\n      expect(wrapper.exists()).toBe(true);\n      expect(wrapper.classes()).toContain('vue-codemirror');\n    });\n\n    it('should not initialize EditorView on server', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'server side code',\n        },\n      });\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n\n      // In SSR, view should remain undefined until client-side hydration\n      // Since we're testing in happy-dom (which has window), we test the defensive approach\n      expect(vm).toBeDefined();\n    });\n\n    it('should handle props correctly in SSR', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'ssr test',\n          basic: true,\n          dark: true,\n          readonly: true,\n          placeholder: 'Enter code',\n        },\n      });\n\n      expect(wrapper.props('modelValue')).toBe('ssr test');\n      expect(wrapper.props('basic')).toBe(true);\n      expect(wrapper.props('dark')).toBe(true);\n      expect(wrapper.props('readonly')).toBe(true);\n      expect(wrapper.props('placeholder')).toBe('Enter code');\n    });\n\n    it('should safely render with all prop combinations', () => {\n      const props = {\n        modelValue: 'test',\n        basic: true,\n        minimal: false,\n        dark: true,\n        wrap: true,\n        tab: true,\n        readonly: false,\n        disabled: false,\n        placeholder: 'Type here...',\n        allowMultipleSelections: true,\n        tabSize: 4,\n        lineSeparator: '\\n',\n      };\n\n      const wrapper = mount(CodeMirror, { props });\n\n      expect(wrapper.exists()).toBe(true);\n      for (const [key, value] of Object.entries(props)) {\n        expect(wrapper.props(key as keyof typeof props)).toBe(value);\n      }\n    });\n  });\n\n  describe('Safe Method Calls in SSR', () => {\n    it('should return safe defaults when view is undefined', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n\n      // Test all exposed methods return safe values\n      expect(vm.getCursor()).toBe(0);\n      expect(vm.lineCount()).toBeGreaterThanOrEqual(0); // May be 1 if doc exists\n      // listSelections may return a default selection if view is initialized\n      expect(Array.isArray(vm.listSelections())).toBe(true);\n      expect(typeof vm.getSelection()).toBe('string');\n      expect(Array.isArray(vm.getSelections())).toBe(true);\n      expect(vm.somethingSelected()).toBe(false);\n      // getRange and getLine return string or undefined depending on whether view is initialized\n      expect(['string', 'undefined']).toContain(typeof vm.getRange());\n      expect(['string', 'undefined']).toContain(typeof vm.getLine(0));\n    });\n\n    it('should not throw when calling methods before view initialization', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n\n      // None of these should throw\n      expect(() => vm.lint()).not.toThrow();\n      expect(() => vm.forceReconfigure()).not.toThrow();\n      expect(() => vm.setCursor(0)).not.toThrow();\n      // setSelection and setSelections with invalid args might throw, which is expected behavior\n      // These are only tested to verify they don't crash when view exists\n      expect(() => vm.replaceRange('new', 0, 3)).not.toThrow();\n      expect(() => vm.replaceSelection('new')).not.toThrow();\n      // extendSelectionsBy should be safe\n      expect(() => vm.extendSelectionsBy(noopExtendSelectionsBy)).not.toThrow();\n    });\n\n    // Move to outer scope\n    function noopExtendSelectionsBy() {}\n\n    it('should handle computed properties safely', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n\n      // These should return safe defaults\n      expect(typeof vm.focus).toBe('boolean');\n      expect(typeof vm.cursor).toBe('number');\n      expect(typeof vm.length).toBe('number');\n    });\n  });\n\n  describe('Client-Side Hydration', () => {\n    it('should initialize view after mount in browser', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'hydration test',\n        },\n        attachTo: document.body,\n      });\n\n      await nextTick();\n      await nextTick(); // Wait for onMounted to complete\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n\n      // After mounting in browser environment, view should be initialized\n      expect(vm.view).toBeDefined();\n\n      wrapper.unmount();\n    });\n\n    it('should emit ready event after client-side initialization', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'ready test',\n        },\n        attachTo: document.body,\n      });\n\n      await nextTick();\n      await nextTick();\n\n      const readyEvents = wrapper.emitted('ready');\n      expect(readyEvents).toBeTruthy();\n\n      wrapper.unmount();\n    });\n\n    it('should handle modelValue updates after hydration', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'initial',\n        },\n        attachTo: document.body,\n      });\n\n      await nextTick();\n      await nextTick();\n\n      await wrapper.setProps({ modelValue: 'updated' });\n      await nextTick();\n\n      expect(wrapper.props('modelValue')).toBe('updated');\n\n      wrapper.unmount();\n    });\n  });\n\n  describe('Graceful Degradation', () => {\n    it('should render placeholder in SSR', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: '',\n          placeholder: 'Enter your code here',\n        },\n      });\n\n      expect(wrapper.props('placeholder')).toBe('Enter your code here');\n    });\n\n    it('should preserve readonly state in SSR', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'readonly content',\n          readonly: true,\n        },\n      });\n\n      expect(wrapper.props('readonly')).toBe(true);\n    });\n\n    it('should preserve disabled state in SSR', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'disabled content',\n          disabled: true,\n        },\n      });\n\n      expect(wrapper.props('disabled')).toBe(true);\n    });\n\n    it('should handle slots in SSR', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: '',\n        },\n        slots: {\n          default: '<pre>SSR Slot Content</pre>',\n        },\n      });\n\n      expect(wrapper.html()).toContain('SSR Slot Content');\n    });\n  });\n\n  describe('Edge Cases in SSR', () => {\n    it('should handle missing editor ref', () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      const vm = wrapper.vm as unknown as CodeMirrorExposed;\n      // Should not throw\n      expect(vm.editor).toBeDefined();\n    });\n\n    it('should handle rapid prop changes before initialization', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'v1',\n        },\n      });\n\n      // Rapidly change props before view is initialized\n      await wrapper.setProps({ modelValue: 'v2' });\n      await wrapper.setProps({ modelValue: 'v3' });\n      await wrapper.setProps({ modelValue: 'v4' });\n\n      expect(wrapper.props('modelValue')).toBe('v4');\n    });\n\n    it('should handle unmount before initialization', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'test',\n        },\n      });\n\n      // Unmount immediately without waiting for initialization\n      expect(() => wrapper.unmount()).not.toThrow();\n    });\n\n    it('should handle multiple instances', () => {\n      const wrapper1 = mount(CodeMirror, {\n        props: { modelValue: 'instance 1' },\n      });\n      const wrapper2 = mount(CodeMirror, {\n        props: { modelValue: 'instance 2' },\n      });\n      const wrapper3 = mount(CodeMirror, {\n        props: { modelValue: 'instance 3' },\n      });\n\n      expect(wrapper1.props('modelValue')).toBe('instance 1');\n      expect(wrapper2.props('modelValue')).toBe('instance 2');\n      expect(wrapper3.props('modelValue')).toBe('instance 3');\n\n      wrapper1.unmount();\n      wrapper2.unmount();\n      wrapper3.unmount();\n    });\n  });\n\n  describe('Memory Leaks Prevention', () => {\n    it('should clean up properly on unmount', async () => {\n      const wrapper = mount(CodeMirror, {\n        props: {\n          modelValue: 'cleanup test',\n        },\n        attachTo: document.body,\n      });\n\n      await nextTick();\n      await nextTick();\n\n      wrapper.unmount();\n\n      // After unmount, destroy event should be emitted\n      const destroyEvents = wrapper.emitted('destroy');\n      expect(destroyEvents).toBeTruthy();\n    });\n\n    it('should handle multiple mount/unmount cycles', async () => {\n      for (let i = 0; i < 5; i++) {\n        const wrapper = mount(CodeMirror, {\n          props: {\n            modelValue: `cycle ${i}`,\n          },\n          attachTo: document.body,\n        });\n\n        await nextTick();\n        await nextTick();\n\n        expect(wrapper.exists()).toBe(true);\n\n        wrapper.unmount();\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "src/helpers/h-demi.ts",
    "content": "/**\n * h-demi - h function for Vue 2 and 3\n *\n * @see {@link https://github.com/vueuse/vue-demi/issues/65}\n */\n\nimport {\n  h as hDemi,\n  isVue2,\n  type Component,\n  type Slots,\n  type VNode,\n  type VNodeProps,\n} from 'vue-demi';\n\ninterface Options extends VNodeProps {\n  class?: string;\n  domProps?: VNodeProps;\n  on?: Record<string, () => void>;\n  props?: VNodeProps;\n  style?: string;\n  'aria-hidden'?: string;\n}\n\nconst adaptOnsV3 = (\n  ons: Record<string, () => void>\n): Record<string, () => void> => {\n  if (!ons) return {};\n  return Object.entries(ons).reduce((ret, [key, handler]) => {\n    key = key.charAt(0).toUpperCase() + key.slice(1);\n    key = `on${key}`;\n    return { ...ret, [key]: handler };\n  }, {});\n};\n\n/**\n * hDemi function.\n */\nexport default function h(\n  type: string | Component,\n  options: Options = {},\n  children?: VNode | VNode[] | null\n): VNode {\n  if (isVue2) {\n    // Makeshift support :(\n    // Since Vue2.7 includes the Composition API, the functions in vue-demi are not used.\n    return hDemi(type, options, children);\n  }\n  const { props, domProps, on, ...extraOptions } = options;\n  const ons = on ? adaptOnsV3(on) : {};\n\n  return hDemi(\n    type,\n    { ...extraOptions, ...props, ...domProps, ...ons },\n    children\n  );\n}\n\nexport const slot = (\n  defaultSlots: (() => VNode[]) | VNode[] | undefined\n): VNode[] =>\n  typeof defaultSlots === 'function' ? defaultSlots() : (defaultSlots ?? []);\n"
  },
  {
    "path": "src/index.ts",
    "content": "import { indentWithTab } from '@codemirror/commands';\nimport { indentUnit, type LanguageSupport } from '@codemirror/language';\nimport {\n  diagnosticCount as linterDiagnosticCount,\n  forceLinting,\n  linter,\n  lintGutter,\n  type Diagnostic,\n  type LintSource,\n} from '@codemirror/lint';\nimport {\n  Compartment,\n  EditorSelection,\n  EditorState,\n  StateEffect,\n  type Transaction,\n  type Extension,\n  type SelectionRange,\n  type StateField,\n  type Text,\n} from '@codemirror/state';\nimport {\n  EditorView,\n  keymap,\n  placeholder,\n  type KeyBinding,\n  type ViewUpdate,\n} from '@codemirror/view';\nimport { basicSetup, minimalSetup } from 'codemirror';\nimport {\n  computed,\n  defineComponent,\n  nextTick,\n  onMounted,\n  onUnmounted,\n  ref,\n  shallowRef,\n  watch,\n  type App,\n  type ComputedRef,\n  type PropType,\n  type Ref,\n  type ShallowRef,\n  type WritableComputedRef,\n} from 'vue-demi';\n\nimport type { StyleSpec } from 'style-mod';\n\nimport Meta from '@/Meta';\nimport h, { slot } from '@/helpers/h-demi';\n\n/** CodeMirror Component */\nconst CodeMirror = defineComponent({\n  /** Component Name */\n  name: 'CodeMirror',\n  /** Model Definition */\n  model: {\n    prop: 'modelValue',\n    event: 'update:modelValue',\n  },\n  /** Props Definition */\n  props: {\n    /** Model value */\n    modelValue: {\n      type: String as PropType<string | Text>,\n      default: '',\n    },\n    /**\n     * Theme\n     *\n     * @see {@link https://codemirror.net/docs/ref/#view.EditorView^theme}\n     */\n    theme: {\n      type: Object as PropType<Record<string, StyleSpec>>,\n      default: () => {\n        return {};\n      },\n    },\n    /** Dark Mode */\n    dark: {\n      type: Boolean,\n      default: false,\n    },\n    /**\n     * Use Basic Setup\n     *\n     * This will enable the basic setup for the editor.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#codemirror.basicSetup}\n     */\n    basic: {\n      type: Boolean,\n      default: false,\n    },\n    /**\n     * Use Minimal Setup (The basic setting has priority.)\n     *\n     * @see {@link https://codemirror.net/docs/ref/#codemirror.minimalSetup}\n     */\n    minimal: {\n      type: Boolean,\n      default: false,\n    },\n    /**\n     * Placeholder\n     *\n     * @see {@link https://codemirror.net/docs/ref/#view.placeholder}\n     */\n    placeholder: {\n      type: String as PropType<string | HTMLElement>,\n      default: undefined,\n    },\n    /**\n     * Line wrapping\n     *\n     * An extension that enables line wrapping in the editor (by setting CSS white-space to pre-wrap in the content).\n     *\n     * @see {@link https://codemirror.net/docs/ref/#view.EditorView%5ElineWrapping}\n     */\n    wrap: {\n      type: Boolean,\n      default: false,\n    },\n    /**\n     * Allow tab key indent.\n     *\n     * This will enable the tab key to indent the current line or selection.\n     *\n     * @see {@link https://codemirror.net/examples/tab/}\n     */\n    tab: {\n      type: Boolean,\n      default: false,\n    },\n    /**\n     * Tab character\n     *\n     * This is the unit of indentation used when the editor is configured to indent with tabs.\n     * It is also used to determine the size of the tab character when the editor is configured to use tabs for indentation..\n     *\n     * @see {@link https://codemirror.net/docs/ref/#state.EditorState^indentUnit}\n     */\n    indentUnit: {\n      type: String,\n      default: undefined,\n    },\n    /**\n     * Allow Multiple Selection.\n     *\n     * This allows the editor to have multiple selections at the same time.\n     * This is useful for editing multiple parts of the document at once.\n     * If this is set to true, the editor will allow multiple selections.\n     * If this is set to false, the editor will only allow a single selection.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#state.EditorState^allowMultipleSelections}\n     */\n    allowMultipleSelections: {\n      type: Boolean,\n      default: false,\n    },\n    /**\n     * Tab size\n     *\n     * This is the number of spaces that a tab character represents in the editor.\n     * It is used to determine the size of the tab character when the editor is configured to use tabs for indentation.\n     * If this is set to a number, the editor will use that number of spaces for each tab character.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#state.EditorState^tabSize}\n     */\n    tabSize: {\n      type: Number,\n      default: undefined,\n    },\n    /**\n     * Set line break (separetor) char.\n     *\n     * This is the character that is used to separate lines in the editor.\n     * It is used to determine the line break character when the editor is configured to use a specific line break character.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#state.EditorState^lineSeparator}\n     */\n    lineSeparator: {\n      type: String,\n      default: undefined,\n    },\n    /**\n     * Readonly\n     *\n     * This is a CodeMirror Facet that allows you to set the editor to read-only mode.\n     * When this is set to true, the editor will not allow any changes to be made to the document.\n     * This is useful for displaying code that should not be edited, such as documentation or examples.\n     * If this is set to false, the editor will allow changes to be made to the document.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#state.EditorState^readOnly}\n     */\n    readonly: {\n      type: Boolean,\n      default: false,\n    },\n    /**\n     * Disable input.\n     *\n     * This is the reversed value of the CodeMirror editable.\n     * Similar to `readonly`, but setting this value to true disables dragging.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#view.EditorView^editable}\n     */\n    disabled: {\n      type: Boolean,\n      default: false,\n    },\n    /**\n     * Additional Extension\n     *\n     * You can use this to add any additional extensions that you want to use in the editor.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#state.Extension}\n     */\n    extensions: {\n      type: Array as PropType<Extension[]>,\n      default: () => {\n        return [];\n      },\n    },\n    /**\n     * Language Phreses\n     *\n     * This is a CodeMirror Facet that allows you to define custom phrases for the editor.\n     * It can be used to override default phrases or add new ones.\n     * This is useful for translating the editor to different languages or for customizing the editor's UI.\n     *\n     * @see {@link https://codemirror.net/examples/translate/}\n     */\n    phrases: {\n      type: Object as PropType<Record<string, string>>,\n      default: undefined,\n    },\n    /**\n     * CodeMirror Language\n     *\n     * This is a CodeMirror Facet that allows you to define the language of the editor.\n     * It can be used to enable syntax highlighting and other language-specific features.\n     * It is useful for displaying code in a specific language, such as JavaScript, Python, or HTML.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#language}\n     */\n    lang: {\n      type: Object as PropType<LanguageSupport>,\n      default: undefined,\n    },\n    /**\n     * CodeMirror Linter\n     *\n     * This is a CodeMirror Facet that allows you to define a linter for the editor.\n     * It can be used to check the code for errors and warnings, and to provide feedback to the user.\n     * It is useful for displaying code in a specific language, such as JavaScript, Python, or HTML.\n     * This is useful for providing feedback to the user about the code they are writing.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#lint.linter}\n     */\n    linter: {\n      type: Function as PropType<LintSource>,\n      default: undefined,\n    },\n    /**\n     * Linter Config\n     *\n     * This is a CodeMirror Facet that allows you to define the configuration for the linter.\n     * It can be used to specify options for the linter, such as the severity of errors and warnings, and to customize the behavior of the linter.\n     * This is useful for providing feedback to the user about the code they are writing.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#lint.linter^config}\n     */\n    linterConfig: {\n      type: Object,\n      default: () => {\n        return {};\n      },\n    },\n    /**\n     * Forces any linters configured to run when the editor is idle to run right away.\n     *\n     * This is useful for running linters on the initial load of the editor, or when the user has made changes to the code and wants to see the results immediately.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#lint.forceLinting}\n     */\n    forceLinting: {\n      type: Boolean,\n      default: false,\n    },\n    /**\n     * Show Linter Gutter\n     *\n     * An area to 🔴 the lines with errors will be displayed.\n     * This feature is not enabled if `linter` is not specified.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#lint.lintGutter}\n     */\n    gutter: {\n      type: Boolean,\n      default: false,\n    },\n    /**\n     * Gutter Config\n     *\n     * This is a CodeMirror Facet that allows you to define the configuration for the gutter.\n     * It can be used to specify options for the gutter, such as the size of the gutter, the position of the gutter, and to customize the behavior of the gutter.\n     * This is useful for providing feedback to the user about the code they are writing.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#lint.lintGutter^config}\n     */\n    gutterConfig: {\n      type: Object,\n      default: undefined,\n    },\n    /**\n     * Using tag\n     */\n    tag: {\n      type: String,\n      default: 'div',\n    },\n    /**\n     * Allows an external update to scroll the form.\n     *\n     * This is useful for scrolling the editor to a specific position when the user has made changes to the code and wants to see the results immediately.\n     * If this is set to true, the editor will scroll to the position specified in the transaction.\n     * If this is set to false, the editor will not scroll to the position specified in the transaction.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#state.TransactionSpec.scrollIntoView}\n     */\n    scrollIntoView: {\n      type: Boolean,\n      default: true,\n    },\n    /**\n     * Preserve the current scroll position on external updates.\n     *\n     * This keeps the editor's own scroll container from jumping when\n     * `modelValue` is updated from outside the component.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#view.EditorView.scrollSnapshot}\n     */\n    preserveScrollPosition: {\n      type: Boolean,\n      default: false,\n    },\n    /**\n     * Key map\n     * This is a CodeMirror Facet that allows you to define custom key bindings.\n     * It can be used to override default key bindings or add new ones.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#view.keymap}\n     */\n    keymap: {\n      type: Array as PropType<KeyBinding[]>,\n      default: () => [],\n    },\n  },\n  /** Emits */\n  emits: {\n    /** Model Update */\n    'update:modelValue': (_value: string | Text = '') => true,\n    /** CodeMirror ViewUpdate */\n    update: (_value: ViewUpdate) => true,\n    /** CodeMirror onReady */\n    ready: (_value: {\n      view: EditorView;\n      state: EditorState;\n      container: HTMLElement;\n    }) => true,\n    /** CodeMirror onFocus */\n    focus: (_value: boolean) => true,\n    /** State Changed */\n    change: (_value: EditorState) => true,\n    /** CodeMirror onDestroy */\n    destroy: () => true,\n  },\n  /**\n   * Setup\n   *\n   * @param props  - Props\n   * @param context - Context\n   */\n  setup(props, context) {\n    /** Editor DOM */\n    const editor: Ref<HTMLElement | undefined> = ref();\n\n    /** Internal value */\n    const doc: Ref<string | Text> = ref(props.modelValue);\n\n    /**\n     * CodeMirror Editor View\n     *\n     * @see {@link https://codemirror.net/docs/ref/#view.EditorView}\n     */\n    const view: ShallowRef<EditorView | undefined> = shallowRef(undefined);\n\n    /**\n     * Focus\n     *\n     * @see {@link https://codemirror.net/docs/ref/#view.EditorView.hasFocus}\n     */\n    const focus: WritableComputedRef<boolean> = computed({\n      get: () => view.value?.hasFocus ?? false,\n      set: f => {\n        if (f && view.value) {\n          view.value.focus();\n        }\n      },\n    });\n\n    /**\n     * Editor Selection\n     *\n     * @see {@link https://codemirror.net/docs/ref/#state.EditorSelection}\n     */\n    const selection: WritableComputedRef<EditorSelection | undefined> =\n      computed({\n        get: () => view.value?.state.selection,\n        set: selection => {\n          if (view.value && selection) {\n            view.value.dispatch({ selection });\n          }\n        },\n      });\n\n    /** Cursor Position */\n    const cursor: WritableComputedRef<number> = computed({\n      get: () => view.value?.state.selection.main.head ?? 0,\n      set: anchor => {\n        if (view.value) {\n          view.value.dispatch({ selection: { anchor } });\n        }\n      },\n    });\n\n    /** JSON */\n    const json: WritableComputedRef<\n      Record<string, StateField<unknown>> | undefined\n    > = computed({\n      get: () => view.value?.state.toJSON(),\n      set: j => {\n        if (view.value && j) {\n          view.value.setState(EditorState.fromJSON(j));\n        }\n      },\n    });\n\n    /** Text length */\n    const length: Ref<number> = ref(0);\n\n    /**\n     * Returns the number of active lint diagnostics in the given state.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#lint.diagnosticCount}\n     */\n    const diagnosticCount: Ref<number> = ref(0);\n\n    /** Get CodeMirror Extension */\n    const extensions: ComputedRef<Extension[]> = computed(() => {\n      // Synamic Reconfiguration\n      // @see https://codemirror.net/examples/config/\n      const language = new Compartment();\n      const tabSize = new Compartment();\n      if (props.basic && props.minimal) {\n        throw new Error(\n          '[Vue CodeMirror] Both basic and minimal cannot be specified.'\n        );\n      }\n      /** Keymap */\n      let keymaps: KeyBinding[] = [];\n      if (props.keymap && props.keymap.length > 0) {\n        // If keymap is specified, use it.\n        keymaps = props.keymap;\n      }\n      if (props.tab) {\n        // If tab is enabled, add indentWithTab to keymap.\n        keymaps.push(indentWithTab);\n      }\n\n      // TODO: Ignore previous prop was not changed.\n      return [\n        // Toggle basic setup\n        props.basic && !props.minimal ? basicSetup : undefined,\n        // Toggle minimal setup\n        props.minimal && !props.basic ? minimalSetup : undefined,\n        // ViewUpdate event listener\n        EditorView.updateListener.of((update: ViewUpdate): void => {\n          if (!view.value) {\n            return;\n          }\n          // Emit focus status\n          context.emit('focus', view.value.hasFocus);\n\n          // Update count\n          length.value = view.value.state.doc?.length;\n\n          if (update.changes.empty || !update.docChanged) {\n            // Suppress event firing if no change\n            return;\n          }\n          if (props.linter) {\n            // Linter process\n            if (props.forceLinting) {\n              // If forceLinting enabled, first liting.\n              forceLinting(view.value);\n            }\n            // Count diagnostics.\n            diagnosticCount.value = (\n              props.linter(view.value) as readonly Diagnostic[]\n            ).length;\n          }\n          context.emit('update', update);\n        }),\n        // Toggle light/dark mode.\n        EditorView.theme(props.theme, { dark: props.dark }),\n        // Toggle line wrapping\n        props.wrap ? EditorView.lineWrapping : undefined,\n        // Tab character\n        props.indentUnit ? indentUnit.of(props.indentUnit) : undefined,\n        // Allow Multiple Selections\n        EditorState.allowMultipleSelections.of(props.allowMultipleSelections),\n        // Indent tab size\n        props.tabSize\n          ? tabSize.of(EditorState.tabSize.of(props.tabSize))\n          : undefined,\n        // locale settings\n        props.phrases ? EditorState.phrases.of(props.phrases) : undefined,\n        // Readonly option\n        EditorState.readOnly.of(props.readonly),\n        // Editable option\n        EditorView.editable.of(!props.disabled),\n        // Set Line break char\n        props.lineSeparator\n          ? EditorState.lineSeparator.of(props.lineSeparator)\n          : undefined,\n        // Lang\n        props.lang ? language.of(props.lang) : undefined,\n        // Append Linter settings\n        props.linter ? linter(props.linter, props.linterConfig) : undefined,\n        // Show 🔴 to error line when linter enabled.\n        props.linter && props.gutter\n          ? lintGutter(props.gutterConfig)\n          : undefined,\n        // Placeholder\n        props.placeholder ? placeholder(props.placeholder) : undefined,\n        // Keymap and Indent with Tab\n        keymaps.length > 0 ? keymap.of(keymaps) : undefined,\n        // Append Extensions\n        ...props.extensions,\n      ].filter((extension): extension is Extension => !!extension); // Filter undefined\n    });\n\n    // Extension (mostly props) Changed\n    watch(\n      extensions,\n      exts =>\n        view.value?.dispatch({ effects: StateEffect.reconfigure.of(exts) }),\n      { immediate: true }\n    );\n\n    // for parent-to-child binding.\n    watch(\n      () => props.modelValue,\n      async value => {\n        if (!view.value) {\n          return;\n        }\n        if (\n          view.value.composing || // IME fix\n          view.value.state.doc.toJSON().join(props.lineSeparator ?? '\\n') ===\n            value // don't need to update\n        ) {\n          // Do not commit CodeMirror's store.\n          return;\n        }\n\n        // Range Fix ?\n        // https://github.com/logue/vue-codemirror6/issues/27\n        const isSelectionOutOfRange = !view.value.state.selection.ranges.every(\n          range => range.anchor < value.length && range.head < value.length\n        );\n\n        /** Scroll Fix */\n        const changes = {\n          from: 0,\n          to: view.value.state.doc.length,\n          insert: value,\n        };\n        // If preserveScrollPosition is enabled, create a scroll snapshot before updating the document.\n        const scrollSnapshot = props.preserveScrollPosition\n          ? view.value.scrollSnapshot().map(view.value.state.changes(changes))\n          : undefined;\n\n        // Update\n        view.value.dispatch({\n          changes,\n          selection: isSelectionOutOfRange\n            ? { anchor: 0, head: 0 }\n            : view.value.state.selection,\n          scrollIntoView: props.scrollIntoView,\n          effects: scrollSnapshot ? [scrollSnapshot] : undefined,\n        });\n      },\n      { immediate: true }\n    );\n\n    /** When loaded */\n    onMounted(async () => {\n      // Skip initialization in SSR environment\n      if (globalThis.window === undefined || !editor.value) {\n        return;\n      }\n\n      /** Initial value */\n      let value: string | Text = doc.value;\n\n      if (editor.value.childNodes[0]) {\n        // when slot mode, overwrite initial value\n        if (doc.value !== '') {\n          console.warn(\n            '[CodeMirror.vue] The <code-mirror> tag contains child elements that overwrite the `v-model` values.'\n          );\n        }\n        value = (editor.value.childNodes[0] as HTMLElement).innerText.trim();\n      }\n\n      // Register Codemirror\n      view.value = new EditorView({\n        parent: editor.value,\n        state: EditorState.create({ doc: value, extensions: extensions.value }),\n        dispatch: (tr: Transaction) => {\n          if (!view.value) {\n            return;\n          }\n          view.value.update([tr]);\n          if (tr.changes.empty || !tr.docChanged) {\n            // if not change value, no fire emit event\n            return;\n          }\n\n          // console.log(view.state.doc.toString(), tr);\n          // state.toString() is not defined, so use toJSON and toText function to convert string.\n          context.emit('update:modelValue', tr.state.doc.toString());\n          // Emit EditorState\n          context.emit('change', tr.state);\n        },\n      });\n\n      await nextTick();\n\n      context.emit('ready', {\n        view: view.value,\n        state: view.value.state,\n        container: editor.value,\n      });\n    });\n\n    /** Destroy */\n    onUnmounted(() => {\n      if (view.value) {\n        view.value.destroy();\n        context.emit('destroy');\n      }\n    });\n\n    /**\n     * Forces any linters configured to run when the editor is idle to run right away.\n     *\n     * @see {@link https://codemirror.net/docs/ref/#lint.forceLinting}\n     */\n    const lint = (): void => {\n      if (!props.linter || !view.value) {\n        return;\n      }\n      if (props.forceLinting) {\n        forceLinting(view.value);\n      }\n      diagnosticCount.value = linterDiagnosticCount(view.value.state);\n    };\n\n    /**\n     * Force Reconfigure Extension\n     *\n     * @see {@link https://codemirror.net/examples/config/#top-level-reconfiguration}\n     */\n    const forceReconfigure = (): void => {\n      // Deconfigure all Extensions\n      view.value?.dispatch({\n        effects: StateEffect.reconfigure.of([]),\n      });\n      // Register extensions\n      view.value?.dispatch({\n        effects: StateEffect.appendConfig.of(extensions.value),\n      });\n    };\n\n    /* ----- Bellow is experimental. ------ */\n\n    /**\n     * Get the text between the given points in the editor.\n     *\n     * @param from - start line number\n     * @param to - end line number\n     */\n    const getRange = (from?: number, to?: number): string | undefined =>\n      view.value?.state.sliceDoc(from, to);\n    /**\n     * Get the content of line.\n     *\n     * @param number - line number\n     */\n    const getLine = (number: number): string | undefined =>\n      view.value?.state.doc.line(number + 1).text;\n    /** Get the number of lines in the editor. */\n    const lineCount = (): number => view.value?.state.doc.lines ?? 0;\n    /** Retrieve one end of the primary selection. */\n    const getCursor = (): number => view.value?.state.selection.main.head ?? 0;\n    /** Retrieves a list of all current selections. */\n    const listSelections = (): readonly SelectionRange[] => {\n      return view.value?.state.selection.ranges ?? [];\n    };\n    /** Get the currently selected code. */\n    const getSelection = (): string => {\n      if (!view.value) {\n        return '';\n      }\n      return view.value.state.sliceDoc(\n        view.value.state.selection.main.from,\n        view.value.state.selection.main.to\n      );\n    };\n    /**\n     * The length of the given array should be the same as the number of active selections.\n     * Replaces the content of the selections with the strings in the array.\n     */\n    const getSelections = (): string[] => {\n      const s = view.value?.state;\n      if (!s) {\n        return [];\n      }\n\n      return s.selection.ranges.map((r: { from: number; to: number }) =>\n        s.sliceDoc(r.from, r.to)\n      );\n    };\n    /** Return true if any text is selected. */\n    const somethingSelected = (): boolean =>\n      view.value?.state.selection.ranges.some(\n        (r: { empty: boolean }) => !r.empty\n      ) ?? false;\n\n    /**\n     * Replace the part of the document between from and to with the given string.\n     *\n     * @param replacement - replacement text\n     * @param from - start string at position\n     * @param to -  insert the string at position\n     */\n    const replaceRange = (\n      replacement: string | Text,\n      from: number,\n      to: number\n    ): void => {\n      if (view.value) {\n        view.value.dispatch({\n          changes: { from, to, insert: replacement },\n        });\n      }\n    };\n    /**\n     * Replace the selection(s) with the given string.\n     * By default, the new selection ends up after the inserted text.\n     *\n     * @param replacement - replacement text\n     */\n    const replaceSelection = (replacement: string | Text): void => {\n      if (view.value) {\n        view.value.dispatch(view.value.state.replaceSelection(replacement));\n      }\n    };\n    /**\n     * Set the cursor position.\n     *\n     * @param position - position.\n     */\n    const setCursor = (position: number): void => {\n      if (view.value) {\n        view.value.dispatch({ selection: { anchor: position } });\n      }\n    };\n    /**\n     * Set a single selection range.\n     *\n     * @param anchor - anchor position\n     * @param head -\n     */\n    const setSelection = (anchor: number, head?: number): void => {\n      if (view.value) {\n        view.value.dispatch({ selection: { anchor, head } });\n      }\n    };\n    /**\n     * Sets a new set of selections. There must be at least one selection in the given array.\n     *\n     * @param ranges - Selection range\n     * @param primary -\n     */\n    const setSelections = (\n      ranges: readonly SelectionRange[],\n      primary?: number\n    ): void => {\n      if (view.value) {\n        view.value.dispatch({\n          selection: EditorSelection.create(ranges, primary),\n        });\n      }\n    };\n    /**\n     * Applies the given function to all existing selections, and calls extendSelections on the result.\n     *\n     * @param f - function\n     */\n    const extendSelectionsBy = (f: (range: SelectionRange) => number): void => {\n      if (view.value && selection.value) {\n        view.value.dispatch({\n          selection: EditorSelection.create(\n            selection.value.ranges.map((r: SelectionRange) => r.extend(f(r)))\n          ),\n        });\n      }\n    };\n\n    const exposed = {\n      editor,\n      view,\n      cursor,\n      selection,\n      focus,\n      length,\n      json,\n      diagnosticCount,\n      dom: view.value?.contentDOM,\n      lint,\n      forceReconfigure,\n      // Bellow is CodeMirror5's function\n      getRange,\n      getLine,\n      lineCount,\n      getCursor,\n      listSelections,\n      getSelection,\n      getSelections,\n      somethingSelected,\n      replaceRange,\n      replaceSelection,\n      setCursor,\n      setSelection,\n      setSelections,\n      extendSelectionsBy,\n    };\n\n    /** Export properties and functions */\n    context.expose(exposed);\n    return exposed;\n  },\n  render() {\n    // <template>\n    //   <div ref=\"editor\" class=\"vue-codemirror\">\n    //     <aside v-show=\"!context.slots.default\" aria-hidden><slot /></aside>\n    //   </div>\n    // </template>\n    return h(\n      this.$props.tag,\n      {\n        ref: 'editor',\n        class: 'vue-codemirror',\n      },\n      this.$slots.default\n        ? // Hide original content\n          h(\n            'aside',\n            { style: 'display: none;', 'aria-hidden': 'true' },\n            slot(this.$slots.default)\n          )\n        : undefined\n    );\n  },\n});\n\nconst installCodeMirror = (app: App): void => {\n  app.component('CodeMirror', CodeMirror);\n};\n\n/** Public API exposed from the CodeMirror component instance.\n * Note: Vue 3 auto-unwraps refs on the component instance proxy,\n * so reactive refs appear as their underlying value types here.\n */\nexport type CodeMirrorExposed = {\n  editor: HTMLElement | undefined;\n  view: EditorView | undefined;\n  cursor: number;\n  selection: EditorSelection | undefined;\n  focus: boolean;\n  length: number;\n  json: Record<string, StateField<unknown>> | undefined;\n  diagnosticCount: number;\n  dom: Element | undefined;\n  lint: () => void;\n  forceReconfigure: () => void;\n  getRange: (from?: number, to?: number) => string | undefined;\n  getLine: (number: number) => string | undefined;\n  lineCount: () => number;\n  getCursor: () => number;\n  listSelections: () => readonly SelectionRange[];\n  getSelection: () => string;\n  getSelections: () => string[];\n  somethingSelected: () => boolean;\n  replaceRange: (replacement: string | Text, from: number, to: number) => void;\n  replaceSelection: (replacement: string | Text) => void;\n  setCursor: (position: number) => void;\n  setSelection: (anchor: number, head?: number) => void;\n  setSelections: (ranges: readonly SelectionRange[], primary?: number) => void;\n  extendSelectionsBy: (f: (range: SelectionRange) => number) => void;\n};\n\nexport { CodeMirror as default, installCodeMirror as install, Meta };\n"
  },
  {
    "path": "src/interfaces/MetaInterface.ts",
    "content": "/** Build information meta data */\ntype MetaInterface = {\n  /** Version */\n  version: string;\n  /** Build date */\n  date: string;\n};\n\nexport default MetaInterface;\n"
  },
  {
    "path": "src-docs/App.vue",
    "content": "<script setup lang=\"ts\">\nimport DemoPage from './DemoPage.vue';\nimport ToggleTheme from './components/ToggleTheme.vue';\n</script>\n\n<!-- eslint-disable vuejs-accessibility/anchor-has-content -->\n<template>\n  <nav class=\"navbar navbar-expand-md bg-dark\" data-bs-theme=\"dark\">\n    <div class=\"container-fluid d-flex justify-content-between\">\n      <a class=\"navbar-brand\" href=\"#\">Vue CodeMirror6</a>\n      <button\n        class=\"navbar-toggler\"\n        type=\"button\"\n        data-bs-toggle=\"collapse\"\n        data-bs-target=\"#navbarCollapse\"\n        aria-controls=\"navbarCollapse\"\n        aria-expanded=\"false\"\n        aria-label=\"Toggle navigation\"\n      >\n        <span class=\"navbar-toggler-icon\" />\n      </button>\n      <div id=\"navbarCollapse\" class=\"collapse navbar-collapse flex-grow-0\">\n        <ul class=\"navbar-nav\">\n          <li class=\"nav-item\">\n            <a class=\"nav-link\" href=\"https://github.com/logue/vue-codemirror6\">\n              <svg\n                xmlns=\"http://www.w3.org/2000/svg\"\n                width=\"16\"\n                height=\"16\"\n                fill=\"currentColor\"\n                class=\"bi bi-github\"\n                viewBox=\"0 0 16 16\"\n              >\n                <path\n                  d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z\"\n                />\n              </svg>\n            </a>\n          </li>\n          <li class=\"nav-item\">\n            <toggle-theme class=\"nav-link\" attribute=\"data-bs-theme\" />\n          </li>\n        </ul>\n      </div>\n    </div>\n  </nav>\n  <header class=\"bg-body-tertiary\">\n    <div class=\"container py-3\">\n      <h1>Vue CodeMirror6 Demo</h1>\n      <p class=\"lead\">\n        A rough demo of Vue CodeMirror6 in action. You can switch between dark\n        modes from the\n        <i class=\"bi bi-circle-half\" />\n        icon in the upper right.\n      </p>\n    </div>\n  </header>\n\n  <main class=\"flex-glow-0 pt-4 bg-body\">\n    <demo-page />\n  </main>\n\n  <footer class=\"footer mt-auto py-3 mb-0 bg-body-tertiary\">\n    <div class=\"container mb-0\">\n      &copy; 2022-2026 by\n      <a href=\"http://logue.dev/\">Logue</a>\n      . Licensed under the\n      <a href=\"http://opensource.org/licenses/mit-license.php\">MIT License</a>\n      .\n    </div>\n  </footer>\n</template>\n"
  },
  {
    "path": "src-docs/DemoPage.vue",
    "content": "<!-- eslint-disable import-x/no-duplicates -- for Demo source code use. -->\n<script setup lang=\"ts\">\nimport { vue } from '@codemirror/lang-vue';\nimport { useDark } from '@vueuse/core';\n// eslint-disable-next-line import-x/no-unresolved -- This is a demo component, and the CodeMirror component is only used here for demonstration purposes. It is not intended to be imported in other components.\nimport CodeMirror from 'vue-codemirror6';\n\nimport KeyMapDemo from './components/KeyMapDemo.vue';\nimport KeyMapDemoSrc from './components/KeyMapDemo.vue?raw';\nimport LinterAndCrossBindingDemo from './components/LinterAndCrossBindingDemo.vue';\nimport LinterAndCrossBindingDemoSrc from './components/LinterAndCrossBindingDemo.vue?raw';\nimport MarkdownDemo from './components/MarkdownDemo.vue';\nimport MarkdownDemoSrc from './components/MarkdownDemo.vue?raw';\nimport ReadonlyAndDisabledDemo from './components/ReadonlyAndDisabledDemo.vue';\nimport ReadonlyAndDisabledDemoSrc from './components/ReadonlyAndDisabledDemo.vue?raw';\nimport SlotDemo from './components/SlotDemo.vue';\nimport SlotDemoSrc from './components/SlotDemo.vue?raw';\n\nconst dark = useDark();\n\nconst markdownDemoSrc = MarkdownDemoSrc.trim();\nconst slotDemoSrc = SlotDemoSrc.trim();\nconst readonlyAndDisabledDemoSrc = ReadonlyAndDisabledDemoSrc.trim();\nconst linterAndCrossBindingDemoSrc = LinterAndCrossBindingDemoSrc.trim();\nconst keyMapDemoSrc = KeyMapDemoSrc.trim();\n</script>\n\n<template>\n  <div class=\"container\">\n    <section class=\"mb-5\">\n      <h2>Markdown Editor Demo</h2>\n      <p>\n        This is an example of simply pouring text into CodeMirror using\n        <code>v-model</code>\n        .\n      </p>\n      <p>\n        <code>basic</code>\n        is an alias for loading\n        <a\n          href=\"https://codemirror.net/6/docs/ref/#basic-setup\"\n          target=\"_blank\"\n        >\n          basic-setup\n        </a>\n        .\n        <br />\n        Use\n        <code>wrap</code>\n        when you want to use columns. (Enable text wrapping)\n      </p>\n      <code-mirror\n        v-model=\"markdownDemoSrc\"\n        :dark=\"dark\"\n        :lang=\"vue()\"\n        basic\n        wrap\n        readonly\n      />\n      <h3>Demo</h3>\n      <markdown-demo :dark=\"dark\" class=\"mb-3\" />\n      <div class=\"alert alert-info d-flex align-items-center my-3\" role=\"alert\">\n        <div class=\"bi flex-shrink-0 me-2 fs-2\" role=\"img\" aria-label=\"Info:\">\n          <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            width=\"32\"\n            height=\"32\"\n            fill=\"currentColor\"\n            class=\"bi bi-info-circle\"\n            viewBox=\"0 0 16 16\"\n          >\n            <path\n              d=\"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z\"\n            />\n            <path\n              d=\"m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z\"\n            />\n          </svg>\n        </div>\n        <div>\n          The process of converting Markdown to HTML uses\n          <a href=\"https://github.com/logue/vue-markdown-wasm\" target=\"_blank\">\n            vue-markdown-wasm\n          </a>\n          .\n          <br />\n          Full demo is\n          <a href=\"https://logue.dev/vue-markdown-wasm\" target=\"_blank\">here</a>\n          .\n        </div>\n      </div>\n    </section>\n    <section class=\"mb-5\">\n      <h2>Slot Method</h2>\n      <p>\n        In this sample, the text is put directly inside the\n        <code>&lt;code-mirror&gt;</code>\n        tag to make it the initial string. On the Vue side, it is evaluated as a\n        DOM node and only the text node is used as the value. In addition, it\n        does not work with Vue2.7.\n      </p>\n      <p>\n        It's just for simple syntax highlighting. Do not use with\n        <code>v-model</code>\n        .\n      </p>\n      <code-mirror\n        v-model=\"slotDemoSrc\"\n        :dark=\"dark\"\n        :lang=\"vue()\"\n        basic\n        wrap\n        readonly\n      />\n      <h3>Sample</h3>\n      <slot-demo :dark=\"dark\" />\n    </section>\n    <section class=\"mb-5\">\n      <h2>Linter and cross binding demo</h2>\n      <p>This is a sample using JavaScript and linter.</p>\n      <p>\n        When using\n        <code>gutter</code>\n        prop, 🔴 is displayed on the line with the error.\n      </p>\n      <p>\n        This sample uses\n        <a\n          href=\"https://github.com/UziTech/eslint-linter-browserify\"\n          target=\"_blank\"\n        >\n          eslint-linter-browserify\n        </a>\n        for the eslint linter.\n      </p>\n      <code-mirror\n        v-model=\"linterAndCrossBindingDemoSrc\"\n        :dark=\"dark\"\n        :lang=\"vue()\"\n        basic\n        wrap\n        readonly\n      />\n      <h3>Sample</h3>\n      <p>Make sure you see 🔴 when you change the value to get an error.</p>\n      <p>\n        The value of\n        <code>@update</code>\n        gets the\n        <a\n          href=\"https://codemirror.net/6/docs/ref/#view.ViewUpdate\"\n          target=\"_blank\"\n        >\n          ViewUpdate\n        </a>\n        object at that time when there is any update in the target form.\n      </p>\n      <p>\n        In this demo code, the\n        <a\n          href=\"https://codemirror.net/docs/ref/#lint.diagnosticCount\"\n          target=\"_blank\"\n        >\n          diagnosticCount\n        </a>\n        function is used to display the count of locations where grammatical\n        errors are found.\n      </p>\n      <linter-and-cross-binding-demo :dark=\"dark\" />\n      <p>Also, make sure that changing either value reflects that value.</p>\n    </section>\n    <section class=\"mb-5\">\n      <h2>\n        Toggle\n        <code>readonly</code>\n        and\n        <code>disabled</code>\n        a demo\n      </h2>\n      <p>\n        <a\n          href=\"https://codemirror.net/docs/ref/#view.EditorView%5Eeditable\"\n          target=\"_blank\"\n        >\n          <code>readonly</code>\n        </a>\n        a specifies whether the state is rewritable or not. Similar to\n        <code>disabled</code>\n        (Inverse value of\n        <a\n          href=\"https://codemirror.net/docs/ref/#view.EditorView%5Eeditable\"\n          target=\"_blank\"\n        >\n          <code>editable</code>\n        </a>\n        ) , except that it is focusable. In short, add\n        <code>disabled</code>\n        prop to if you want to use it as a simple syntax highlighter.\n      </p>\n      <div class=\"row\">\n        <div class=\"col-sm\">\n          <code-mirror\n            v-model=\"readonlyAndDisabledDemoSrc\"\n            :dark=\"dark\"\n            :lang=\"vue()\"\n            basic\n            wrap\n            readonly\n          />\n        </div>\n        <div class=\"col-sm\">\n          <h3>Demo</h3>\n          <readonly-and-disabled-demo :dark=\"dark\" />\n        </div>\n      </div>\n    </section>\n    <section class=\"mb-5\">\n      <h2>Key Map Demo</h2>\n      <p>\n        This is a sample that allows you to define your own keymap. The\n        <code>keymap</code>\n        prop is an array of objects that define the keymap.\n      </p>\n      <p>\n        The\n        <code>run</code>\n        function is called when the keymap is matched. If it returns\n        <code>true</code>\n        , the default behavior of the keymap is not executed.\n      </p>\n      <div class=\"row\">\n        <div class=\"col-sm\">\n          <code-mirror\n            v-model=\"keyMapDemoSrc\"\n            :dark=\"dark\"\n            :lang=\"vue()\"\n            basic\n            wrap\n            readonly\n          />\n        </div>\n        <div class=\"col-sm\">\n          <h3>Demo</h3>\n          <p>Press Shift+Ctrl+Enter to see the console log.</p>\n          <key-map-demo />\n        </div>\n      </div>\n    </section>\n  </div>\n</template>\n"
  },
  {
    "path": "src-docs/components/KeyMapDemo.vue",
    "content": "<script lang=\"ts\" setup>\nimport { ref } from 'vue';\n\n// eslint-disable-next-line import-x/no-unresolved -- This is a demo component, and the CodeMirror component is only used here for demonstration purposes. It is not intended to be imported in other components.\nimport CodeMirror from 'vue-codemirror6';\n\nconst temp = ref('Press Shift+Ctrl+Enter here to see the console log.');\n</script>\n\n<template>\n  <code-mirror\n    v-model=\"temp\"\n    :keymap=\"[\n      {\n        key: 'Shift-Ctrl-Enter',\n        run: () => {\n          console.log('Shift+Ctrl+Enter');\n          return true;\n        },\n      },\n    ]\"\n    tab\n    basic\n  />\n</template>\n"
  },
  {
    "path": "src-docs/components/LinterAndCrossBindingDemo.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref, type Ref } from 'vue';\n\nimport { javascript, esLint } from '@codemirror/lang-javascript';\n// Uses linter.mjs\nimport eslint from 'eslint-linter-browserify';\n// eslint-disable-next-line import-x/no-unresolved -- This is a demo component, and the CodeMirror component is only used here for demonstration purposes. It is not intended to be imported in other components.\nimport CodeMirror from 'vue-codemirror6';\n\n// Sync Dark mode\ndefineProps<{ dark?: boolean }>();\n\n/** CodeMirror Instance */\nconst cm: Ref<InstanceType<typeof CodeMirror> | undefined> = ref();\n\n/** Demo code */\nconst value: Ref<string> = ref(`document.querySelectorAll('.btn').forEach(\n  element => ああああelement.addEventListner('click', alert('あああああ'));\n);`);\n\nconst focused: Ref<boolean> = ref(false);\n\n/**\n * JavaScript language Linter Setting.\n * Using eslint-linter-browserify\n *\n * @see {@link https://github.com/UziTech/eslint-linter-browserify#eslint-linter-browserify}\n */\nconst linter = esLint(new eslint.Linter(), {\n  languageOptions: {\n    parserOptions: {\n      ecmaVersion: 2022,\n      sourceType: 'module',\n    },\n  },\n  rules: {\n    semi: ['error', 'never'],\n  },\n});\n\nconst onFocus = (f: boolean): void => {\n  focused.value = f;\n};\n</script>\n\n<!-- eslint-disable vuejs-accessibility/label-has-for -->\n<template>\n  <div class=\"row\">\n    <div class=\"col-6\">\n      <code-mirror\n        ref=\"cm\"\n        v-model=\"value\"\n        :dark=\"dark\"\n        :lang=\"javascript()\"\n        :linter=\"linter\"\n        class=\"mb-3\"\n        basic\n        gutter\n        wrap\n        @focus=\"onFocus\"\n      />\n      <div class=\"row mb-3\">\n        <div class=\"col-4\">\n          <div class=\"input-group\">\n            <label for=\"count\" class=\"input-group-text\">Count</label>\n            <input\n              id=\"count\"\n              :value=\"cm?.length\"\n              type=\"text\"\n              class=\"form-control\"\n              readonly\n            />\n          </div>\n        </div>\n        <div class=\"col-5\">\n          <div class=\"input-group\">\n            <label for=\"diagnosticCount\" class=\"input-group-text\">\n              Diagnostic Count\n            </label>\n            <input\n              id=\"diagnosticCount\"\n              :value=\"cm?.diagnosticCount\"\n              type=\"number\"\n              class=\"form-control\"\n              readonly\n            />\n          </div>\n        </div>\n        <div class=\"col-3\">\n          <div class=\"form-check form-check-inline\">\n            <input\n              id=\"focused\"\n              v-model=\"focused\"\n              class=\"form-check-input\"\n              type=\"checkbox\"\n              checked\n              disabled\n            />\n            <label class=\"form-check-label\" for=\"focused\">Focused</label>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"col-6\">\n      <!-- eslint-disable-next-line vuejs-accessibility/form-control-has-label, vue/html-self-closing -->\n      <textarea v-model=\"value\" rows=\"4\" class=\"form-control\"></textarea>\n    </div>\n  </div>\n  <p>\n    <kbd>Ctrl-Shift-m</kbd>\n    (\n    <kbd>Cmd-Shift-m</kbd>\n    on macOS) to show lint panel.\n    <kbd>F8</kbd>\n    key shows the next error.\n  </p>\n</template>\n"
  },
  {
    "path": "src-docs/components/MarkdownDemo.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref, type Ref } from 'vue';\n\nimport { markdown } from '@codemirror/lang-markdown';\n// eslint-disable-next-line import-x/no-unresolved -- This is a demo component, and the CodeMirror component is only used here for demonstration purposes. It is not intended to be imported in other components.\nimport CodeMirror from 'vue-codemirror6';\nimport VueMarkdown from 'vue-markdown-wasm';\n\n/** Demo text */\nconst input: Ref<string> = ref(`# The quick brown fox jumps over the lazy dog.\n\n[Lorem ipsum](https://www.lipsum.com/) dolor sit amet, **consectetur** adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\nUt enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\nDuis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\nExcepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`);\n\n// Sync dark mode\ndefineProps<{ dark?: boolean }>();\n</script>\n\n<template>\n  <div class=\"row\">\n    <div class=\"col-6\">\n      <code-mirror\n        ref=\"cm\"\n        v-model=\"input\"\n        :dark=\"dark\"\n        :lang=\"markdown()\"\n        wrap\n        basic\n      />\n    </div>\n    <div class=\"col-6\">\n      <vue-markdown\n        v-model=\"input\"\n        :data-color-mode=\"dark ? 'dark' : 'light'\"\n        class=\"markdown-body\"\n      />\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src-docs/components/ReadonlyAndDisabledDemo.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref, type Ref } from 'vue';\n\n// eslint-disable-next-line import-x/no-unresolved -- This is a demo component, and the CodeMirror component is only used here for demonstration purposes. It is not intended to be imported in other components.\nimport CodeMirror from 'vue-codemirror6';\n\n/** Readonly */\nconst isReadonly: Ref<boolean> = ref(true);\n/** Disabled (Not Editable) */\nconst isDisabled: Ref<boolean> = ref(false);\n\n// Sync dark mode\ndefineProps<{ dark?: boolean }>();\n</script>\n\n<!-- eslint-disable no-irregular-whitespace -->\n<!-- eslint-disable vuejs-accessibility/label-has-for -->\n<template>\n  <div class=\"form-check form-switch\">\n    <input\n      id=\"readonly\"\n      v-model=\"isReadonly\"\n      :aria-checked=\"isReadonly\"\n      type=\"checkbox\"\n      class=\"form-check-input\"\n      role=\"switch\"\n    />\n    <label class=\"form-check-label\" for=\"readonly\">Readonly</label>\n  </div>\n  <div class=\"form-check form-switch\">\n    <input\n      id=\"disabled\"\n      v-model=\"isDisabled\"\n      :aria-checked=\"isDisabled\"\n      type=\"checkbox\"\n      class=\"form-check-input\"\n      role=\"switch\"\n    />\n    <label class=\"form-check-label\" for=\"disabled\">Disabled</label>\n  </div>\n  <code-mirror :dark=\"dark\" :readonly=\"isReadonly\" :disabled=\"isDisabled\" basic>\n    <pre>\n色は匂へど　散りぬるを\n我が世誰そ　常ならむ\n有為の奥山　今日越えて\n浅き夢見じ　酔ひもせず</pre\n    >\n  </code-mirror>\n</template>\n"
  },
  {
    "path": "src-docs/components/SlotDemo.vue",
    "content": "<script setup lang=\"ts\">\nimport { json, jsonParseLinter } from '@codemirror/lang-json';\n// eslint-disable-next-line import-x/no-unresolved -- This is a demo component, and the CodeMirror component is only used here for demonstration purposes. It is not intended to be imported in other components.\nimport CodeMirror from 'vue-codemirror6';\n\n// Sync Dark mode\ndefineProps<{ dark?: boolean }>();\n</script>\n\n<!-- prettier-ignore -->\n<template>\n  <code-mirror\n    :dark=\"dark\"\n    :lang=\"json()\"\n    :linter=\"jsonParseLinter()\"\n    basic\n    readonly\n  >\n    <pre>{\n  \"@schema\": \"https://json.schemastore.org/jsonld.json\",\n  \"@context\": \"http://schema.org\",\n  \"@type\": \"WebSite\",\n  \"name\": \"vue-codemirror6 Demo\",\n  \"url\": \"https://github.com/logue/vue-codemirror6\",\n  \"description\": \"CodeMirror6 for Vue3 and Vue2 component\"\n}</pre\n    >\n  </code-mirror>\n</template>\n"
  },
  {
    "path": "src-docs/components/ToggleTheme.vue",
    "content": "<script setup lang=\"ts\">\n/** Bootstrap 5.3 Toggle Dark mode */\nimport { watch } from 'vue';\n\nimport { useDark, useToggle } from '@vueuse/core';\n\nconst isDark = useDark();\nconst toggleDark = useToggle(isDark);\n\nwatch(\n  () => isDark.value,\n  dark =>\n    document.documentElement.setAttribute(\n      'data-bs-theme',\n      dark ? 'dark' : 'light'\n    ),\n  { immediate: true }\n);\n</script>\n\n<template>\n  <a href=\"#\" aria-label=\"Toggle Dark Mode\" @click=\"toggleDark()\">\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width=\"16\"\n      height=\"16\"\n      fill=\"currentColor\"\n      class=\"bi bi-circle-half\"\n      viewBox=\"0 0 16 16\"\n    >\n      <path d=\"M8 15A7 7 0 1 0 8 1v14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z\" />\n    </svg>\n  </a>\n</template>\n"
  },
  {
    "path": "src-docs/main.ts",
    "content": "import './style.scss';\n\n/** Demo Code */\nimport { createApp } from 'vue';\n\nimport App from './App.vue';\n\ncreateApp(App).mount('#app');\n"
  },
  {
    "path": "src-docs/style.scss",
    "content": "// 1. Include functions first (so you can manipulate colors, SVGs, calc, etc)\n@import '~/bootstrap/scss/functions';\n\n// 2. Include any default variable overrides here\n\n// 3. Include remainder of required Bootstrap stylesheets (including any separate color mode stylesheets)\n@import '~/bootstrap/scss/variables';\n@import '~/bootstrap/scss/variables-dark';\n\n// 4. Include any default map overrides here\n\n// 5. Include remainder of required parts\n@import '~/bootstrap/scss/maps';\n@import '~/bootstrap/scss/mixins';\n@import '~/bootstrap/scss/root';\n\n// 6. Optionally include any other parts as needed\n@import '~/bootstrap/scss/utilities';\n@import '~/bootstrap/scss/reboot';\n// @import '~/bootstrap/scss/type';\n@import '~/bootstrap/scss/forms';\n// @import '~/bootstrap/scss/dropdown';\n@import '~/bootstrap/scss/alert';\n@import '~/bootstrap/scss/nav';\n@import '~/bootstrap/scss/navbar';\n@import '~/bootstrap/scss/containers';\n@import '~/bootstrap/scss/grid';\n@import '~/bootstrap/scss/helpers';\n\n// 7. Optionally include utilities API last to generate classes based on the Sass map in `_utilities.scss`\n@import '~/bootstrap/scss/utilities/api';\n\n// 8. Add additional custom code here\n.vue-codemirror * {\n  font-family: var(--bs-font-monospace);\n}\n\n// GitHub Markdown CSS (used in MarkdownDemo)\n@import url(https://cdn.jsdelivr.net/npm/github-markdown-css@5.1.0/github-markdown.min.css);\n\n.markdown-body {\n  // Override prefers-color-scheme to respect Vue's dark mode setting\n  @media (prefers-color-scheme: dark) {\n    &[data-color-mode='light'] {\n      color-scheme: light;\n      --color-prettylights-syntax-comment: #57606a;\n      --color-prettylights-syntax-constant: #0550ae;\n      --color-prettylights-syntax-entity: #6639ba;\n      --color-prettylights-syntax-storage-modifier-import: #24292f;\n      --color-prettylights-syntax-entity-tag: #116329;\n      --color-prettylights-syntax-keyword: #cf222e;\n      --color-prettylights-syntax-string: #0a3069;\n      --color-prettylights-syntax-variable: #953800;\n      --color-prettylights-syntax-brackethighlighter-unmatched: #82071e;\n      --color-prettylights-syntax-invalid-illegal-text: #f6f8fa;\n      --color-prettylights-syntax-invalid-illegal-bg: #82071e;\n      --color-prettylights-syntax-carriage-return-text: #f6f8fa;\n      --color-prettylights-syntax-carriage-return-bg: #cf222e;\n      --color-prettylights-syntax-string-regexp: #116329;\n      --color-prettylights-syntax-markup-list: #3b2300;\n      --color-prettylights-syntax-markup-heading: #0550ae;\n      --color-prettylights-syntax-markup-italic: #24292f;\n      --color-prettylights-syntax-markup-bold: #24292f;\n      --color-prettylights-syntax-markup-deleted-text: #82071e;\n      --color-prettylights-syntax-markup-deleted-bg: #ffebe9;\n      --color-prettylights-syntax-markup-inserted-text: #116329;\n      --color-prettylights-syntax-markup-inserted-bg: #dafbe1;\n      --color-prettylights-syntax-markup-changed-text: #953800;\n      --color-prettylights-syntax-markup-changed-bg: #ffd8b5;\n      --color-prettylights-syntax-markup-ignored-text: #eaeef2;\n      --color-prettylights-syntax-markup-ignored-bg: #0550ae;\n      --color-prettylights-syntax-meta-diff-range: #8250df;\n      --color-prettylights-syntax-brackethighlighter-angle: #57606a;\n      --color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;\n      --color-prettylights-syntax-constant-other-reference-link: #0a3069;\n      --color-fg-default: #24292f;\n      --color-fg-muted: #57606a;\n      --color-fg-subtle: #6e7781;\n      --color-canvas-default: #ffffff;\n      --color-canvas-subtle: #f6f8fa;\n      --color-border-default: #d0d7de;\n      --color-border-muted: hsla(210, 18%, 87%, 1);\n      --color-neutral-muted: rgba(175, 184, 193, 0.2);\n      --color-accent-fg: #0969da;\n      --color-accent-emphasis: #0969da;\n      --color-attention-subtle: #fff8c5;\n      --color-danger-fg: #cf222e;\n    }\n  }\n\n  @media (prefers-color-scheme: light) {\n    &[data-color-mode='dark'] {\n      color-scheme: dark;\n      --color-prettylights-syntax-comment: #8b949e;\n      --color-prettylights-syntax-constant: #79c0ff;\n      --color-prettylights-syntax-entity: #d2a8ff;\n      --color-prettylights-syntax-storage-modifier-import: #c9d1d9;\n      --color-prettylights-syntax-entity-tag: #7ee787;\n      --color-prettylights-syntax-keyword: #ff7b72;\n      --color-prettylights-syntax-string: #a5d6ff;\n      --color-prettylights-syntax-variable: #ffa657;\n      --color-prettylights-syntax-brackethighlighter-unmatched: #f85149;\n      --color-prettylights-syntax-invalid-illegal-text: #f0f6fc;\n      --color-prettylights-syntax-invalid-illegal-bg: #8e1519;\n      --color-prettylights-syntax-carriage-return-text: #f0f6fc;\n      --color-prettylights-syntax-carriage-return-bg: #b62324;\n      --color-prettylights-syntax-string-regexp: #7ee787;\n      --color-prettylights-syntax-markup-list: #f2cc60;\n      --color-prettylights-syntax-markup-heading: #1f6feb;\n      --color-prettylights-syntax-markup-italic: #c9d1d9;\n      --color-prettylights-syntax-markup-bold: #c9d1d9;\n      --color-prettylights-syntax-markup-deleted-text: #ffdcd7;\n      --color-prettylights-syntax-markup-deleted-bg: #67060c;\n      --color-prettylights-syntax-markup-inserted-text: #aff5b4;\n      --color-prettylights-syntax-markup-inserted-bg: #033a16;\n      --color-prettylights-syntax-markup-changed-text: #ffdfb6;\n      --color-prettylights-syntax-markup-changed-bg: #5a1e02;\n      --color-prettylights-syntax-markup-ignored-text: #c9d1d9;\n      --color-prettylights-syntax-markup-ignored-bg: #1158c7;\n      --color-prettylights-syntax-meta-diff-range: #d2a8ff;\n      --color-prettylights-syntax-brackethighlighter-angle: #8b949e;\n      --color-prettylights-syntax-sublimelinter-gutter-mark: #484f58;\n      --color-prettylights-syntax-constant-other-reference-link: #a5d6ff;\n      --color-fg-default: #c9d1d9;\n      --color-fg-muted: #8b949e;\n      --color-fg-subtle: #6e7681;\n      --color-canvas-default: #0d1117;\n      --color-canvas-subtle: #161b22;\n      --color-border-default: #30363d;\n      --color-border-muted: #21262d;\n      --color-neutral-muted: rgba(110, 118, 129, 0.4);\n      --color-accent-fg: #58a6ff;\n      --color-accent-emphasis: #1f6feb;\n      --color-attention-subtle: rgba(187, 128, 9, 0.15);\n      --color-danger-fg: #f85149;\n    }\n  }\n\n  h1 > a.anchor,\n  h2 > a.anchor,\n  h3 > a.anchor,\n  h4 > a.anchor,\n  h5 > a.anchor,\n  h6 > a.anchor {\n    display: block;\n    float: left;\n    height: 1.2em;\n    width: 1em;\n    margin-left: -1em;\n    position: relative;\n    outline: none;\n  }\n  /*.anchor:target { background: yellow; }*/\n  h1 > a.anchor:before,\n  h2 > a.anchor:before,\n  h3 > a.anchor:before,\n  h4 > a.anchor:before,\n  h5 > a.anchor:before,\n  h6 > a.anchor:before {\n    visibility: hidden;\n    position: absolute;\n    opacity: 0.2;\n    right: 0;\n    top: 0;\n    width: 1.2em;\n    line-height: inherit;\n    content: '🔗';\n  }\n  h1 > a.anchor:hover:before,\n  h2 > a.anchor:hover:before,\n  h3 > a.anchor:hover:before,\n  h4 > a.anchor:hover:before,\n  h5 > a.anchor:hover:before,\n  h6 > a.anchor:hover:before {\n    visibility: visible;\n    opacity: 0.8;\n  }\n  h1:hover .anchor:before,\n  h2:hover .anchor:before,\n  h3:hover .anchor:before,\n  h4:hover .anchor:before,\n  h5:hover .anchor:before,\n  h6:hover .anchor:before {\n    visibility: visible;\n  }\n}\n"
  },
  {
    "path": "tsconfig.app.json",
    "content": "{\n  \"include\": [\"env.d.ts\", \"src/**/*\", \"src/**/*.vue\"],\n  \"exclude\": [\"src/**/__tests__/*\"],\n  \"compilerOptions\": {\n    \"tsBuildInfoFile\": \"./node_modules/.tmp/tsconfig.app.tsbuildinfo\",\n    \"target\": \"ES2020\",\n    \"useDefineForClassFields\": true,\n    \"lib\": [\"ES2020\", \"DOM\", \"DOM.Iterable\"],\n    \"module\": \"ESNext\",\n    \"skipLibCheck\": true,\n    \"allowImportingTsExtensions\": true,\n    \"moduleResolution\": \"bundler\",\n    \"allowSyntheticDefaultImports\": true,\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true,\n    \"jsx\": \"preserve\",\n    \"strict\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"paths\": {\n      \"@/*\": [\"./src/*\"]\n    }\n  }\n}\n"
  },
  {
    "path": "tsconfig.docs.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/tsconfig.json\",\n  \"extends\": \"./tsconfig.app.json\",\n  \"include\": [\n    \"./env.d.ts\",\n    \"./src/**/*\",\n    \"./src/**/*.vue\",\n    \"./src-docs/**/*\",\n    \"./src-docs/**/*.vue\"\n  ],\n  \"compilerOptions\": {\n    \"composite\": true,\n    \"declarationMap\": true,\n    \"tsBuildInfoFile\": \"./node_modules/.tmp/tsconfig.app.tsbuildinfo\",\n    \"paths\": {\n      \"@/*\": [\"./src/*\"],\n      \"vue-codemirror6\": [\"./src/index.ts\"]\n    }\n  }\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/tsconfig.json\",\n  \"files\": [],\n  \"references\": [\n    { \"path\": \"./tsconfig.app.json\" },\n    { \"path\": \"./tsconfig.docs.json\" },\n    { \"path\": \"./tsconfig.node.json\" },\n    { \"path\": \"./tsconfig.vitest.json\" }\n  ]\n}\n"
  },
  {
    "path": "tsconfig.node.json",
    "content": "{\n  \"extends\": \"@tsconfig/node-lts/tsconfig.json\",\n  \"include\": [\n    \"vite.config.*\",\n    \"vitest.config.*\",\n    \"cypress.config.*\",\n    \"nightwatch.conf.*\",\n    \"playwright.config.*\",\n    \"eslint.config.*\"\n  ],\n  \"compilerOptions\": {\n    \"noEmit\": true,\n    \"tsBuildInfoFile\": \"./node_modules/.tmp/tsconfig.node.tsbuildinfo\",\n\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Bundler\",\n    \"types\": [\"node\"]\n  }\n}\n"
  },
  {
    "path": "tsconfig.vitest.json",
    "content": "{\n  \"extends\": \"./tsconfig.app.json\",\n  \"include\": [\"src/**/*\", \"src/**/__tests__/*\", \"env.d.ts\"],\n  \"exclude\": [],\n  \"compilerOptions\": {\n    \"tsBuildInfoFile\": \"./node_modules/.tmp/tsconfig.vitest.tsbuildinfo\",\n    \"composite\": true,\n    \"lib\": [\"ES2022\", \"DOM\"],\n    \"types\": [\"node\", \"vitest/globals\", \"@vue/test-utils\"]\n  }\n}\n"
  },
  {
    "path": "vite.config.ts",
    "content": "import { writeFileSync } from 'node:fs';\nimport { fileURLToPath, URL } from 'node:url';\n\nimport Vue from '@vitejs/plugin-vue';\nimport { defineConfig, type UserConfig } from 'vite';\n\nimport { visualizer } from 'rollup-plugin-visualizer';\nimport banner from 'vite-plugin-banner';\nimport { checker } from 'vite-plugin-checker';\nimport dts from 'vite-plugin-dts';\n\nimport pkg from './package.json';\n\n// https://vitejs.dev/config/\nexport default defineConfig(({ mode, command }): UserConfig => {\n  const config: UserConfig = {\n    base: './',\n    publicDir: command === 'serve' ? 'public' : false,\n    // Resolver\n    resolve: {\n      // https://vitejs.dev/config/shared-options.html#resolve-alias\n      alias: {\n        '@': fileURLToPath(new URL('./src', import.meta.url)),\n        '~': fileURLToPath(new URL('./node_modules', import.meta.url)),\n        'vue-codemirror6': fileURLToPath(new URL('./src', import.meta.url)),\n      },\n    },\n    plugins: [\n      Vue(),\n      // vite-plugin-checker\n      // https://github.com/fi3ework/vite-plugin-checker\n      checker({\n        typescript: true,\n        // vueTsc: true,\n        // eslint: { lintCommand: 'eslint' },\n      }),\n      // vite-plugin-banner\n      // https://github.com/chengpeiquan/vite-plugin-banner\n      banner(`/**\n * ${pkg.name}\n *\n * @description ${pkg.description}\n * @author ${pkg.author.name} <${pkg.author.email}>\n * @copyright 2022-2026 By Masashi Yoshikawa All rights reserved.\n * @license ${pkg.license}\n * @version ${pkg.version}\n * @see {@link ${pkg.homepage}}\n */\n`),\n      // vite-plugin-dts\n      // https://github.com/qmhc/vite-plugin-dts\n      mode === 'docs'\n        ? undefined\n        : dts({ tsconfigPath: './tsconfig.app.json' }),\n    ],\n    optimizeDeps: {\n      exclude: [\n        'vue-demi',\n        // https://github.com/codemirror/dev/issues/608\n        '@codemirror/state',\n      ],\n    },\n    // Build Options\n    // https://vitejs.dev/config/#build-options\n    build: {\n      outDir: mode === 'docs' ? 'docs' : undefined,\n      lib:\n        mode === 'docs'\n          ? undefined\n          : {\n              entry: fileURLToPath(new URL('./src/index.ts', import.meta.url)),\n              name: 'CodeMirror',\n              formats: ['es', 'cjs', 'umd', 'iife'],\n              fileName: format => `index.${format}.js`,\n            },\n\n      rollupOptions: {\n        plugins: [\n          mode === 'analyze'\n            ? // rollup-plugin-visualizer\n              // https://github.com/btd/rollup-plugin-visualizer\n              visualizer({\n                open: true,\n                filename: 'stats.html',\n                gzipSize: false,\n                brotliSize: false,\n              })\n            : undefined,\n        ],\n        external:\n          mode === 'docs'\n            ? undefined\n            : [\n                '@codemirror/autocomplete',\n                '@codemirror/commands',\n                '@codemirror/language',\n                '@codemirror/lint',\n                '@codemirror/search',\n                '@codemirror/state',\n                '@codemirror/view',\n                'codemirror',\n                'style-mod',\n                'vue-demi',\n                'vue',\n              ],\n        output: {\n          esModule: true,\n          exports: 'named',\n          globals: {\n            '@codemirror/autocomplete': 'autocomplete',\n            '@codemirror/commands': 'commands',\n            '@codemirror/language': 'language',\n            '@codemirror/lint': 'lint',\n            '@codemirror/search': 'search',\n            '@codemirror/state': 'state',\n            '@codemirror/view': 'view',\n            'style-mod': 'styleMod',\n            'vue-demi': 'VueDemi',\n            codemirror: 'codemirror',\n            vue: 'Vue',\n          },\n          manualChunks:\n            mode !== 'docs'\n              ? undefined\n              : (id: string) => {\n                  if (\n                    id.includes('/node_modules/@vue/') ||\n                    id.includes('/node_modules/vue')\n                  ) {\n                    return 'vue';\n                  }\n\n                  if (id.includes('/node_modules/eslint-linter-browserify/')) {\n                    return 'eslint-linter-browserify';\n                  }\n\n                  // CodeMirror6\n                  if (\n                    id.includes('/node_modules/codemirror/') ||\n                    id.includes('/node_modules/@codemirror/') ||\n                    id.includes('/node_modules/style-mod/')\n                  ) {\n                    // Split CodeMirror and CodeMirror language into separate chunks\n                    return !/lang-/.exec(id) ? 'codemirror' : 'codemirror-lang';\n                  }\n\n                  if (id.includes('/node_modules/')) {\n                    // Other chunks\n                    return 'vendor';\n                  }\n                },\n        },\n      },\n      // Minify option\n      target: 'esnext',\n      // minify: mode === 'docs',\n    },\n  };\n\n  // Write meta data.\n  // eslint-disable-next-line security/detect-non-literal-fs-filename -- path is resolved from import.meta.url which is a static ESM URL, not user input\n  writeFileSync(\n    fileURLToPath(new URL('./src/Meta.ts', import.meta.url)),\n    `import type MetaInterface from '@/interfaces/MetaInterface';\n\n// This file is auto-generated by the build system.\nconst meta: MetaInterface = {\n  version: '${pkg.version}',\n  date: '${new Date().toISOString()}',\n};\nexport default meta;\n`\n  );\n\n  // Export vite config\n  return config;\n});\n"
  },
  {
    "path": "vitest.config.ts",
    "content": "import { fileURLToPath, URL } from 'node:url';\n\nimport Vue from '@vitejs/plugin-vue';\nimport { defineConfig } from 'vitest/config';\n\n// https://vitest.dev/config/\nexport default defineConfig({\n  plugins: [Vue()],\n  resolve: {\n    alias: {\n      '@': fileURLToPath(new URL('./src', import.meta.url)),\n    },\n  },\n  test: {\n    globals: true,\n    environment: 'happy-dom',\n    coverage: {\n      provider: 'v8',\n      reporter: ['text', 'json', 'html'],\n      exclude: [\n        'node_modules/',\n        'src-docs/',\n        'dist/',\n        'docs/',\n        '**/*.d.ts',\n        '**/*.config.*',\n        '**/mockData/**',\n        'src/Meta.ts',\n        'src/helpers/h-demi.ts',\n      ],\n    },\n  },\n});\n"
  }
]