[
  {
    "path": ".github/workflows/unis-babel-preset.yml",
    "content": "name: \"@unis/babel-preset CI/CD\"\n\non:\n  push:\n    branches:\n      - 'main'\n    paths:\n      - 'packages/unis-babel-preset/**'\n\njobs:\n\n  \"test\":\n    runs-on: ubuntu-latest\n    if: ${{contains(github.event.head_commit.message, '(babel-preset):')}}\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: 16.x\n          registry-url: \"https://registry.npmjs.org\"\n      - uses: pnpm/action-setup@v2.0.1\n        with:\n          version: 7.9.0\n      - run: |\n          pnpm install\n          cd packages/unis-core\n          pnpm build\n          cd ../unis-babel-preset\n          pnpm test\n\n  \"publish\":\n    needs: test\n    runs-on: ubuntu-latest\n    if: ${{startsWith(github.event.head_commit.message, 'release(babel-preset):')}}\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: 16.x\n          registry-url: \"https://registry.npmjs.org\"\n      - uses: pnpm/action-setup@v2.0.1\n        with:\n          version: 7.9.0\n      - run: |\n          pnpm install\n          cd packages/unis-core\n          pnpm build\n          cd ../unis-babel-preset\n          pnpm build\n          pnpm publish --no-git-checks --access public\n        env:\n          NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}"
  },
  {
    "path": ".github/workflows/unis-core.yml",
    "content": "name: \"@unis/core CI/CD\"\n\non:\n  push:\n    branches:\n      - 'main'\n    paths:\n      - 'packages/unis-core/**'\n\njobs:\n\n  \"test\":\n    runs-on: ubuntu-latest\n    if: ${{contains(github.event.head_commit.message, '(core):')}}\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: 16.x\n          registry-url: \"https://registry.npmjs.org\"\n      - uses: pnpm/action-setup@v2.0.1\n        with:\n          version: 7.9.0\n      - run: |\n          pnpm install\n          cd packages/unis-core\n          pnpm test\n\n  \"publish\":\n    needs: test\n    runs-on: ubuntu-latest\n    if: ${{startsWith(github.event.head_commit.message, 'release(core):')}}\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: 16.x\n          registry-url: \"https://registry.npmjs.org\"\n      - uses: pnpm/action-setup@v2.0.1\n        with:\n          version: 7.1.2\n      - run: |\n          pnpm install\n          cd packages/unis-core\n          pnpm build\n          pnpm publish --no-git-checks --access public\n        env:\n          NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}"
  },
  {
    "path": ".github/workflows/unis-dom.yml",
    "content": "name: \"@unis/dom CI/CD\"\n\non:\n  push:\n    branches:\n      - 'main'\n    paths:\n      - 'packages/unis-dom/**'\n\njobs:\n\n  \"test\":\n    runs-on: ubuntu-latest\n    if: ${{contains(github.event.head_commit.message, '(dom):')}}\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: 16.x\n          registry-url: \"https://registry.npmjs.org\"\n      - uses: pnpm/action-setup@v2.0.1\n        with:\n          version: 7.9.0\n      - run: |\n          pnpm install\n          cd packages/unis-core\n          pnpm build\n          cd ../unis-vite-preset\n          pnpm build\n          cd ../unis-dom\n          pnpm test\n\n  \"publish\":\n    needs: test\n    runs-on: ubuntu-latest\n    if: ${{startsWith(github.event.head_commit.message, 'release(dom):')}}\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: 16.x\n          registry-url: \"https://registry.npmjs.org\"\n      - uses: pnpm/action-setup@v2.0.1\n        with:\n          version: 7.1.2\n      - run: |\n          pnpm install\n          cd packages/unis-core\n          pnpm build\n          cd ../unis-dom\n          pnpm build\n          pnpm publish --no-git-checks --access public\n        env:\n          NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}"
  },
  {
    "path": ".github/workflows/unis-router.yml",
    "content": "name: \"@unis/router CI/CD\"\n\non:\n  push:\n    branches:\n      - 'main'\n    paths:\n      - 'packages/unis-router/**'\n\njobs:\n  \"test\":\n    runs-on: ubuntu-latest\n    if: ${{contains(github.event.head_commit.message, '(router):')}}\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: 16.x\n          registry-url: \"https://registry.npmjs.org\"\n      - uses: pnpm/action-setup@v2.0.1\n        with:\n          version: 7.9.0\n      - run: |\n          pnpm install\n          cd packages/unis-core\n          pnpm build\n          cd ../unis-vite-preset\n          pnpm build\n          cd ../unis-router\n          pnpm test\n\n  \"publish\":\n    needs: test\n    runs-on: ubuntu-latest\n    if: ${{startsWith(github.event.head_commit.message, 'release(router):')}}\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: 16.x\n          registry-url: \"https://registry.npmjs.org\"\n      - uses: pnpm/action-setup@v2.0.1\n        with:\n          version: 7.9.0\n      - run: |\n          pnpm install\n          cd packages/unis-core\n          pnpm build\n          cd ../unis-router\n          pnpm build\n          pnpm publish --no-git-checks --access public\n        env:\n          NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}"
  },
  {
    "path": ".github/workflows/unis-transition.yml",
    "content": "name: \"@unis/transition CI/CD\"\n\non:\n  push:\n    branches:\n      - 'main'\n    paths:\n      - 'packages/unis-transition/**'\n\njobs:\n\n  \"publish\":\n    runs-on: ubuntu-latest\n    if: ${{startsWith(github.event.head_commit.message, 'release(transition):')}}\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: 16.x\n          registry-url: \"https://registry.npmjs.org\"\n      - uses: pnpm/action-setup@v2.0.1\n        with:\n          version: 7.9.0\n      - run: |\n          pnpm install\n          cd packages/unis-core\n          pnpm build\n          cd ../unis-transition\n          pnpm build\n          pnpm publish --no-git-checks --access public\n        env:\n          NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}"
  },
  {
    "path": ".github/workflows/unis-vite-preset.yml",
    "content": "name: \"@unis/vite-preset CI/CD\"\n\non:\n  push:\n    branches:\n      - 'main'\n    paths:\n      - 'packages/unis-vite-preset/**'\n\njobs:\n\n  \"publish\":\n    runs-on: ubuntu-latest\n    if: ${{startsWith(github.event.head_commit.message, 'release(vite-preset):')}}\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v2\n        with:\n          node-version: 16.x\n          registry-url: \"https://registry.npmjs.org\"\n      - uses: pnpm/action-setup@v2.0.1\n        with:\n          version: 7.9.0\n      - run: |\n          pnpm install\n          cd packages/unis-core\n          pnpm build\n          cd ../unis-vite-preset\n          pnpm build\n          pnpm publish --no-git-checks --access public\n        env:\n          NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}"
  },
  {
    "path": ".gitignore",
    "content": "# Dependency directories\nnode_modules/\n\n.DS_Store\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"editor.defaultFormatter\": \"esbenp.prettier-vscode\",\n  \"[typescriptreact]\": {\n    \"editor.formatOnSave\": true\n  },\n  \"[typescript]\": {\n    \"editor.formatOnSave\": true\n  },\n  \"[javascript]\": {\n    \"editor.formatOnSave\": true\n  },\n  \"[markdown]\": {\n    \"editor.formatOnSave\": true\n  },\n  \"editor.tabSize\": 2,\n  \"editor.insertSpaces\": true,\n  \"files.associations\": {\n    \"*.json\": \"jsonc\"\n  }\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021-present anuoua\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."
  },
  {
    "path": "README-zh_CN.md",
    "content": "<p align=\"center\">\n  <img height=\"300\" src=\"./assets/logo.svg\">\n</p>\n\n[![@unis/core CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-core.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-core.yml) [![@unis/dom CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-dom.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-dom.yml) [![@unis/router CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-router.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-router.yml) [![@unis/transition CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-transition.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-transition.yml) [![@unis/vite-preset CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-vite-preset.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-vite-preset.yml) [![@unis/babel-preset CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-babel-preset.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-babel-preset.yml)\n\n# Unis\n\nUnis 是一款新的前端框架，创新的编译策略打造的组件 API 帮助你更加轻松的创建网页 UI。\n\n## 性能\n\n<img height=\"500\" src=\"./assets/bench.png\">\n\n## 安装\n\n```bash\nnpm i @unis/core @unis/dom\n```\n\n## Vite 开发\n\n```shell\nnpm i vite @unis/vite-preset -D\n```\n\nvite.config.js\n\n```javascript\nimport { defineConfig } from \"vite\";\nimport { unisPreset } from \"@unis/vite-preset\";\n\nexport default defineConfig({\n  plugins: [unisPreset()],\n});\n```\n\ntsconfig.json\n\n```json\n{\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"@unis/core\"\n  }\n}\n```\n\nindex.html\n\n```javascript\n<html>\n  ...\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"./index.tsx\"></script>\n  </body>\n</html>\n```\n\nindex.tsx\n\n```javascript\nfunction App() {\n  return () => <div>hello</div>;\n}\n\nrender(<App />, document.querySelector(\"#root\"));\n```\n\n## 用法\n\nUnis 并不是 React 的复刻，而是保留了 React 使用体验的全新框架，unis 的用法很简单，熟悉 React 的可以很快上手。\n\n### 组件\n\n在 unis 中组件是一个高阶函数。\n\n```javascript\nimport { render } from \"@unis/dom\";\n\nconst App = () => {\n  return () => (\n    // 返回一个函数\n    <div>hello world</div>\n  );\n};\n\nrender(<App />, document.querySelector(\"#root\"));\n```\n\n### 组件状态\n\nUnis 中的 `useState` 用法和 React 相似，但是要注意的是 unis 中 `use` 系列方法，定义类型必须为 `let` ，因为 unis 使用了 Callback Reassign 编译策略，[@callback-reassign/rollup-plugin](https://github.com/anuoua/callback-reassign) 帮我们补全了 Callback Reassign 代码。\n\n```javascript\nimport { useState } from \"@unis/core\";\n\nconst App = () => {\n  let [msg, setMsg] = useState(\"hello\");\n  /**\n   * Compile to:\n   *\n   * let [msg, setMsg] = useState('hello', ([$0, $1]) => { msg = $0; setMsg = $1 });\n   */\n  return () => <div>{msg}</div>;\n};\n```\n\n### Props\n\nUnis 直接使用 props 会无法获取最新值，所以 unis 提供了 useProps。\n\n```javascript\nimport { useProps } from \"@unis/core\";\n\nconst App = (p) => {\n  let { some } = useProps(p);\n  /**\n   * Compile to:\n   *\n   * let { some } = useProps(p, ({ some: $0 }) => { some = $0 });\n   */\n  return () => <div>{some}</div>;\n};\n```\n\n### 副作用\n\nUnis 保留了和 React 基本一致的 `useEffect` 和 `useLayoutEffect` ，但 deps 是一个返回数组的函数。\n\n```javascript\nimport { useEffect } from \"@unis/core\";\n\nconst App = () => {\n  useEffect(\n    () => {\n      // ...\n      return () => {\n        // 清理...\n      };\n    },\n    () => [] // deps 是一个返回数组的函数\n  );\n\n  return () => <div>hello</div>;\n};\n```\n\n### 自定义 hook\n\nUnis 的自定义 hook ，在有返回值的场景需要搭配 `use` 方法使用，原因则是前面提到的 Callback Reassign 编译策略。自定义 hook 的命名我们约定以小写字母 `u` 开头，目的是用于区分其他函数，同时在 IDE 的提示下更加方便的导入。\n\n```javascript\nimport { use, useState } from \"@unis/core\";\n\n// 创建自定义 hook 高阶函数\nconst uCount = () => {\n  let [count, setCount] = useState(0);\n  const add = () => setCount(count + 1);\n  return () => [count, add];\n};\n\n// 通过 `use` 使用 hook\nfunction App() {\n  let [count, add] = use(uCount());\n  /**\n   * Compile to:\n   *\n   * let [count, add] = use(uCount(), ([$0, $1]) => { count = $0; add = $1 });\n   */\n  return () => <div onClick={add}>{count}</div>;\n}\n```\n\n## 特性\n\n### Fragment\n\n```javascript\nimport { Fragment } from \"@unis/core\";\n\nfunction App() {\n  return () => (\n    <Fragment>\n      <div></div>\n      <span></span>\n    </Fragment>\n  );\n}\n```\n\n### Portal\n\n```javascript\nimport { createPortal } from \"@unis/core\";\n\nfunction App() {\n  return () => createPortal(<div></div>, document.body);\n}\n```\n\n### Context\n\n```javascript\nimport { createContext } from \"@unis/core\";\nimport { render } from \"@unis/dom\";\n\nconst ThemeContext = createContext(\"light\");\n\nfunction App() {\n  let theme = useContext(ThemeContext);\n\n  return () => <div>{theme}</div>;\n}\n\nrender(\n  <ThemeContext.Provider value=\"dark\">\n    <App />\n  </ThemeContext.Provider>,\n  document.querySelector(\"#root\")\n);\n```\n\n## SSR 服务端渲染\n\n服务端\n\n```javascript\nimport express from \"express\";\nimport { renderToString } from \"@unis/dom/server\";\n\nconst app = express();\n\napp.get(\"/\", (req, res) => {\n  const SSR_CONTENT = renderToString(<div>hello world</div>);\n\n  res.send(`\n    <html>\n      <header>...</header>\n      <body>\n        <div id=\"root\">${SSR_CONTENT}</div>\n      </body>\n    </html>\n  `);\n});\n```\n\n客户端\n\n```javascript\nimport { render } from \"@unis/dom\";\n\nrender(\n  <App />,\n  document.querySelector(\"#root\"),\n  true // true 代表使用 hydrate （水合）进行渲染，复用 server 端的内容。\n);\n```\n\n## Todo 项目\n\n完整项目请查看\n\n- [packages/unis-example](packages/unis-example) Todo 示例\n- [stackbliz](https://stackblitz.com/edit/vitejs-vite-8hn3pz) 试用\n\n## API\n\n- Core\n\n  - h\n  - h2 (for jsx2)\n  - Fragment\n  - createPortal\n  - createContext\n  - render\n  - memo\n\n- Hooks\n  - use\n  - useProps\n  - useState\n  - useReducer\n  - useContext\n  - useMemo\n  - useEffect\n  - useRef\n  - useId\n\n## License\n\nMIT @anuoua\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n  <img height=\"300\" src=\"./assets/logo.svg\">\n</p>\n\n[![@unis/core CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-core.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-core.yml) [![@unis/dom CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-dom.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-dom.yml) [![@unis/router CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-router.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-router.yml) [![@unis/transition CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-transition.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-transition.yml) [![@unis/vite-preset CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-vite-preset.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-vite-preset.yml) [![@unis/babel-preset CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-babel-preset.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-babel-preset.yml)\n\n# Unis [中文](./README-zh_CN.md)\n\nUnis is a new front-end framework. Its innovative compilation strategy and component API built help you create web UI more easily.\n\n## Performance\n\n<img height=\"500\" src=\"./assets/bench.png\">\n\n## Installation\n\n```bash\nnpm i @unis/core @unis/dom\n```\n\n## Vite Development\n\n```shell\nnpm i vite @unis/vite-preset -D\n```\n\nvite.config.js\n\n```javascript\nimport { defineConfig } from \"vite\";\nimport { unisPreset } from \"@unis/vite-preset\";\n\nexport default defineConfig({\n  plugins: [unisPreset()],\n});\n```\n\ntsconfig.json\n\n```json\n{\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"@unis/core\"\n  }\n}\n```\n\nindex.html\n\n```javascript\n<html>\n  ...\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"./index.tsx\"></script>\n  </body>\n</html>\n```\n\nindex.tsx\n\n```javascript\nfunction App() {\n  return () => <div>hello</div>;\n}\n\nrender(<App />, document.querySelector(\"#root\"));\n```\n\n## Usage\n\nUnis is not a replica of React, but a brand new framework that retains the user experience of React. Unis is easy to use, and those who are familiar with React can quickly get started.\n\n### Components\n\nIn Unis, the component is a higher-order function.\n\n```javascript\nimport { render } from \"@unis/dom\";\n\nconst App = () => {\n  return () => (\n    // Returns a function\n    <div>hello world</div>\n  );\n};\n\nrender(<App />, document.querySelector(\"#root\"));\n```\n\n### Component State\n\nThe usage of `useState` in Unis is similar to React, but it should be noted that for the `use` method series in Unis, the defined type must be `let`. This is because Unis uses the Callback Reassign compilation strategy, and [@callback-reassign/rollup-plugin](https://github.com/anuoua/callback-reassign) helps us complete the Callback Reassign code.\n\n```javascript\nimport { useState } from \"@unis/core\";\n\nconst App = () => {\n  let [msg, setMsg] = useState(\"hello\");\n  /**\n   * Compile to:\n   *\n   * let [msg, setMsg] = useState('hello', ([$0, $1]) => { msg = $0; setMsg = $1 });\n   */\n  return () => <div>{msg}</div>;\n};\n```\n\n### Props\n\nDirectly using `props` in Unis will be unable to get the latest value, so Unis provides `useProps`.\n\n```javascript\nimport { useProps } from \"@unis/core\";\n\nconst App = (p) => {\n  let { some } = useProps(p);\n  /**\n   * Compile to:\n   *\n   * let { some } = useProps(p, ({ some: $0 }) => { some = $0 });\n   */\n  return () => <div>{some}</div>;\n};\n```\n\n### Side Effects\n\nUnis retains the familiar `useEffect` and `useLayoutEffect` methods from React, but the `deps` parameter is a function that returns an array.\n\n```javascript\nimport { useEffect } from \"@unis/core\";\n\nconst App = () => {\n  useEffect(\n    () => {\n      // ...\n      return () => {\n        // Clean up...\n      };\n    },\n    () => [] // deps is a function that returns an array\n  );\n\n  return () => <div>hello</div>;\n};\n```\n\n### Custom Hook\n\nFor Unis' custom hooks that have a return value, the `use` method should be used accordingly, due to the Callback Reassign compilation strategy mentioned earlier. We conventionally name custom hooks with a lowercase `u` at the beginning, to differentiate them from other functions and make them easy to import with IDE hints.\n\n```javascript\nimport { use, useState } from \"@unis/core\";\n\n// Create a higher-order function for the custom hook\nconst uCount = () => {\n  let [count, setCount] = useState(0);\n  const add = () => setCount(count + 1);\n  return () => [count, add];\n};\n\n// Use the hook through `use`\nfunction App() {\n  let [count, add] = use(uCount());\n  /**\n   * Compile to:\n   *\n   * let [count, add] = use(uCount(), ([$0, $1]) => { count = $0; add = $1 });\n   */\n  return () => <div onClick={add}>{count}</div>;\n}\n```\n\n## Features\n\n### Fragment\n\n```javascript\nimport { Fragment } from \"@unis/core\";\n\nfunction App() {\n  return () => (\n    <Fragment>\n      <div></div>\n      <span></span>\n    </Fragment>\n  );\n}\n```\n\n### Portal\n\n```javascript\nimport { createPortal } from \"@unis/core\";\n\nfunction App() {\n  return () => createPortal(<div></div>, document.body);\n}\n```\n\n### Context\n\n```javascript\nimport { createContext } from \"@unis/core\";\nimport { render } from \"@unis/dom\";\n\nconst ThemeContext = createContext(\"light\");\n\nfunction App() {\n  let theme = useContext(ThemeContext);\n\n  return () => <div>{theme}</div>;\n}\n\nrender(\n  <ThemeContext.Provider value=\"dark\">\n    <App />\n  </ThemeContext.Provider>,\n  document.querySelector(\"#root\")\n);\n```\n\n## Server-Side Rendering\n\nServer\n\n```javascript\nimport express from \"express\";\nimport { renderToString } from \"@unis/dom/server\";\n\nconst app = express();\n\napp.get(\"/\", (req, res) => {\n  const SSR_CONTENT = renderToString(<div>hello world</div>);\n\n  res.send(`\n    <html>\n      <header>...</header>\n      <body>\n        <div id=\"root\">${SSR_CONTENT}</div>\n      </body>\n    </html>\n  `);\n});\n```\n\nClient\n\n```javascript\nimport { render } from \"@unis/dom\";\n\nrender(\n  <App />,\n  document.querySelector(\"#root\"),\n  true // true means using hydration to render and reuse the server-side rendered content.\n);\n```\n\n## Todo Project\n\nSee complete project at\n\n- [packages/unis-example](packages/unis-example) Todo example\n- [stackbliz](https://stackblitz.com/edit/vitejs-vite-8hn3pz) Try it out\n\n## API\n\n- Core\n\n  - h\n  - h2 (for jsx2)\n  - Fragment\n  - createPortal\n  - createContext\n  - render\n  - memo\n\n- Hooks\n  - use\n  - useProps\n  - useState\n  - useReducer\n  - useContext\n  - useMemo\n  - useEffect\n  - useRef\n  - useId\n\n## License\n\nMIT @anuoua\n"
  },
  {
    "path": "assets/logo.txt",
    "content": "                       \n          ████         \n         ██  █         \n         █   █         \n   ███  █    █         \n   █ ████    ██████    \n   █  ██     ██   ██   \n   ██            ███   \n    █  █   █   ██      \n    ██         ███     \n    █            █     \n    ██        ████     \n     ██████████        \n                       "
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"unis\",\n  \"version\": \"0.0.0\",\n  \"description\": \"\",\n  \"private\": true,\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"workspaces\": {\n    \"packages\": [\n      \"./packages/*\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/anuoua/unis.git\"\n  },\n  \"author\": \"anuoua\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/anuoua/unis/issues\"\n  },\n  \"homepage\": \"https://github.com/anuoua/unis#readme\"\n}\n"
  },
  {
    "path": "packages/unis-babel-preset/.gitignore",
    "content": "build/"
  },
  {
    "path": "packages/unis-babel-preset/README.md",
    "content": "# Unis Babel Preset\n\nUnis develop preset for babel.\n\n## Install\n\n```shell\nnpm add -D @unis/babel-preset\n```\n\n## Usage\n\n.babelrc.json or babel.config.js\n\n```javascript\n{\n  \"presets\": [\"@unis/babel-preset\"]\n}\n```\n\nIf you use @babel/preset-env, please use relatively new targets. There is a bug in the babel transformation of destructuring syntax. e.g.\n\n```javascript\n{\n  \"presets\": [\n    [\n      \"@babel/preset-env\",\n      {\n        targets: \"> 0.25%, not dead\",\n      }\n    ],\n    \"@unis/babel-preset\"\n  ]\n}\n```\n"
  },
  {
    "path": "packages/unis-babel-preset/package.json",
    "content": "{\n  \"name\": \"@unis/babel-preset\",\n  \"version\": \"0.0.2\",\n  \"description\": \"Unis babel preset\",\n  \"main\": \"build/index.js\",\n  \"module\": \"build/index.mjs\",\n  \"types\": \"build/index.d.ts\",\n  \"typings\": \"build/index.d.ts\",\n  \"scripts\": {\n    \"build\": \"rimraf build && rollup --config && tsc\",\n    \"build:dev\": \"cross-env NODE_ENV=development pnpm build\",\n    \"test\": \"vitest run\"\n  },\n  \"exports\": {\n    \".\": {\n      \"require\": \"./build/index.js\",\n      \"import\": \"./build/index.mjs\"\n    }\n  },\n  \"keywords\": [\n    \"babel\",\n    \"preset\",\n    \"unis\"\n  ],\n  \"files\": [\n    \"build\"\n  ],\n  \"author\": \"anuoua\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/anuoua/unis/issues\"\n  },\n  \"homepage\": \"https://github.com/anuoua/unis/tree/main/packages/unis-babel-preset\",\n  \"peerDependencies\": {\n    \"@unis/core\": \"workspace:^\"\n  },\n  \"dependencies\": {\n    \"@babel/plugin-syntax-jsx\": \"^7.21.4\",\n    \"@babel/plugin-transform-react-jsx\": \"^7.21.0\",\n    \"@callback-reassign/babel-plugin\": \"^0.0.1\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.21.4\",\n    \"@rollup/plugin-node-resolve\": \"^13.0.6\",\n    \"@types/babel__core\": \"^7.20.0\",\n    \"@unis/core\": \"workspace:^\",\n    \"cross-env\": \"^7.0.3\",\n    \"esbuild\": \"^0.13.13\",\n    \"rimraf\": \"^3.0.2\",\n    \"rollup\": \"^2.72.0\",\n    \"rollup-plugin-esbuild\": \"^4.6.0\",\n    \"typescript\": \"^4.4.4\",\n    \"vite\": \"^4.2.1\",\n    \"vitest\": \"^0.29.8\"\n  }\n}\n"
  },
  {
    "path": "packages/unis-babel-preset/rollup.config.js",
    "content": "import { defineConfig } from \"rollup\";\nimport { nodeResolve } from \"@rollup/plugin-node-resolve\";\nimport esbuild from \"rollup-plugin-esbuild\";\n\nconst configGen = (format) =>\n  defineConfig({\n    input: \"src/index.ts\",\n    external: [\n      /^@unis/,\n      \"@callback-reassign/rollup-plugin\",\n      \"@babel/plugin-syntax-jsx\",\n      \"@babel/plugin-transform-react-jsx\",\n    ],\n    output: [\n      {\n        dir: \"build\",\n        entryFileNames: `index.${format === \"esm\" ? \"mjs\" : \"js\"}`,\n        format,\n        sourcemap: true,\n      },\n    ],\n    plugins: [\n      nodeResolve({\n        modulesOnly: true,\n      }),\n      esbuild({\n        sourceMap: true,\n        minify: process.env.NODE_ENV === \"development\" ? false : true,\n        target: \"esnext\",\n      }),\n    ],\n  });\n\nconst config = [configGen(\"cjs\"), configGen(\"esm\")];\n\nexport default config;\n"
  },
  {
    "path": "packages/unis-babel-preset/src/index.ts",
    "content": "import { unisFns } from \"@unis/core\";\nimport reassign from \"@callback-reassign/babel-plugin\";\n// @ts-ignore\nimport syntaxJsx from \"@babel/plugin-syntax-jsx\";\n// @ts-ignore\nimport transformReactJsx from \"@babel/plugin-transform-react-jsx\";\n\nexport default function unisPreset() {\n  return {\n    plugins: [\n      syntaxJsx,\n      [\n        transformReactJsx,\n        {\n          runtime: \"automatic\",\n          importSource: \"@unis/core\",\n        },\n      ],\n      [\n        reassign,\n        {\n          targetFns: {\n            \"@unis/core\": unisFns,\n          },\n        },\n      ],\n    ],\n  };\n}\n"
  },
  {
    "path": "packages/unis-babel-preset/test/index.test.ts",
    "content": "import { it, expect } from \"vitest\";\nimport { transform } from \"@babel/core\";\nimport unisPreset from \"../src/index\";\n\nconst code = `\nimport { useState } from \"@unis/core\";\nlet [a, seta] = useState(1);\n`;\n\nconst transformed = `import { useState } from \"@unis/core\";\nlet [a, seta] = useState(1, ([$0, $1]) => {\n  a = $0;\n  seta = $1;\n});`;\n\nit(\"transform\", () => {\n  const result = transform(code, {\n    presets: [unisPreset],\n  });\n  expect(result?.code).toBe(transformed);\n});\n"
  },
  {
    "path": "packages/unis-babel-preset/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"emitDeclarationOnly\": true,\n    \"declarationMap\": false,\n    \"outDir\": \"build\"\n  },\n  \"include\": [\"src\"]\n}"
  },
  {
    "path": "packages/unis-core/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Microbundle cache\n.rpt2_cache/\n.rts2_cache_cjs/\n.rts2_cache_es/\n.rts2_cache_umd/\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n.env.test\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n.parcel-cache\n\n# Next.js build output\n.next\n\n# Nuxt.js build / generate output\n.nuxt\ndist\nbuild\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and *not* Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# TernJS port file\n.tern-port\n"
  },
  {
    "path": "packages/unis-core/index.d.ts",
    "content": "import \"./jsx-runtime/jsx-runtime\";\nimport \"./jsx-runtime/jsx-dev-runtime\";\nexport * from \"./dist\";\n"
  },
  {
    "path": "packages/unis-core/jsx-runtime/jsx-dev-runtime.d.ts",
    "content": "declare module \"@unis/core/jsx-dev-runtime\";\n"
  },
  {
    "path": "packages/unis-core/jsx-runtime/jsx-dev-runtime.js",
    "content": "const { h2, Fragment } = require(\"../dist/index.js\");\n\nexports.jsxDEV = h2;\nexports.Fragment = Fragment;\n"
  },
  {
    "path": "packages/unis-core/jsx-runtime/jsx-dev-runtime.mjs",
    "content": "export { h2 as jsxDEV, Fragment } from \"../dist/index.mjs\";\n"
  },
  {
    "path": "packages/unis-core/jsx-runtime/jsx-runtime.d.ts",
    "content": "declare module \"@unis/core/jsx-runtime\";\n"
  },
  {
    "path": "packages/unis-core/jsx-runtime/jsx-runtime.js",
    "content": "const { h2, Fragment } = require(\"../dist/index.mjs\");\n\nexports.jsx = h2;\nexports.jsxs = h2;\nexports.Fragment = Fragment;\n"
  },
  {
    "path": "packages/unis-core/jsx-runtime/jsx-runtime.mjs",
    "content": "export { h2 as jsx, h2 as jsxs, Fragment } from \"../dist/index.mjs\";\n"
  },
  {
    "path": "packages/unis-core/package.json",
    "content": "{\n  \"name\": \"@unis/core\",\n  \"version\": \"1.2.5\",\n  \"description\": \"Unis is a simpler and easier to use front-end framework than React\",\n  \"main\": \"dist/index.js\",\n  \"module\": \"dist/index.mjs\",\n  \"types\": \"index.d.ts\",\n  \"typings\": \"index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"require\": \"./dist/index.js\",\n      \"import\": \"./dist/index.mjs\"\n    },\n    \"./jsx-runtime\": {\n      \"require\": \"./jsx-runtime/jsx-runtime.js\",\n      \"import\": \"./jsx-runtime/jsx-runtime.mjs\"\n    },\n    \"./jsx-dev-runtime\": {\n      \"require\": \"./jsx-runtime/jsx-dev-runtime.js\",\n      \"import\": \"./jsx-runtime/jsx-dev-runtime.mjs\"\n    }\n  },\n  \"scripts\": {\n    \"build\": \"rimraf build && rimraf dist && tsc -p tsconfig.build.json && rollup --config\",\n    \"build:dev\": \"cross-env NODE_ENV=development pnpm build\",\n    \"test\": \"vitest run --coverage\",\n    \"test:watch\": \"vitest -w\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/anuoua/unis.git\"\n  },\n  \"keywords\": [\n    \"frontend\",\n    \"web\",\n    \"framwork\"\n  ],\n  \"files\": [\n    \"dist\",\n    \"jsx-runtime\",\n    \"index.d.ts\"\n  ],\n  \"author\": \"anuoua\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/anuoua/unis/issues\"\n  },\n  \"homepage\": \"https://github.com/anuoua/unis#readme\",\n  \"dependencies\": {\n    \"@types/prop-types\": \"^15.7.5\",\n    \"@types/scheduler\": \"^0.16.3\",\n    \"csstype\": \"^3.1.2\"\n  },\n  \"devDependencies\": {\n    \"@rollup/plugin-node-resolve\": \"^15.0.2\",\n    \"@types/jsdom\": \"^21.1.1\",\n    \"@vitest/coverage-c8\": \"^0.29.8\",\n    \"cross-env\": \"^7.0.3\",\n    \"esbuild\": \"^0.17.15\",\n    \"jsdom\": \"^21.1.1\",\n    \"rimraf\": \"^4.4.1\",\n    \"rollup\": \"^3.20.2\",\n    \"rollup-plugin-dts\": \"^5.3.0\",\n    \"rollup-plugin-esbuild\": \"^5.0.0\",\n    \"tslib\": \"^2.5.0\",\n    \"typescript\": \"^5.0.3\",\n    \"vite\": \"^4.2.1\",\n    \"vitest\": \"^0.29.8\"\n  }\n}\n"
  },
  {
    "path": "packages/unis-core/rollup.config.mjs",
    "content": "import dts from \"rollup-plugin-dts\";\nimport esbuild from \"rollup-plugin-esbuild\";\nimport { defineConfig } from \"rollup\";\nimport { nodeResolve } from \"@rollup/plugin-node-resolve\";\n\nconst configGen = (format) =>\n  defineConfig({\n    input: \"src/index.ts\",\n    output: [\n      {\n        dir: \"dist\",\n        entryFileNames: `index.${format === \"esm\" ? \"mjs\" : \"js\"}`,\n        format,\n        sourcemap: true,\n      },\n    ],\n    plugins: [\n      nodeResolve(),\n      esbuild({\n        sourceMap: true,\n        target: \"esnext\",\n      }),\n    ],\n  });\n\nconst dtsRollup = () =>\n  defineConfig({\n    input: \"build/index.d.ts\",\n    output: [{ file: `dist/index.d.ts`, format: \"es\" }],\n    plugins: [dts()],\n  });\n\nconst config = [configGen(\"cjs\"), configGen(\"esm\"), dtsRollup()];\n\nexport default config;\n"
  },
  {
    "path": "packages/unis-core/src/api/use.ts",
    "content": "import { getWF } from \"./utils\";\n\nexport function use<T extends (...args: any[]) => any>(fn: T): ReturnType<T>;\nexport function use<T extends (...args: any[]) => any>(\n  fn: T,\n  raFn: Function\n): ReturnType<T>;\nexport function use<T extends (...args: any[]) => any>(fn: T, raFn?: Function) {\n  const workingFiber = getWF();\n  const effect = () => {\n    const result = fn(getWF());\n    return raFn?.(result);\n  };\n  workingFiber.stateEffects?.push(effect) ??\n    (workingFiber.stateEffects = [effect]);\n  return fn(workingFiber) as ReturnType<T>;\n}\n"
  },
  {
    "path": "packages/unis-core/src/api/useContext.ts",
    "content": "import { Context } from \"../context\";\nimport { Fiber } from \"../fiber\";\nimport { use } from \"./use\";\n\nexport function useContext<T extends Context>(ctx: T) {\n  return use(contextHof(ctx), arguments[1]);\n}\n\nconst contextHof = <T extends Context>(context: T) => {\n  const readContext = (fiber: Fiber): T[\"initial\"] => {\n    const { dependencyList = [] } = fiber.reconcileState!;\n    const result = [...dependencyList]\n      .reverse()\n      .find((d) => d.context === context);\n\n    if (result) {\n      if (fiber.dependencies) {\n        !fiber.dependencies.includes(result) && fiber.dependencies.push(result);\n      } else {\n        fiber.dependencies = [result];\n      }\n      return result.value;\n    } else {\n      return context.initial;\n    }\n  };\n  return (WF: Fiber) => readContext(WF);\n};\n"
  },
  {
    "path": "packages/unis-core/src/api/useEffect.ts",
    "content": "import { Effect, EFFECT_TYPE, getWF } from \"./utils\";\n\nexport const useEffect = (cb: Effect, depsFn?: () => any[]) => {\n  const workingFiber = getWF();\n  cb.depsFn = depsFn;\n  if (!cb.type) cb.type = EFFECT_TYPE.TICK;\n  workingFiber.effects?.push(cb) ?? (workingFiber.effects = [cb]);\n};\n"
  },
  {
    "path": "packages/unis-core/src/api/useId.ts",
    "content": "import { Fiber } from \"../fiber\";\nimport { getWF } from \"./utils\";\nimport { use } from \"./use\";\nimport { generateId } from \"../utils\";\n\nexport const idHof = () => {\n  let workingFiber = getWF();\n  if (!workingFiber.id) {\n    workingFiber.id = generateId();\n  }\n  return (WF: Fiber) => WF.id;\n};\n\nexport function useId() {\n  return use(idHof());\n}\n"
  },
  {
    "path": "packages/unis-core/src/api/useLayoutEffect.ts",
    "content": "import { useEffect } from \"./useEffect\";\nimport { Effect, EFFECT_TYPE } from \"./utils\";\n\nexport const useLayoutEffect = (cb: Effect, depsFn?: () => any[]) => {\n  cb.type = EFFECT_TYPE.LAYOUT;\n  return useEffect(cb, depsFn);\n};\n"
  },
  {
    "path": "packages/unis-core/src/api/useMemo.ts",
    "content": "import { use } from \"./use\";\nimport { Fiber, MemorizeState } from \"../fiber\";\nimport { arraysEqual } from \"../utils\";\nimport { addDispatchEffect, linkMemorizeState } from \"./useReducer\";\n\nexport const memoHof = <T extends unknown>(\n  handler: () => T,\n  depsFn?: () => any[]\n) => {\n  let freshFiber: Fiber | undefined;\n  let freshDeps: any[];\n  let freshMemorizeState: MemorizeState | undefined;\n\n  let memorizeState: MemorizeState = {\n    value: undefined,\n    deps: undefined!,\n  };\n\n  const effect = () => {\n    memorizeState = freshMemorizeState!;\n    memorizeState.deps = freshDeps;\n    freshFiber = undefined;\n    freshMemorizeState = undefined;\n  };\n\n  return (WF: Fiber) => {\n    freshFiber = WF;\n    freshDeps = depsFn?.() ?? freshDeps;\n\n    addDispatchEffect(freshFiber, effect);\n\n    freshMemorizeState = {\n      value:\n        depsFn && arraysEqual(memorizeState.deps, freshDeps)\n          ? memorizeState.value\n          : handler(),\n      deps: memorizeState?.deps,\n    };\n\n    linkMemorizeState(freshFiber, freshMemorizeState);\n\n    return freshMemorizeState.value as T;\n  };\n};\n\nexport function useMemo<T extends unknown>(\n  handler: () => T,\n  depsFn?: () => any[]\n) {\n  return use(memoHof(handler, depsFn), arguments[2]);\n}\n"
  },
  {
    "path": "packages/unis-core/src/api/useProps.ts",
    "content": "import { Fiber } from \"../fiber\";\nimport { use } from \"./use\";\n\nexport function useProps<T>(p: T) {\n  return use(propsHof(p), arguments[1]);\n}\n\nexport const propsHof = <T>(props: T) => {\n  return (WF: Fiber) => WF.props as T;\n};\n"
  },
  {
    "path": "packages/unis-core/src/api/useReducer.ts",
    "content": "import { Effect, markFiber } from \"./utils\";\nimport { use } from \"./use\";\nimport { Fiber, findRoot, findRuntime, MemorizeState, TokTik } from \"../fiber\";\nimport { readyForWork } from \"../reconcile\";\n\nexport type Reducer<T, T2> = (state: T, action: T2) => T;\n\nconst readyList: (() => Fiber)[] = [];\n\nconst triggerReconcile = () => {\n  const fibers = new Set(readyList.map((getFiber) => getFiber()));\n  fibers.forEach(markFiber);\n\n  // multiple app trigger same time\n  const rootFibers = new Set(Array.from(fibers).map(findRoot));\n  rootFibers.forEach((fiber) => readyForWork(fiber));\n\n  readyList.length = 0;\n};\n\nexport const reducerHof = <T extends any, T2 extends any>(\n  reducerFn: Reducer<T, T2>,\n  initial: T\n) => {\n  let currentFiber: Fiber | undefined; // do not getWF here, workingFiber should be assigned in effect.\n  let freshFiber: Fiber | undefined;\n  let freshMemorizeState: MemorizeState | undefined;\n  let toktik: TokTik | undefined;\n\n  let memorizeState: MemorizeState = {\n    value: undefined,\n    dispatchValue: initial,\n    deps: [initial],\n  };\n\n  const dispatch = (action: T2) => {\n    if (!currentFiber) return console.warn(\"Component is not created\");\n    if (currentFiber.isDestroyed)\n      return console.warn(\"Component has been destroyed\");\n\n    const newState = reducerFn(memorizeState.value, action);\n    if (Object.is(newState, memorizeState.value)) return;\n\n    memorizeState.dispatchValue = newState;\n    memorizeState.deps = [newState];\n\n    if (freshFiber) {\n      toktik!.clearTikTaskQueue();\n    }\n\n    readyList.push(() => currentFiber!);\n\n    if (readyList.length === 1) {\n      toktik!.addTok(triggerReconcile, true);\n    }\n  };\n\n  const effect: Effect = () => {\n    currentFiber = freshFiber!;\n    memorizeState = freshMemorizeState!;\n    if (!toktik) toktik = findRuntime(currentFiber).toktik;\n    freshFiber = undefined;\n    freshMemorizeState = undefined;\n  };\n\n  return (WF: Fiber) => {\n    freshFiber = WF;\n\n    addDispatchEffect(freshFiber, effect);\n\n    freshMemorizeState = {\n      value:\n        memorizeState.deps.length > 0\n          ? memorizeState.dispatchValue\n          : memorizeState.value,\n      deps: [],\n    };\n\n    linkMemorizeState(freshFiber, freshMemorizeState);\n\n    return [freshMemorizeState.value, dispatch] as const;\n  };\n};\n\nexport function useReducer<T, T2>(reducerFn: Reducer<T, T2>, initial: T) {\n  return use(reducerHof(reducerFn, initial), arguments[2]);\n}\n\nexport const addDispatchEffect = (freshFiber: Fiber, effect: Effect) => {\n  freshFiber.reconcileState!.dispatchEffectList?.push(effect) ??\n    (freshFiber.reconcileState!.dispatchEffectList = [effect]);\n};\n\nexport const linkMemorizeState = (\n  freshFiber: Fiber,\n  freshMemorizeState: MemorizeState\n) => {\n  if (freshFiber.memorizeState) {\n    const first = freshFiber.memorizeState.next;\n    freshFiber.memorizeState.next = freshMemorizeState;\n    freshMemorizeState.next = first;\n  } else {\n    freshFiber.memorizeState = freshMemorizeState;\n    freshMemorizeState.next = freshMemorizeState;\n  }\n};\n\nexport const cutMemorizeState = (fiber: Fiber) => {\n  const first = fiber.memorizeState?.next;\n  fiber.memorizeState && (fiber.memorizeState.next = undefined);\n  fiber.memorizeState = first;\n};\n"
  },
  {
    "path": "packages/unis-core/src/api/useRef.ts",
    "content": "export interface Ref<T> {\n  current: T;\n}\n\nexport function useRef<T>(): Ref<T | undefined>;\nexport function useRef<T>(value: T): Ref<T>;\nexport function useRef<T>(value?: T) {\n  return { current: value };\n}\n"
  },
  {
    "path": "packages/unis-core/src/api/useState.ts",
    "content": "import { use } from \"./use\";\nimport { reducerHof } from \"./useReducer\";\n\nexport const stateHof = <T extends any>(initial: T) => {\n  return reducerHof<T, T>((preState, action) => action, initial);\n};\n\nexport function useState<T = undefined>(): [\n  T | undefined,\n  (value: T | undefined) => void\n];\nexport function useState<T>(initial: T): [T, (value: T) => void];\nexport function useState<T>(initial?: T) {\n  return use(stateHof(initial), arguments[1]);\n}\n"
  },
  {
    "path": "packages/unis-core/src/api/utils.ts",
    "content": "import { Fiber, FLAG, mergeFlag } from \"../fiber\";\nimport { getWorkingFiber } from \"../reconcile\";\nimport { arraysEqual } from \"../utils\";\n\nexport enum EFFECT_TYPE {\n  LAYOUT = \"layout\",\n  TICK = \"tick\",\n}\n\nexport type Effect = (() => (() => void) | void) & {\n  type?: EFFECT_TYPE;\n  clear?: (() => void) | void;\n  depsFn?: () => any;\n  deps?: any;\n};\n\nexport const getWF = (): Fiber | never => {\n  const workingFiber = getWorkingFiber();\n  if (workingFiber) {\n    return workingFiber;\n  } else {\n    throw Error(\"Do not call use function outside of component\");\n  }\n};\n\nexport const markFiber = (workingFiber: Fiber) => {\n  workingFiber.flag = mergeFlag(workingFiber.flag, FLAG.UPDATE);\n\n  let iFiber: Fiber | undefined = workingFiber;\n\n  while ((iFiber = iFiber.parent)) {\n    if (iFiber.childFlag) break;\n    iFiber.childFlag = mergeFlag(iFiber.childFlag, FLAG.UPDATE);\n  }\n};\n\nexport const runStateEffects = (fiber: Fiber) => {\n  for (const effect of fiber.stateEffects ?? []) {\n    effect();\n  }\n};\n\nexport const effectDepsEqual = (effect: Effect) => {\n  const deps = effect.depsFn?.();\n  const equal = arraysEqual(deps, effect.deps);\n  effect.deps = deps;\n  return equal;\n};\n\nexport const clearEffects = (effects?: Effect[]) => {\n  if (!effects) return;\n  for (const effect of effects) {\n    effect.clear?.();\n  }\n};\n\nexport const runEffects = (effects?: Effect[]) => {\n  if (!effects) return;\n  for (const effect of effects) {\n    effect.clear = effect();\n  }\n};\n\nexport const clearAndRunEffects = (effects?: Effect[]) => {\n  if (!effects) return;\n  for (const effect of effects) {\n    if (effectDepsEqual(effect)) continue;\n    effect.clear?.();\n    effect.clear = effect();\n  }\n};\n"
  },
  {
    "path": "packages/unis-core/src/commit.ts",
    "content": "import { clearEffects } from \"./api/utils\";\nimport {\n  Fiber,\n  findEls,\n  FLAG,\n  getContainerElFiber,\n  graft,\n  isComponent,\n  isHostElement,\n  matchFlag,\n  isText,\n  isElement,\n  ReconcileState,\n  isPortal,\n  Operator,\n} from \"./fiber\";\n\nexport const commitDeletion = (fiber: Fiber, operator: Operator) => {\n  let iFiber: Fiber | undefined = fiber;\n\n  while (iFiber) {\n    if (isHostElement(iFiber)) {\n      iFiber.props.ref && (iFiber.props.ref.current = undefined);\n    }\n    if (isComponent(iFiber)) {\n      clearEffects(iFiber.effects);\n    }\n    /**\n     * remove input element may trigger blur sync event,\n     * so isDestroyed must be true before remove to prevent dispatch in useReducer.\n     */\n    iFiber.isDestroyed = true;\n    if (isPortal(iFiber)) {\n      iFiber.child && operator.remove(iFiber.child);\n    }\n    iFiber.dependencies = undefined;\n    iFiber.reconcileState = undefined;\n\n    if (iFiber.child) {\n      iFiber = iFiber.child;\n      continue;\n    } else if (iFiber === fiber) {\n      iFiber = undefined;\n      continue;\n    }\n\n    while (iFiber) {\n      if (iFiber.sibling) {\n        iFiber = iFiber.sibling;\n        break;\n      }\n\n      if (iFiber.parent !== fiber) {\n        iFiber = iFiber.parent;\n      } else {\n        iFiber = undefined;\n        break;\n      }\n    }\n  }\n\n  operator.remove(fiber);\n};\n\nexport const commitUpdate = (fiber: Fiber, operator: Operator) => {\n  if (isText(fiber)) operator.updateTextProperties(fiber);\n  if (isHostElement(fiber)) operator.updateElementProperties(fiber);\n};\n\nexport const commitInsert = (fiber: Fiber, operator: Operator) => {\n  const container = getContainerElFiber(fiber)!;\n\n  const insertElements = isElement(fiber)\n    ? [fiber.el!]\n    : findEls(\n        matchFlag(fiber.commitFlag, FLAG.REUSE) ? fiber.alternate! : fiber\n      );\n\n  const insertTarget = isPortal(container)\n    ? null\n    : fiber.preElFiber\n    ? operator.nextSibling(fiber.preElFiber)\n    : operator.firstChild(container);\n\n  for (const insertElement of insertElements) {\n    operator.insertBefore(container, insertElement, insertTarget);\n  }\n};\n\nexport const commit = (reconcileState: ReconcileState) => {\n  const { operator } = reconcileState.rootWorkingFiber.runtime!;\n  for (const fiber of reconcileState.commitList) {\n    if (matchFlag(fiber.commitFlag, FLAG.DELETE)) {\n      commitDeletion(fiber.alternate!, operator);\n      continue;\n    }\n    if (matchFlag(fiber.commitFlag, FLAG.UPDATE)) {\n      commitUpdate(fiber, operator);\n    }\n    if (matchFlag(fiber.commitFlag, FLAG.INSERT)) {\n      commitInsert(fiber, operator);\n    }\n    if (matchFlag(fiber.commitFlag, FLAG.REUSE)) {\n      graft(fiber, fiber.alternate!);\n    }\n    fiber.preElFiber = undefined;\n    fiber.alternate = undefined;\n    fiber.commitFlag = undefined;\n  }\n};\n"
  },
  {
    "path": "packages/unis-core/src/context.ts",
    "content": "import { useProps } from \"./api/useProps\";\nimport { useContext } from \"./api/useContext\";\nimport { PROVIDER, Fiber } from \"./fiber\";\n\nexport interface Context<T = any> {\n  Provider: (props: { value: T; children: any }) => JSX.Element;\n  Consumer: (props: { children: (value: T) => JSX.Element }) => JSX.Element;\n  initial: T;\n}\n\nexport interface Dependency<T = any> {\n  context: Context<T>;\n  value: T;\n}\n\nconst providerContextMap = new WeakMap<Function, Context>();\n\nexport const createDependency = (fiber: Fiber) => {\n  return {\n    context: providerContextMap.get(fiber.tag as Function)!,\n    value: fiber.props.value,\n  };\n};\n\nexport const findDependency = (fiber: Fiber, contextFiber: Fiber) =>\n  fiber.dependencies?.find(\n    (dependency) =>\n      dependency.context ===\n      providerContextMap.get(contextFiber.tag as Function)\n  );\n\nexport function createContext<T>(initial: T): Context<T>;\nexport function createContext<T>(initial: T) {\n  const Provider = (props: { value: T; children: any }) => props.children;\n\n  Provider.take = {\n    type: PROVIDER,\n  };\n\n  const Consumer = (props: { children: (value: T) => JSX.Element }) => {\n    let p = useProps(\n      props,\n      // @ts-ignore\n      ($) => (p = $)\n    );\n    let state = useContext(\n      context,\n      // @ts-ignore\n      ($) => (state = $)\n    );\n    return () => p.children(state);\n  };\n\n  const context: Context<T> = {\n    Provider,\n    Consumer,\n    initial,\n  };\n\n  providerContextMap.set(Provider, context);\n\n  return context;\n}\n"
  },
  {
    "path": "packages/unis-core/src/createTokTik.ts",
    "content": "export type Task = Function & { isTok?: any };\n\nexport const createTokTik = (options: {\n  nextTick: (cb: VoidFunction, pending: boolean) => void;\n  now: () => number;\n  interval?: number;\n}) => {\n  const { nextTick, now, interval = 4 } = options;\n\n  const timeSlicing = !!interval;\n\n  let lastTime: number = 0;\n  let looping = false;\n\n  const tikQueue: Task[] = [];\n  const tokQueue: Task[] = [];\n\n  const next = () => tikQueue[0] ?? tokQueue[0];\n\n  const pick = () => tikQueue.shift() ?? tokQueue.shift();\n\n  const loop = (task: Task): void => {\n    looping = true;\n    runTask(task);\n    const nextTask = next();\n    if (nextTask) {\n      if (shouldYield() || nextTask.isTok) {\n        nextTick(() => loop(pick()!), nextTask.isTok);\n      } else {\n        loop(pick()!);\n      }\n      return;\n    }\n    looping = false;\n  };\n\n  const runTask = timeSlicing\n    ? (task: Task) => {\n        lastTime = now();\n        return task();\n      }\n    : (task: Task) => task();\n\n  const addTok = (task: Task, pending = false) => {\n    task.isTok = true;\n    looping\n      ? tokQueue.push(task)\n      : pending\n      ? nextTick(() => loop(task), pending)\n      : loop(task);\n  };\n\n  const addTik = (task: Task) => {\n    looping && tikQueue.push(task);\n  };\n\n  const clearTikTaskQueue = () => (tikQueue.length = 0);\n\n  const shouldYield = timeSlicing\n    ? () => now() - lastTime > interval\n    : () => false;\n\n  return {\n    addTok,\n    addTik,\n    clearTikTaskQueue,\n    shouldYield,\n  };\n};\n"
  },
  {
    "path": "packages/unis-core/src/diff.ts",
    "content": "import {\n  clearFlag,\n  Fiber,\n  FLAG,\n  isElement,\n  matchFlag,\n  isPortal,\n  isSame,\n  mergeFlag,\n  isComponent,\n  ReconcileState,\n  isText,\n  findToRoot,\n} from \"./fiber\";\nimport {\n  classes,\n  isNullish,\n  isStr,\n  isEvent,\n  keys,\n  styleStr,\n  svgKey,\n} from \"./utils\";\n\nexport type AttrDiff = [string, any, any][];\n\nexport const attrDiff = (\n  newFiber: Record<string, any>,\n  oldFiber: Record<string, any>,\n  onlyEvent = false\n) => {\n  const diff: AttrDiff = [];\n  const newProps = newFiber.props;\n  const oldProps = oldFiber.props;\n\n  const getRealAttr = (attr: string) => {\n    if (attr === \"className\") return \"class\";\n    if (attr === \"htmlFor\") return \"for\";\n    if (newFiber.isSvg) return svgKey(attr);\n    return attr.toLowerCase();\n  };\n\n  const getRealValue = (newValue: any, key: string) => {\n    if (isNullish(newValue)) return;\n    switch (key) {\n      case \"className\":\n        return isStr(newValue) ? newValue : classes(newValue);\n      case \"style\":\n        return isStr(newValue)\n          ? newValue\n          : styleStr(newValue as Partial<CSSStyleDeclaration>);\n      default:\n        return newValue;\n    }\n  };\n\n  for (const key of keys({ ...newProps, ...oldProps })) {\n    if (onlyEvent && !isEvent(key)) continue;\n    if ([\"xmlns\", \"children\"].includes(key)) continue;\n    const newValue = newProps[key];\n    const oldValue = oldProps[key];\n    const realNewValue = getRealValue(newValue, key);\n    const realOldValue = getRealValue(oldValue, key);\n    if (\n      !isNullish(newValue) &&\n      !isNullish(oldValue) &&\n      realNewValue === realOldValue\n    )\n      continue;\n    diff.push([getRealAttr(key), realNewValue, realOldValue]);\n  }\n\n  return diff;\n};\n\nexport const clone = (newFiber: Fiber, oldFiber: Fiber, commitFlag?: FLAG) =>\n  Object.assign(\n    {\n      ...newFiber,\n      commitFlag,\n      alternate: oldFiber,\n    },\n    isComponent(newFiber)\n      ? {\n          renderFn: oldFiber.renderFn,\n          rendered: oldFiber.rendered,\n          stateEffects: oldFiber.stateEffects,\n          effects: oldFiber.effects,\n          id: oldFiber.id,\n        }\n      : isElement(newFiber)\n      ? { el: oldFiber.el, isSvg: oldFiber.isSvg }\n      : isPortal(newFiber)\n      ? { to: oldFiber.to }\n      : undefined\n  );\n\nexport const reuse = (newFiber: Fiber, oldFiber: Fiber, commitFlag?: FLAG) => ({\n  ...newFiber,\n  commitFlag,\n  alternate: oldFiber,\n});\n\nexport const del = (oldFiber: Fiber): Fiber => ({\n  commitFlag: FLAG.DELETE,\n  alternate: oldFiber,\n});\n\nexport const create = (\n  newFiber: Fiber,\n  parentFiber: Fiber,\n  hydrate = false\n) => {\n  const retFiber = {\n    ...newFiber,\n    commitFlag: matchFlag(parentFiber.commitFlag, FLAG.CREATE)\n      ? FLAG.CREATE\n      : FLAG.CREATE | FLAG.INSERT,\n  } as Fiber;\n\n  if (isElement(newFiber)) {\n    retFiber.isSvg = newFiber.tag === \"svg\" || parentFiber.isSvg;\n    if (!hydrate) {\n      retFiber.attrDiff = isText(retFiber)\n        ? undefined\n        : attrDiff(retFiber, { props: {} });\n    }\n  }\n\n  if (isPortal(newFiber)) {\n    retFiber.commitFlag = undefined;\n  }\n\n  return retFiber;\n};\n\nexport const keyIndexMapGen = (\n  children: Fiber[],\n  start: number,\n  end: number\n) => {\n  const map: any = {};\n  for (let i = start; i <= end; i++) {\n    const key = children[i].props?.key;\n    if (key !== undefined) map[key] = i;\n  }\n  return map;\n};\n\nconst determineCommitFlag = (\n  parentFiber: Fiber,\n  newFiber: Fiber,\n  oldFiber: Fiber,\n  flag?: FLAG\n) => {\n  /**\n   * the nearest parent component fiber\n   */\n  const nearestComponent = isComponent(parentFiber)\n    ? parentFiber\n    : findToRoot(parentFiber, (fiber) => isComponent(fiber));\n\n  /**\n   * when nearest parent component fiber with FLAG.UPDATE commitFlag, it should be FLAG.UPDATE.\n   */\n  let commitFlag =\n    !matchFlag(nearestComponent?.commitFlag, FLAG.UPDATE) &&\n    parentFiber.alternate!.childFlag\n      ? !oldFiber.childFlag && !oldFiber.flag\n        ? FLAG.REUSE\n        : oldFiber.flag\n      : FLAG.UPDATE;\n\n  /**\n   * when memo fiber compare result is true, it should be FLAG.REUSE.\n   */\n  if (\n    isComponent(oldFiber) &&\n    !oldFiber.childFlag &&\n    !oldFiber.flag &&\n    (oldFiber.tag as Function & { compare?: Function }).compare?.(\n      newFiber.props,\n      oldFiber.props\n    )\n  ) {\n    commitFlag = mergeFlag(commitFlag, FLAG.REUSE);\n  }\n\n  if (isElement(newFiber) && matchFlag(commitFlag, FLAG.UPDATE)) {\n    let diff = attrDiff(newFiber, oldFiber);\n    if (diff.length) {\n      newFiber.attrDiff = diff;\n    } else {\n      commitFlag = clearFlag(commitFlag, FLAG.UPDATE);\n    }\n  }\n\n  flag && (commitFlag = mergeFlag(commitFlag, flag));\n\n  /**\n   * portal don't need commitFlag\n   */\n  if (isPortal(newFiber)) {\n    commitFlag = undefined;\n  }\n\n  if (matchFlag(commitFlag, FLAG.REUSE)) {\n    commitFlag = clearFlag(commitFlag, FLAG.UPDATE);\n  }\n\n  return commitFlag;\n};\n\nconst getSameNewFiber = (\n  parentFiber: Fiber,\n  newFiber: Fiber,\n  oldFiber: Fiber,\n  flag?: FLAG\n) => {\n  const commitFlag = determineCommitFlag(parentFiber, newFiber, oldFiber, flag);\n  return matchFlag(commitFlag, FLAG.REUSE)\n    ? reuse(newFiber, oldFiber, commitFlag)\n    : clone(newFiber, oldFiber, commitFlag);\n};\n\nexport const diff = (\n  parentFiber: Fiber,\n  oldChildren: Fiber[] = [],\n  newChildren: Fiber[] = []\n) => {\n  const { reconcileState } = parentFiber as { reconcileState: ReconcileState };\n\n  let cloneChildren: Fiber[] = [];\n  let newStartIndex = 0;\n  let newEndIndex = newChildren.length - 1;\n  let oldStartIndex = 0;\n  let oldEndIndex = oldChildren.length - 1;\n\n  let newStartFiber = newChildren[newStartIndex];\n  let newEndFiber = newChildren[newEndIndex];\n  let oldStartFiber = oldChildren[oldStartIndex];\n  let oldEndFiber = oldChildren[oldEndIndex];\n\n  let preStartFiber: Fiber | undefined;\n  let preEndFiber: Fiber | undefined;\n\n  const deletion = (fiber: Fiber) => {\n    reconcileState.commitList.push(del(fiber));\n  };\n\n  const forward = () => {\n    if (preStartFiber) preStartFiber.sibling = newStartFiber;\n    newStartFiber.parent = parentFiber;\n    newStartFiber.index = newStartIndex;\n    newStartFiber.reconcileState = reconcileState;\n    preStartFiber = newStartFiber;\n    cloneChildren[newStartIndex] = newStartFiber;\n    newStartFiber = newChildren[++newStartIndex];\n  };\n\n  const forwardEnd = () => {\n    if (preEndFiber) newEndFiber.sibling = preEndFiber;\n    newEndFiber.parent = parentFiber;\n    newEndFiber.index = newEndIndex;\n    newEndFiber.reconcileState = reconcileState;\n    preEndFiber = newEndFiber;\n    cloneChildren[newEndIndex] = newEndFiber;\n    newEndFiber = newChildren[--newEndIndex];\n  };\n\n  const oldForward = () => {\n    oldStartFiber = oldChildren[++oldStartIndex];\n  };\n\n  const oldForwardEnd = () => {\n    oldEndFiber = oldChildren[--oldEndIndex];\n  };\n\n  let keyIndexMap: any;\n\n  while (newStartIndex <= newEndIndex && oldStartIndex <= oldEndIndex) {\n    if (oldStartFiber === undefined) {\n      oldForward();\n    } else if (oldEndFiber === undefined) {\n      oldForwardEnd();\n    } else if (isSame(newStartFiber, oldStartFiber)) {\n      newStartFiber = getSameNewFiber(\n        parentFiber,\n        newStartFiber,\n        oldStartFiber\n      );\n      forward();\n      oldForward();\n    } else if (isSame(newEndFiber, oldEndFiber)) {\n      newEndFiber = getSameNewFiber(parentFiber, newEndFiber, oldEndFiber);\n      forwardEnd();\n      oldForwardEnd();\n    } else if (isSame(newStartFiber, oldEndFiber)) {\n      newStartFiber = getSameNewFiber(\n        parentFiber,\n        newStartFiber,\n        oldEndFiber,\n        FLAG.INSERT\n      );\n      forward();\n      oldForwardEnd();\n    } else if (isSame(newEndFiber, oldStartFiber)) {\n      newEndFiber = getSameNewFiber(\n        parentFiber,\n        newEndFiber,\n        oldStartFiber,\n        FLAG.INSERT\n      );\n      forwardEnd();\n      oldForward();\n    } else {\n      if (!keyIndexMap) {\n        keyIndexMap = keyIndexMapGen(oldChildren, oldStartIndex, oldEndIndex);\n      }\n      const index = keyIndexMap[newStartFiber.props.key];\n      if (isNaN(index)) {\n        newStartFiber = create(newStartFiber, parentFiber);\n      } else {\n        const targetFiber = oldChildren[index];\n        if (isSame(newStartFiber, targetFiber)) {\n          newStartFiber = getSameNewFiber(\n            parentFiber,\n            newStartFiber,\n            targetFiber,\n            FLAG.INSERT\n          );\n          oldChildren[index] = undefined as unknown as Fiber;\n        } else {\n          newStartFiber = create(newStartFiber, parentFiber);\n        }\n      }\n      forward();\n    }\n  }\n\n  if (oldStartIndex > oldEndIndex) {\n    newChildren.slice(newStartIndex, newEndIndex + 1).forEach((fiber) => {\n      newStartFiber = create(\n        newStartFiber,\n        parentFiber,\n        reconcileState.hydrate\n      );\n      forward();\n    });\n  } else if (newStartIndex > newEndIndex) {\n    oldChildren\n      .slice(oldStartIndex, oldEndIndex + 1)\n      .forEach((fiber) => fiber && deletion(fiber));\n  }\n\n  if (preStartFiber && preEndFiber) preStartFiber.sibling = preEndFiber;\n\n  parentFiber.child = cloneChildren[0];\n  parentFiber.children = cloneChildren;\n};\n"
  },
  {
    "path": "packages/unis-core/src/fiber.ts",
    "content": "import { Effect } from \"./api/utils\";\nimport { Dependency } from \"./context\";\nimport { AttrDiff } from \"./diff\";\nimport { isFun, isNullish } from \"./utils\";\n\nexport interface ReconcileState {\n  rootWorkingFiber: Fiber;\n  dispatchEffectList: Effect[];\n  commitList: Fiber[];\n  dependencyList: Dependency[];\n  workingPreElFiber?: Fiber;\n  hydrate: boolean;\n  hydrateEl?: FiberEl;\n}\n\nexport enum FLAG {\n  CREATE = 1 << 1,\n  INSERT = 1 << 2,\n  UPDATE = 1 << 3,\n  DELETE = 1 << 4,\n  REUSE = 1 << 5,\n}\n\nexport type FlagName = \"flag\" | \"childFlag\" | \"commitFlag\";\n\nexport const mergeFlag = (a: FLAG | undefined, b: FLAG) =>\n  isNullish(a) ? b : a | b;\n\nexport const clearFlag = (a: FLAG | undefined, b: FLAG) =>\n  isNullish(a) ? a : a & ~b;\n\nexport const matchFlag = (a: FLAG | undefined, b: FLAG) =>\n  isNullish(a) ? false : a & b;\n\nexport type FiberEl = unknown;\nexport type FiberType =\n  | string\n  | Function\n  | Symbol\n  | ((...p: any[]) => () => any);\n\nexport interface MemorizeState {\n  value: any;\n  dispatchValue?: any;\n  deps: any[];\n  next?: MemorizeState;\n}\n\nexport interface TokTik {\n  addTok: (task: Function, pending?: boolean) => void;\n  addTik: (task: Function) => void;\n  clearTikTaskQueue: () => void;\n  shouldYield: () => boolean;\n}\n\nexport interface Operator {\n  // for reuse element when hydrate\n  nextElement(el: FiberEl): FiberEl | null;\n\n  // for reuse element when hydrate\n  matchElement(fiber: Fiber, el: FiberEl): boolean;\n\n  createElement(fiber: Fiber): FiberEl;\n\n  remove(fiber: Fiber): void;\n\n  insertBefore(\n    containerFiber: Fiber,\n    insertElement: FiberEl,\n    targetElement: FiberEl | null\n  ): void;\n\n  firstChild(fiber: Fiber): FiberEl | null;\n\n  nextSibling(fiber: Fiber): FiberEl | null;\n\n  updateTextProperties(fiber: Fiber): void;\n\n  updateElementProperties(fiber: Fiber): void;\n}\n\nexport interface Runtime {\n  toktik: TokTik;\n  operator: Operator;\n}\n\nexport interface Fiber {\n  id?: string;\n  parent?: Fiber;\n  child?: Fiber;\n  sibling?: Fiber;\n  index?: number;\n  to?: FiberEl;\n  el?: FiberEl;\n  preElFiber?: Fiber;\n  isSvg?: boolean;\n  isDestroyed?: boolean;\n  props?: any;\n  compare?: Function;\n  attrDiff?: AttrDiff;\n  alternate?: Fiber;\n  tag?: string | Function;\n  type?: Symbol;\n  renderFn?: Function;\n  rendered?: any;\n  flag?: FLAG;\n  childFlag?: FLAG;\n  commitFlag?: FLAG;\n  children?: Fiber[];\n  stateEffects?: Effect[];\n  effects?: Effect[];\n  dependencies?: Dependency[];\n  reconcileState?: ReconcileState;\n  memorizeState?: MemorizeState;\n  runtime?: Runtime;\n}\n\nexport const createFiber = (options: Partial<Fiber> = {}) =>\n  Object.assign<Fiber, Fiber>(\n    {\n      id: undefined,\n      parent: undefined,\n      child: undefined,\n      sibling: undefined,\n      index: undefined,\n      to: undefined,\n      el: undefined,\n      preElFiber: undefined,\n      isSvg: undefined,\n      isDestroyed: undefined,\n      props: undefined,\n      compare: undefined,\n      attrDiff: undefined,\n      alternate: undefined,\n      tag: undefined,\n      type: undefined,\n      renderFn: undefined,\n      rendered: undefined,\n      flag: undefined,\n      childFlag: undefined,\n      commitFlag: undefined,\n      children: undefined,\n      stateEffects: undefined,\n      effects: undefined,\n      dependencies: undefined,\n      reconcileState: undefined,\n      memorizeState: undefined,\n    },\n    options\n  );\n\nexport const TEXT = Symbol(\"$$Text\");\nexport const ELEMENT = Symbol(\"$$Element\");\nexport const PORTAL = Symbol(\"$$Portal\");\nexport const PROVIDER = Symbol(\"$$Provider\");\nexport const COMPONENT = Symbol(\"$$Component\");\n\nexport const isText = (fiber: Fiber) => fiber.type === TEXT;\nexport const isHostElement = (fiber: Fiber) => fiber.type === ELEMENT;\nexport const isElement = (fiber: Fiber) =>\n  isHostElement(fiber) || isText(fiber);\n\nexport const isPortal = (fiber: Fiber) => fiber.type === PORTAL;\nexport const isProvider = (fiber: Fiber) => fiber.type === PROVIDER;\nexport const isCustomComponent = (fiber: Fiber) => fiber.type === COMPONENT;\nexport const isComponent = (fiber: Fiber) => isFun(fiber.tag);\n\nexport const isSame = (fiber1?: Fiber, fiber2?: Fiber) =>\n  fiber1 &&\n  fiber2 &&\n  fiber1.tag === fiber2.tag &&\n  fiber1.props?.key === fiber2.props?.key;\n\nexport interface WalkHook {\n  enter?: (currentFiber: Fiber, skipChild: boolean) => any;\n  down?: (currentFiber: Fiber, nextFiber: Fiber) => any;\n  sibling?: (currentFiber: Fiber, nextFiber?: Fiber) => any;\n  up?: (currentFiber: Fiber, nextFiber?: Fiber) => any;\n  return?: (currentFiber?: Fiber) => any;\n}\n\nexport type WalkHookKeys = keyof WalkHook;\n\nexport type WalkHookList = {\n  [K in keyof WalkHook]: WalkHook[K][];\n};\n\nexport const createNext = () => {\n  const walkHooks: WalkHookList = {};\n\n  const addHook = (walkHook: WalkHook) => {\n    Object.entries(walkHook).forEach(([key, value]) => {\n      const list = walkHooks[key as WalkHookKeys];\n      list ? list.push(value) : (walkHooks[key as WalkHookKeys] = [value]);\n    });\n  };\n\n  const runWalkHooks = <T extends WalkHookKeys>(\n    key: T,\n    ...args: Parameters<Required<WalkHook>[T]>\n  ) => {\n    return walkHooks[key]?.map((hook) => hook!(...(args as [any, any])));\n  };\n\n  const next = (fiber: Fiber, skipChild = false): Fiber | undefined => {\n    if (runWalkHooks(\"enter\", fiber, skipChild)?.includes(false)) return;\n    const { child } = fiber;\n    let nextFiber: Fiber | undefined = fiber;\n    if (child && !skipChild) {\n      runWalkHooks(\"down\", nextFiber, child);\n      nextFiber = child;\n    } else {\n      while (nextFiber) {\n        const { sibling, parent } = nextFiber as Fiber;\n        if (sibling) {\n          runWalkHooks(\"sibling\", nextFiber, sibling);\n          nextFiber = sibling;\n          break;\n        }\n        if (runWalkHooks(\"up\", nextFiber, parent)?.includes(false)) {\n          nextFiber = undefined;\n          break;\n        }\n        nextFiber = parent;\n      }\n    }\n    runWalkHooks(\"return\", nextFiber);\n    return nextFiber;\n  };\n\n  return [next, addHook] as const;\n};\n\nexport const graft = (newFiber: Fiber, oldFiber: Fiber) => {\n  const parent = newFiber.parent!;\n  const parentChildren = parent.children!;\n  const index = newFiber.index!;\n  const preIndex = index - 1;\n\n  if (index === 0) parent.child = oldFiber;\n  if (preIndex >= 0) parentChildren[preIndex].sibling = oldFiber;\n\n  parentChildren[index] = oldFiber;\n\n  oldFiber.sibling = newFiber.sibling;\n  oldFiber.parent = parent;\n};\n\nexport const findEls = (fiber: Fiber, findInPortal = false) => {\n  const els: FiberEl[] = [];\n  isElement(fiber)\n    ? els.push(fiber.el!)\n    : isPortal(fiber) && !findInPortal\n    ? false\n    : fiber.children?.forEach((child) => {\n        els.push(...findEls(child, findInPortal));\n      });\n\n  return els;\n};\n\nexport const findLastElFiber = (fiber: Fiber): Fiber | undefined => {\n  if (isElement(fiber)) {\n    return fiber;\n  } else if (isPortal(fiber)) {\n    return undefined;\n  } else {\n    for (let i = 0; i < (fiber.children?.length ?? 0); i++) {\n      return findLastElFiber(fiber.children!.at(-(i + 1))!);\n    }\n  }\n};\n\nexport type ContainerElement = Exclude<FiberEl, Text>;\n\nexport const getContainerElFiber = (\n  fiber: Fiber | undefined\n): Fiber | undefined => {\n  while ((fiber = fiber?.parent)) {\n    if (isPortal(fiber) || isElement(fiber)) return fiber;\n  }\n};\n\nexport const findToRoot = (\n  fiber: Fiber | undefined,\n  cb: (fiber: Fiber) => boolean\n): Fiber | undefined => {\n  while ((fiber = fiber?.parent)) {\n    if (cb(fiber)) return fiber;\n  }\n};\n\nexport const findRoot = (fiber: Fiber) =>\n  findToRoot(fiber, (fiber) => !fiber.parent)!;\n\nexport const findRuntime = (fiber: Fiber) =>\n  fiber.reconcileState?.rootWorkingFiber\n    ? fiber.reconcileState.rootWorkingFiber.runtime!\n    : findRoot(fiber).runtime!;\n"
  },
  {
    "path": "packages/unis-core/src/h.ts",
    "content": "import { isNum, isStr, keys, toArray } from \"./utils\";\nimport {\n  COMPONENT,\n  createFiber,\n  ELEMENT,\n  Fiber,\n  FiberEl,\n  PORTAL,\n  TEXT,\n} from \"./fiber\";\n\nexport const h = (tag: any, props: any, ...children: any[]) => {\n  props = { ...props };\n  if (children.length === 1) props.children = children[0];\n  if (children.length > 1) props.children = children;\n  return createFiber({\n    tag,\n    type: isStr(tag) ? ELEMENT : COMPONENT,\n    props,\n    ...tag.take,\n  });\n};\n\nexport const h2 = (tag: any, props: any, key?: string | number) => {\n  if (key !== undefined) props.key = key;\n  return createFiber({\n    tag,\n    type: isStr(tag) ? ELEMENT : COMPONENT,\n    props,\n    ...tag.take,\n  });\n};\n\nexport const formatChildren = (children: any) => {\n  const formatedChildren: Fiber[] = [];\n\n  for (const child of toArray(children)) {\n    if ([null, false, true, undefined].includes(child)) {\n      continue;\n    } else {\n      Array.isArray(child)\n        ? formatedChildren.push(...formatChildren(child))\n        : formatedChildren.push(\n            isStr(child) || isNum(child)\n              ? createFiber({\n                  type: TEXT,\n                  props: { nodeValue: child },\n                })\n              : child\n          );\n    }\n  }\n\n  return formatedChildren;\n};\n\nexport const createRoot = (element: any, container: FiberEl): Fiber => {\n  return {\n    tag: (container as any).tagName.toLocaleLowerCase(),\n    type: ELEMENT,\n    el: container,\n    index: 0,\n    props: {\n      children: toArray(element),\n    },\n  };\n};\n\nexport const createPortal = (child: JSX.Element, container: FiberEl) =>\n  createFiber({\n    type: PORTAL,\n    props: { children: child },\n    to: container,\n  });\n\nconst defaultCompare = (newProps: any = {}, oldProps: any = {}) => {\n  const newKeys = keys(newProps);\n  const oldKeys = keys(oldProps);\n  if (newKeys.length !== oldKeys.length) return false;\n  return newKeys.every((key) => Object.is(newProps[key], oldProps[key]));\n};\n\nexport const memo = <\n  T extends ((props: any) => JSX.Element) & { compare?: Function }\n>(\n  child: T,\n  compare: Function = defaultCompare\n) => {\n  child.compare = compare;\n  return child;\n};\n\nexport const cloneElement = (\n  element: Fiber,\n  props = {},\n  ...children: JSX.Element[]\n) => h(element.tag, { ...props, ...props }, ...children);\n\nexport const createElement = h;\n\nexport const Fragment = (props: any) => props.children;\n\nexport const FGMT = Fragment;\n"
  },
  {
    "path": "packages/unis-core/src/index.ts",
    "content": "export * from \"./h\";\nexport * from \"./fiber\";\nexport * from \"./context\";\nexport * from \"./reconcile\";\nexport * from \"./utils\";\nexport * from \"./diff\";\nexport * from \"./createTokTik\";\nexport * from \"./api/utils\";\nexport * from \"./api/use\";\nexport * from \"./api/useState\";\nexport * from \"./api/useContext\";\nexport * from \"./api/useProps\";\nexport * from \"./api/useReducer\";\nexport * from \"./api/useMemo\";\nexport * from \"./api/useEffect\";\nexport * from \"./api/useLayoutEffect\";\nexport * from \"./api/useId\";\nexport * from \"./api/useRef\";\n\nexport type * from \"../types/jsx\";\n\nexport const unisFns = {\n  use: 1,\n  useState: 1,\n  useProps: 1,\n  useContext: 1,\n  useReducer: 2,\n  useMemo: 2,\n};\n"
  },
  {
    "path": "packages/unis-core/src/reconcile.ts",
    "content": "import {\n  clearAndRunEffects,\n  clearEffects,\n  Effect,\n  EFFECT_TYPE,\n  effectDepsEqual,\n  runEffects,\n  runStateEffects,\n} from \"./api/utils\";\nimport {\n  createNext,\n  Fiber,\n  FLAG,\n  ReconcileState,\n  isComponent,\n  createFiber,\n  matchFlag,\n  findRuntime,\n  isElement,\n} from \"./fiber\";\nimport { commit } from \"./commit\";\nimport { preElFiberWalkHook } from \"./reconcileWalkHooks/preElFiber\";\nimport { effectWalkHook } from \"./reconcileWalkHooks/effect\";\nimport { formatChildren } from \"./h\";\nimport { isFun } from \"./utils\";\nimport { diff } from \"./diff\";\nimport { contextWalkHook } from \"./reconcileWalkHooks/context\";\nimport { cutMemorizeState } from \"./api/useReducer\";\n\nlet workingFiber: Fiber | undefined;\n\nexport const getWorkingFiber = () => workingFiber;\nexport const setWorkingFiber = (fiber: Fiber | undefined) =>\n  (workingFiber = fiber);\n\n// reconcile walker\nconst [next, addHook] = createNext();\n\n// preEl\naddHook(preElFiberWalkHook);\n// effect\naddHook(effectWalkHook);\n// context\naddHook(contextWalkHook);\n\nexport const readyForWork = (rootCurrentFiber: Fiber, hydrate = false) => {\n  rootCurrentFiber.runtime!.toktik.addTok(() =>\n    performWork(rootCurrentFiber, hydrate)\n  );\n};\n\nconst performWork = (rootCurrentFiber: Fiber, hydrate: boolean) => {\n  const rootWorkingFiber = createFiber({\n    index: rootCurrentFiber.index,\n    tag: rootCurrentFiber.tag,\n    type: rootCurrentFiber.type,\n    props: rootCurrentFiber.props,\n    alternate: rootCurrentFiber,\n    el: rootCurrentFiber.el,\n    runtime: rootCurrentFiber.runtime,\n  });\n\n  const initialReconcileState: ReconcileState = {\n    rootWorkingFiber,\n    dispatchEffectList: [],\n    commitList: [],\n    dependencyList: [],\n    workingPreElFiber: undefined,\n    hydrate,\n    hydrateEl: rootCurrentFiber.el,\n  };\n\n  rootWorkingFiber.reconcileState = initialReconcileState;\n\n  setWorkingFiber(rootWorkingFiber);\n  tickWork(rootWorkingFiber!);\n};\n\nconst tickWork = (workingFiber: Fiber) => {\n  const { toktik } = findRuntime(workingFiber);\n\n  let iFiber: Fiber | undefined = workingFiber;\n\n  // work loop\n  while (iFiber && !toktik.shouldYield()) {\n    const isReuse = !!matchFlag(iFiber.commitFlag, FLAG.REUSE);\n    {\n      !isReuse && update(iFiber);\n      !isReuse && isElement(iFiber) && compose(iFiber);\n      complete(iFiber);\n    }\n    iFiber = next(iFiber, isReuse);\n    setWorkingFiber(iFiber);\n  }\n\n  if (iFiber) {\n    toktik.addTik(() => {\n      setWorkingFiber(iFiber);\n      tickWork(iFiber!);\n    });\n  } else {\n    const { reconcileState } = workingFiber;\n\n    // switch dispatch bind fiber\n    runEffects(reconcileState!.dispatchEffectList);\n\n    // commit\n    commit(reconcileState!);\n\n    // call component effects\n    callComponentEffects(reconcileState!);\n\n    // clear reconcileState\n    for (const prop of Object.keys(reconcileState!)) {\n      delete reconcileState![prop as keyof ReconcileState];\n    }\n  }\n};\n\nconst callComponentEffects = (reconcileState: ReconcileState) => {\n  const { commitList, rootWorkingFiber } = reconcileState!;\n  const { toktik } = rootWorkingFiber.runtime!;\n\n  const triggeredLayoutEffects: Effect[] = [];\n  const tickEffects: Effect[] = [];\n\n  // clear and run layoutEffects\n  for (const fiber of commitList) {\n    if (!isComponent(fiber)) continue;\n    for (const effect of fiber.effects ?? []) {\n      if (effect.type === EFFECT_TYPE.TICK) {\n        tickEffects.push(effect);\n      } else {\n        const equal = effectDepsEqual(effect);\n        if (!equal) {\n          triggeredLayoutEffects.push(effect);\n          clearEffects([effect]);\n        }\n      }\n    }\n  }\n\n  // run triggered layout effects\n  runEffects(triggeredLayoutEffects);\n\n  // clear and run tick effects\n  toktik.addTik(() => clearAndRunEffects(tickEffects));\n};\n\nconst update = (fiber: Fiber) => {\n  if (isComponent(fiber)) {\n    updateComponent(fiber);\n  } else {\n    updateHost(fiber);\n  }\n};\n\nconst updateHost = (fiber: Fiber) => {\n  diff(fiber, fiber.alternate?.children, formatChildren(fiber.props.children));\n};\n\nconst updateComponent = (fiber: Fiber) => {\n  if (!fiber.renderFn) {\n    fiber.renderFn = fiber.tag as Function;\n    let rendered = fiber.renderFn(fiber.props);\n    if (isFun(rendered)) {\n      fiber.renderFn = rendered;\n      rendered = fiber.renderFn!();\n    }\n    fiber.rendered = formatChildren(rendered);\n  } else {\n    runStateEffects(fiber);\n    if (matchFlag(fiber.commitFlag, FLAG.UPDATE)) {\n      fiber.rendered = formatChildren(fiber.renderFn(fiber.props));\n    } else {\n      /**\n       * this condition, means `fiber.alternate` is on childFlag marked chain, and `fiber.commitFlag` is undefined.\n       * diff will keep going on.\n       */\n    }\n  }\n\n  cutMemorizeState(fiber);\n\n  diff(fiber, fiber.alternate?.children, fiber.rendered);\n};\n\nconst compose = (fiber: Fiber) => {\n  const { hydrate, hydrateEl } = fiber.reconcileState!;\n  const { operator } = findRuntime(fiber);\n\n  if (hydrate && hydrateEl) {\n    if (!operator.matchElement(fiber, hydrateEl))\n      throw new Error(\"Hydrate failed!\");\n    fiber.el = hydrateEl;\n    fiber.reconcileState!.hydrateEl = operator.nextElement(hydrateEl);\n  } else if (matchFlag(fiber.commitFlag, FLAG.CREATE) && !hydrate) {\n    fiber.el = operator.createElement(fiber);\n    fiber.attrDiff?.length && operator.updateElementProperties(fiber);\n\n    let iFiber: Fiber | undefined = fiber;\n\n    while ((iFiber = iFiber.parent)) {\n      if (!matchFlag(iFiber.commitFlag, FLAG.CREATE)) break;\n      if (isElement(iFiber)) {\n        operator.insertBefore(iFiber, fiber.el, null);\n        break;\n      }\n    }\n  }\n};\n\nconst complete = (fiber: Fiber) => {\n  !fiber.commitFlag && (fiber.alternate = undefined);\n};\n"
  },
  {
    "path": "packages/unis-core/src/reconcileWalkHooks/context.ts",
    "content": "import { createDependency, findDependency } from \"../context\";\nimport { createNext, Fiber, isProvider, WalkHook } from \"../fiber\";\nimport { markFiber } from \"../api/utils\";\n\nexport const contextWalkHook: WalkHook = {\n  down: (from: Fiber, to?: Fiber) => {\n    isProvider(from) &&\n      from.reconcileState!.dependencyList.push(createDependency(from));\n  },\n\n  up: (from: Fiber, to?: Fiber) => {\n    to && isProvider(to) && from.reconcileState!.dependencyList.pop();\n  },\n\n  enter: (enter: Fiber, skipChild: boolean) => {\n    if (\n      enter.alternate &&\n      isProvider(enter.alternate) &&\n      !Object.is(enter.alternate.props.value, enter.props.value)\n    ) {\n      let alternate = enter.alternate;\n      let iFiber: Fiber | undefined = alternate;\n\n      const [next, addHook] = createNext();\n\n      addHook({ up: (from, to) => to !== alternate });\n\n      do {\n        findDependency(iFiber, enter) && markFiber(iFiber);\n        iFiber = next(\n          iFiber,\n          iFiber !== alternate && isProvider(iFiber) && iFiber.tag === enter.tag\n        );\n      } while (iFiber);\n    }\n  },\n};\n"
  },
  {
    "path": "packages/unis-core/src/reconcileWalkHooks/effect.ts",
    "content": "import { Fiber, WalkHook } from \"../fiber\";\n\nexport const pushEffect = (fiber: Fiber) => {\n  fiber.reconcileState!.commitList.push(fiber);\n};\n\nexport const effectWalkHook: WalkHook = {\n  up: (from, to) => {\n    !from.child && from.commitFlag && pushEffect(from);\n    to?.commitFlag && pushEffect(to);\n  },\n  sibling: (from) => {\n    !from.child && from.commitFlag && pushEffect(from);\n  },\n};\n"
  },
  {
    "path": "packages/unis-core/src/reconcileWalkHooks/preElFiber.ts",
    "content": "import {\n  Fiber,\n  findLastElFiber,\n  FLAG,\n  isElement,\n  isPortal,\n  matchFlag,\n  WalkHook,\n} from \"../fiber\";\n\nconst setWorkingPreElFiber = (\n  fiber: Fiber,\n  workingPreElFiber: Fiber | undefined\n) => {\n  if (fiber.reconcileState)\n    fiber.reconcileState.workingPreElFiber = workingPreElFiber;\n};\n\nconst setReuseFiberPreElFiber = (fiber: Fiber) => {\n  if (!matchFlag(fiber.commitFlag, FLAG.REUSE)) return;\n  const lastElFiber = findLastElFiber(fiber.alternate!);\n  lastElFiber && setWorkingPreElFiber(fiber, lastElFiber);\n};\n\nexport const preElFiberWalkHook: WalkHook = {\n  down: (from: Fiber, to?: Fiber) => {\n    isElement(from) && setWorkingPreElFiber(from, undefined);\n    isPortal(from) && setWorkingPreElFiber(from, undefined);\n  },\n\n  up: (from: Fiber, to?: Fiber) => {\n    if (from && !from.child) {\n      isElement(from) && setWorkingPreElFiber(from, from);\n    }\n    if (to) {\n      isElement(to) && setWorkingPreElFiber(from, to);\n      isPortal(to) && setWorkingPreElFiber(from, to.preElFiber);\n    }\n    setReuseFiberPreElFiber(from);\n  },\n\n  sibling: (from: Fiber, to?: Fiber) => {\n    if (matchFlag(from.commitFlag, FLAG.REUSE)) {\n      setReuseFiberPreElFiber(from);\n    } else {\n      isElement(from) && setWorkingPreElFiber(from, from);\n    }\n  },\n\n  return: (retn?: Fiber) => {\n    if (retn && matchFlag(retn.commitFlag, FLAG.INSERT))\n      retn.preElFiber = retn.reconcileState!.workingPreElFiber;\n  },\n};\n"
  },
  {
    "path": "packages/unis-core/src/svg.ts",
    "content": "// kebab svg attr keys\nexport const displayAttrs = [\n  \"baselineShift\",\n  \"alignmentBaseline\",\n  \"clip\",\n  \"clipPath\",\n  \"clipRule\",\n  \"color\",\n  \"colorInterpolation\",\n  \"colorInterpolationFilters\",\n  \"colorProfile\",\n  \"colorRendering\",\n  \"cursor\",\n  \"direction\",\n  \"display\",\n  \"dominantBaseline\",\n  \"enableBackground\",\n  \"fill\",\n  \"fillOpacity\",\n  \"fillRule\",\n  \"filter\",\n  \"floodColor\",\n  \"floodOpacity\",\n  \"fontFamily\",\n  \"fontSize\",\n  \"fontSizeAdjust\",\n  \"fontStretch\",\n  \"fontStyle\",\n  \"fontVariant\",\n  \"fontWeight\",\n  \"glyphOrientationHorizontal\",\n  \"glyphOrientationVertical\",\n  \"imageRendering\",\n  \"kerning\",\n  \"letterSpacing\",\n  \"lightingColor\",\n  \"markerEnd\",\n  \"markerMid\",\n  \"markerStart\",\n  \"mask\",\n  \"opacity\",\n  \"overflow\",\n  \"pointerEvents\",\n  \"shapeRendering\",\n  \"stopColor\",\n  \"stopOpacity\",\n  \"stroke\",\n  \"strokeDasharray\",\n  \"strokeDashoffset\",\n  \"strokeLinecap\",\n  \"strokeLinejoin\",\n  \"strokeMiterlimit\",\n  \"strokeOpacity\",\n  \"strokeWidth\",\n  \"textAnchor\",\n  \"transform\",\n  \"textDecoration\",\n  \"textRendering\",\n  \"unicodeBidi\",\n  \"vectorEffect\",\n  \"visibility\",\n  \"wordSpacing\",\n  \"writingMode\",\n];\n"
  },
  {
    "path": "packages/unis-core/src/utils.ts",
    "content": "import type { CSArray, CSObject } from \"../types/jsx\";\nimport { displayAttrs } from \"./svg\";\n\nexport const keys = Object.keys;\n\nexport const type = (a: any) =>\n  Object.prototype.toString.bind(a)().slice(8, -1);\n\nexport const isFun = (a: any): a is Function => typeof a === \"function\";\nexport const isStr = (a: any): a is string => typeof a === \"string\";\nexport const isNum = (a: any): a is number => typeof a === \"number\";\nexport const isBool = (a: any): a is boolean => typeof a === \"boolean\";\nexport const isSymbol = (a: any): a is boolean => typeof a === \"symbol\";\n\nexport const isArray = Array.isArray;\nexport const isObject = (a: any): a is object => type(a) === \"Object\";\n\nexport const isNullish = (a: any): a is null | undefined => a == null;\n\nexport const isEvent = (a: string) => a.startsWith(\"on\");\nexport const getEventName = (event: string) => {\n  const [, eventName, capture] = event.match(/^on(.*)(Capture)?$/)!;\n  return [eventName.toLowerCase(), !!capture] as const;\n};\n\nexport const camel2kebab = (text: string) =>\n  text.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n\nexport const toArray = <T extends any>(a: T) => (Array.isArray(a) ? a : [a]);\n\nexport const arraysEqual = (a: any, b: any) => {\n  if (a == null || b == null) return false;\n  if (a.length !== b.length) return false;\n  for (var i = 0; i < a.length; ++i) {\n    if (!Object.is(a[i], b[i])) return false;\n  }\n  return true;\n};\n\nexport const styleStr = (style: Partial<CSSStyleDeclaration>) =>\n  keys(style)\n    .map(\n      (key) => `${camel2kebab(key)}: ${style[key as keyof CSSStyleDeclaration]}`\n    )\n    .join(\"; \") + \";\";\n\nexport const svgKey = (key: string) => {\n  for (const str of [\"xmlns\", \"xml\", \"xlink\"]) {\n    if (key.startsWith(str)) return key.toLowerCase().replace(str, `${str}:`);\n  }\n  return displayAttrs.includes(key) ? camel2kebab(key) : key;\n};\n\nexport const classes = (cs: CSArray | CSObject): string => {\n  const objectClasses = (objcs: Record<string, any>) =>\n    keys(objcs)\n      .reduce((pre, cur) => pre + \" \" + (objcs[cur] ? cur : \"\"), \"\")\n      .trim();\n\n  const arrayClasses = (arrcs: CSArray) =>\n    arrcs\n      .reduce(\n        (pre: string, cur) =>\n          pre +\n          \" \" +\n          `${\n            isNum(cur) || isStr(cur)\n              ? cur\n              : isObject(cur)\n              ? objectClasses(cur)\n              : isArray(cur)\n              ? classes(cur)\n              : \"\"\n          }`,\n        \"\"\n      )\n      .trim();\n\n  return isArray(cs) ? arrayClasses(cs) : objectClasses(cs);\n};\n\nlet overflow = \"\";\nlet count = 0;\n\nexport const generateId = () => {\n  if (count === Number.MAX_SAFE_INTEGER) {\n    overflow += count.toString(32);\n    count = 0;\n  }\n  return `${overflow}${(count++).toString(32)}`;\n};\n"
  },
  {
    "path": "packages/unis-core/test/utils.test.ts",
    "content": "/**\n * @vitest-environment jsdom\n */\nimport { expect, it } from \"vitest\";\nimport { classes, svgKey, styleStr } from \"../src/utils\";\n\nit(\"classes\", () => {\n  expect(classes([\"a\", \"b\", 1, [\"c\", { d: true }]])).toBe(\"a b 1 c d\");\n  expect(classes({ a: true, b: undefined, c: null })).toBe(\"a\");\n  expect(classes({ a: false, b: true, c: null })).toBe(\"b\");\n});\n\nit(\"realSVGAttr\", () => {\n  expect(svgKey(\"glyphOrientationVertical\")).toBe(\"glyph-orientation-vertical\");\n});\n\nit(\"style2String\", () => {\n  expect(styleStr({ background: \"yellow\", fontSize: \"14px\" })).toBe(\n    \"background: yellow; font-size: 14px;\"\n  );\n});\n"
  },
  {
    "path": "packages/unis-core/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"include\": [\"src\"],\n  \"exclude\": [\"**/*.test.*\"]\n}\n"
  },
  {
    "path": "packages/unis-core/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"build\"\n  },\n  \"include\": [\"src\", \"test\", \"jsx-runtime\", \"types/jsx.d.ts\"]\n}\n"
  },
  {
    "path": "packages/unis-core/types/jsx.d.ts",
    "content": "// Note: this file is auto concatenated to the end of the bundled d.ts during\n// build.\n\n// This code is based on react definition in DefinitelyTyped published under the MIT license.\n//      Repository: https://github.com/DefinitelyTyped/DefinitelyTyped\n//      Path in the repository: types/react/index.d.ts\n//\n// Copyrights of original definition are:\n//      AssureSign <http://www.assuresign.com>\n//      Microsoft <https://microsoft.com>\n//                 John Reilly <https://github.com/johnnyreilly>\n//      Benoit Benezech <https://github.com/bbenezech>\n//      Patricio Zavolinsky <https://github.com/pzavolinsky>\n//      Digiguru <https://github.com/digiguru>\n//      Eric Anderson <https://github.com/ericanderson>\n//      Dovydas Navickas <https://github.com/DovydasNavickas>\n//                 Josh Rutherford <https://github.com/theruther4d>\n//                 Guilherme Hübner <https://github.com/guilhermehubner>\n//                 Ferdy Budhidharma <https://github.com/ferdaber>\n//                 Johann Rakotoharisoa <https://github.com/jrakotoharisoa>\n//                 Olivier Pascal <https://github.com/pascaloliv>\n//                 Martin Hochel <https://github.com/hotell>\n//                 Frank Li <https://github.com/franklixuefei>\n//                 Jessica Franco <https://github.com/Jessidhia>\n//                 Saransh Kataria <https://github.com/saranshkataria>\n//                 Kanitkorn Sujautra <https://github.com/lukyth>\n//                 Sebastian Silbermann <https://github.com/eps1lon>\n\n/**\n *\nThe MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\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\nall copies 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\nTHE SOFTWARE.\n\n---\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\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\n * \n */\n\nimport * as CSS from \"csstype\";\n\nexport interface FiberNode {\n  tag?: string | Function;\n  type?: Symbol;\n  props?: any;\n}\n\nexport interface CSSProperties\n  extends CSS.Properties<string | number>,\n    CSS.PropertiesHyphen<string | number> {\n  /**\n   * The index signature was removed to enable closed typing for style\n   * using CSSType. You're able to use type assertion or module augmentation\n   * to add properties or an index signature of your own.\n   *\n   * For examples and more information, visit:\n   * https://github.com/frenic/csstype#what-should-i-do-when-i-get-type-errors\n   */\n}\n\ntype Booleanish = boolean | \"true\" | \"false\";\ntype Numberish = number | string;\n\n// All the WAI-ARIA 1.1 attributes from https://www.w3.org/TR/wai-aria-1.1/\ninterface AriaAttributes {\n  /** Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application. */\n  \"aria-activedescendant\"?: string;\n  /** Indicates whether assistive technologies will present all, or only parts of, the changed region based on the change notifications defined by the aria-relevant attribute. */\n  \"aria-atomic\"?: Booleanish;\n  /**\n   * Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\n   * presented if they are made.\n   */\n  \"aria-autocomplete\"?: \"none\" | \"inline\" | \"list\" | \"both\";\n  /** Indicates an element is being modified and that assistive technologies MAY want to wait until the modifications are complete before exposing them to the user. */\n  \"aria-busy\"?: Booleanish;\n  /**\n   * Indicates the current \"checked\" state of checkboxes, radio buttons, and other widgets.\n   * @see aria-pressed @see aria-selected.\n   */\n  \"aria-checked\"?: Booleanish | \"mixed\";\n  /**\n   * Defines the total number of columns in a table, grid, or treegrid.\n   * @see aria-colindex.\n   */\n  \"aria-colcount\"?: Numberish;\n  /**\n   * Defines an element's column index or position with respect to the total number of columns within a table, grid, or treegrid.\n   * @see aria-colcount @see aria-colspan.\n   */\n  \"aria-colindex\"?: Numberish;\n  /**\n   * Defines the number of columns spanned by a cell or gridcell within a table, grid, or treegrid.\n   * @see aria-colindex @see aria-rowspan.\n   */\n  \"aria-colspan\"?: Numberish;\n  /**\n   * Identifies the element (or elements) whose contents or presence are controlled by the current element.\n   * @see aria-owns.\n   */\n  \"aria-controls\"?: string;\n  /** Indicates the element that represents the current item within a container or set of related elements. */\n  \"aria-current\"?: Booleanish | \"page\" | \"step\" | \"location\" | \"date\" | \"time\";\n  /**\n   * Identifies the element (or elements) that describes the object.\n   * @see aria-labelledby\n   */\n  \"aria-describedby\"?: string;\n  /**\n   * Identifies the element that provides a detailed, extended description for the object.\n   * @see aria-describedby.\n   */\n  \"aria-details\"?: string;\n  /**\n   * Indicates that the element is perceivable but disabled, so it is not editable or otherwise operable.\n   * @see aria-hidden @see aria-readonly.\n   */\n  \"aria-disabled\"?: Booleanish;\n  /**\n   * Indicates what functions can be performed when a dragged object is released on the drop target.\n   * @deprecated in ARIA 1.1\n   */\n  \"aria-dropeffect\"?: \"none\" | \"copy\" | \"execute\" | \"link\" | \"move\" | \"popup\";\n  /**\n   * Identifies the element that provides an error message for the object.\n   * @see aria-invalid @see aria-describedby.\n   */\n  \"aria-errormessage\"?: string;\n  /** Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed. */\n  \"aria-expanded\"?: Booleanish;\n  /**\n   * Identifies the next element (or elements) in an alternate reading order of content which, at the user's discretion,\n   * allows assistive technology to override the general default of reading in document source order.\n   */\n  \"aria-flowto\"?: string;\n  /**\n   * Indicates an element's \"grabbed\" state in a drag-and-drop operation.\n   * @deprecated in ARIA 1.1\n   */\n  \"aria-grabbed\"?: Booleanish;\n  /** Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element. */\n  \"aria-haspopup\"?:\n    | Booleanish\n    | \"menu\"\n    | \"listbox\"\n    | \"tree\"\n    | \"grid\"\n    | \"dialog\";\n  /**\n   * Indicates whether the element is exposed to an accessibility API.\n   * @see aria-disabled.\n   */\n  \"aria-hidden\"?: Booleanish;\n  /**\n   * Indicates the entered value does not conform to the format expected by the application.\n   * @see aria-errormessage.\n   */\n  \"aria-invalid\"?: Booleanish | \"grammar\" | \"spelling\";\n  /** Indicates keyboard shortcuts that an author has implemented to activate or give focus to an element. */\n  \"aria-keyshortcuts\"?: string;\n  /**\n   * Defines a string value that labels the current element.\n   * @see aria-labelledby.\n   */\n  \"aria-label\"?: string;\n  /**\n   * Identifies the element (or elements) that labels the current element.\n   * @see aria-describedby.\n   */\n  \"aria-labelledby\"?: string;\n  /** Defines the hierarchical level of an element within a structure. */\n  \"aria-level\"?: Numberish;\n  /** Indicates that an element will be updated, and describes the types of updates the user agents, assistive technologies, and user can expect from the live region. */\n  \"aria-live\"?: \"off\" | \"assertive\" | \"polite\";\n  /** Indicates whether an element is modal when displayed. */\n  \"aria-modal\"?: Booleanish;\n  /** Indicates whether a text box accepts multiple lines of input or only a single line. */\n  \"aria-multiline\"?: Booleanish;\n  /** Indicates that the user may select more than one item from the current selectable descendants. */\n  \"aria-multiselectable\"?: Booleanish;\n  /** Indicates whether the element's orientation is horizontal, vertical, or unknown/ambiguous. */\n  \"aria-orientation\"?: \"horizontal\" | \"vertical\";\n  /**\n   * Identifies an element (or elements) in order to define a visual, functional, or contextual parent/child relationship\n   * between DOM elements where the DOM hierarchy cannot be used to represent the relationship.\n   * @see aria-controls.\n   */\n  \"aria-owns\"?: string;\n  /**\n   * Defines a short hint (a word or short phrase) intended to aid the user with data entry when the control has no value.\n   * A hint could be a sample value or a brief description of the expected format.\n   */\n  \"aria-placeholder\"?: string;\n  /**\n   * Defines an element's number or position in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM.\n   * @see aria-setsize.\n   */\n  \"aria-posinset\"?: Numberish;\n  /**\n   * Indicates the current \"pressed\" state of toggle buttons.\n   * @see aria-checked @see aria-selected.\n   */\n  \"aria-pressed\"?: Booleanish | \"mixed\";\n  /**\n   * Indicates that the element is not editable, but is otherwise operable.\n   * @see aria-disabled.\n   */\n  \"aria-readonly\"?: Booleanish;\n  /**\n   * Indicates what notifications the user agent will trigger when the accessibility tree within a live region is modified.\n   * @see aria-atomic.\n   */\n  \"aria-relevant\"?:\n    | \"additions\"\n    | \"additions text\"\n    | \"all\"\n    | \"removals\"\n    | \"text\";\n  /** Indicates that user input is required on the element before a form may be submitted. */\n  \"aria-required\"?: Booleanish;\n  /** Defines a human-readable, author-localized description for the role of an element. */\n  \"aria-roledescription\"?: string;\n  /**\n   * Defines the total number of rows in a table, grid, or treegrid.\n   * @see aria-rowindex.\n   */\n  \"aria-rowcount\"?: Numberish;\n  /**\n   * Defines an element's row index or position with respect to the total number of rows within a table, grid, or treegrid.\n   * @see aria-rowcount @see aria-rowspan.\n   */\n  \"aria-rowindex\"?: Numberish;\n  /**\n   * Defines the number of rows spanned by a cell or gridcell within a table, grid, or treegrid.\n   * @see aria-rowindex @see aria-colspan.\n   */\n  \"aria-rowspan\"?: Numberish;\n  /**\n   * Indicates the current \"selected\" state of various widgets.\n   * @see aria-checked @see aria-pressed.\n   */\n  \"aria-selected\"?: Booleanish;\n  /**\n   * Defines the number of items in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM.\n   * @see aria-posinset.\n   */\n  \"aria-setsize\"?: Numberish;\n  /** Indicates if items in a table or grid are sorted in ascending or descending order. */\n  \"aria-sort\"?: \"none\" | \"ascending\" | \"descending\" | \"other\";\n  /** Defines the maximum allowed value for a range widget. */\n  \"aria-valuemax\"?: Numberish;\n  /** Defines the minimum allowed value for a range widget. */\n  \"aria-valuemin\"?: Numberish;\n  /**\n   * Defines the current value for a range widget.\n   * @see aria-valuetext.\n   */\n  \"aria-valuenow\"?: Numberish;\n  /** Defines the human readable text alternative of aria-valuenow for a range widget. */\n  \"aria-valuetext\"?: string;\n}\n\n// All the WAI-ARIA 1.1 role attribute values from https://www.w3.org/TR/wai-aria-1.1/#role_definitions\ntype AriaRole =\n  | \"alert\"\n  | \"alertdialog\"\n  | \"application\"\n  | \"article\"\n  | \"banner\"\n  | \"button\"\n  | \"cell\"\n  | \"checkbox\"\n  | \"columnheader\"\n  | \"combobox\"\n  | \"complementary\"\n  | \"contentinfo\"\n  | \"definition\"\n  | \"dialog\"\n  | \"directory\"\n  | \"document\"\n  | \"feed\"\n  | \"figure\"\n  | \"form\"\n  | \"grid\"\n  | \"gridcell\"\n  | \"group\"\n  | \"heading\"\n  | \"img\"\n  | \"link\"\n  | \"list\"\n  | \"listbox\"\n  | \"listitem\"\n  | \"log\"\n  | \"main\"\n  | \"marquee\"\n  | \"math\"\n  | \"menu\"\n  | \"menubar\"\n  | \"menuitem\"\n  | \"menuitemcheckbox\"\n  | \"menuitemradio\"\n  | \"navigation\"\n  | \"none\"\n  | \"note\"\n  | \"option\"\n  | \"presentation\"\n  | \"progressbar\"\n  | \"radio\"\n  | \"radiogroup\"\n  | \"region\"\n  | \"row\"\n  | \"rowgroup\"\n  | \"rowheader\"\n  | \"scrollbar\"\n  | \"search\"\n  | \"searchbox\"\n  | \"separator\"\n  | \"slider\"\n  | \"spinbutton\"\n  | \"status\"\n  | \"switch\"\n  | \"tab\"\n  | \"table\"\n  | \"tablist\"\n  | \"tabpanel\"\n  | \"term\"\n  | \"textbox\"\n  | \"timer\"\n  | \"toolbar\"\n  | \"tooltip\"\n  | \"tree\"\n  | \"treegrid\"\n  | \"treeitem\"\n  | (string & {});\n\n// Vue's style normalization supports nested arrays\nexport type StyleValue = string | CSSProperties | Array<StyleValue>;\n\nexport type CSValue = string | number | boolean | undefined | null;\nexport type CSObject = Record<string, CSValue>;\nexport type CSArray = (CSValue | CSObject | CSArray)[];\n\nexport interface HTMLAttributes extends AriaAttributes, EventHandlers<Events> {\n  // Standard HTML Attributes\n  accessKey?: string | undefined;\n  className?: string | CSObject | CSArray | undefined;\n  contentEditable?: Booleanish | \"inherit\" | undefined;\n  contextMenu?: string | undefined;\n  dir?: string | undefined;\n  draggable?: Booleanish | undefined;\n  hidden?: boolean | undefined;\n  id?: string | undefined;\n  lang?: string | undefined;\n  placeholder?: string | undefined;\n  slot?: string | undefined;\n  spellCheck?: Booleanish | undefined;\n  style?: CSSProperties | string | undefined;\n  tabIndex?: number | undefined;\n  title?: string | undefined;\n  translate?: \"yes\" | \"no\" | undefined;\n\n  // Unknown\n  radioGroup?: string | undefined; // <command>, <menuitem>\n\n  // WAI-ARIA\n  role?: AriaRole | undefined;\n\n  // RDFa Attributes\n  about?: string | undefined;\n  datatype?: string | undefined;\n  inlist?: any;\n  prefix?: string | undefined;\n  property?: string | undefined;\n  resource?: string | undefined;\n  typeof?: string | undefined;\n  vocab?: string | undefined;\n\n  // Non-standard Attributes\n  autoCapitalize?: string | undefined;\n  autoCorrect?: string | undefined;\n  autoSave?: string | undefined;\n  color?: string | undefined;\n  itemProp?: string | undefined;\n  itemScope?: boolean | undefined;\n  itemType?: string | undefined;\n  itemID?: string | undefined;\n  itemRef?: string | undefined;\n  results?: number | undefined;\n  security?: string | undefined;\n  unselectable?: \"on\" | \"off\" | undefined;\n\n  // Living Standard\n  /**\n   * Hints at the type of data that might be entered by the user while editing the element or its contents\n   * @see https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute\n   */\n  inputMode?:\n    | \"none\"\n    | \"text\"\n    | \"tel\"\n    | \"url\"\n    | \"email\"\n    | \"numeric\"\n    | \"decimal\"\n    | \"search\"\n    | undefined;\n  /**\n   * Specify that a standard HTML element should behave like a defined custom built-in element\n   * @see https://html.spec.whatwg.org/multipage/custom-elements.html#attr-is\n   */\n  is?: string | undefined;\n}\n\ntype HTMLAttributeReferrerPolicy =\n  | \"\"\n  | \"no-referrer\"\n  | \"no-referrer-when-downgrade\"\n  | \"origin\"\n  | \"origin-when-cross-origin\"\n  | \"same-origin\"\n  | \"strict-origin\"\n  | \"strict-origin-when-cross-origin\"\n  | \"unsafe-url\";\n\ntype HTMLAttributeAnchorTarget =\n  | \"_self\"\n  | \"_blank\"\n  | \"_parent\"\n  | \"_top\"\n  | (string & {});\n\nexport interface AnchorHTMLAttributes extends HTMLAttributes {\n  download?: any;\n  href?: string | undefined;\n  hrefLang?: string | undefined;\n  media?: string | undefined;\n  ping?: string | undefined;\n  rel?: string | undefined;\n  target?: HTMLAttributeAnchorTarget | undefined;\n  type?: string | undefined;\n  referrerPolicy?: HTMLAttributeReferrerPolicy | undefined;\n}\n\nexport interface AudioHTMLAttributes extends MediaHTMLAttributes {}\n\nexport interface AreaHTMLAttributes extends HTMLAttributes {\n  alt?: string | undefined;\n  coords?: string | undefined;\n  download?: any;\n  href?: string | undefined;\n  hrefLang?: string | undefined;\n  media?: string | undefined;\n  referrerPolicy?: HTMLAttributeReferrerPolicy | undefined;\n  rel?: string | undefined;\n  shape?: string | undefined;\n  target?: string | undefined;\n}\n\nexport interface BaseHTMLAttributes extends HTMLAttributes {\n  href?: string | undefined;\n  target?: string | undefined;\n}\n\nexport interface BlockquoteHTMLAttributes extends HTMLAttributes {\n  cite?: string | undefined;\n}\n\nexport interface ButtonHTMLAttributes extends HTMLAttributes {\n  autoFocus?: boolean | undefined;\n  disabled?: boolean | undefined;\n  form?: string | undefined;\n  formAction?: string | undefined;\n  formEncType?: string | undefined;\n  formMethod?: string | undefined;\n  formNoValidate?: boolean | undefined;\n  formTarget?: string | undefined;\n  name?: string | undefined;\n  type?: \"submit\" | \"reset\" | \"button\" | undefined;\n  value?: string | ReadonlyArray<string> | number | undefined;\n}\n\nexport interface CanvasHTMLAttributes extends HTMLAttributes {\n  height?: number | string | undefined;\n  width?: number | string | undefined;\n}\n\nexport interface ColHTMLAttributes extends HTMLAttributes {\n  span?: number | undefined;\n  width?: number | string | undefined;\n}\n\nexport interface ColgroupHTMLAttributes extends HTMLAttributes {\n  span?: number | undefined;\n}\n\nexport interface DataHTMLAttributes extends HTMLAttributes {\n  value?: string | ReadonlyArray<string> | number | undefined;\n}\n\nexport interface DetailsHTMLAttributes extends HTMLAttributes {\n  open?: boolean | undefined;\n}\n\nexport interface DelHTMLAttributes extends HTMLAttributes {\n  cite?: string | undefined;\n  dateTime?: string | undefined;\n}\n\nexport interface DialogHTMLAttributes extends HTMLAttributes {\n  open?: boolean | undefined;\n}\n\nexport interface EmbedHTMLAttributes extends HTMLAttributes {\n  height?: number | string | undefined;\n  src?: string | undefined;\n  type?: string | undefined;\n  width?: number | string | undefined;\n}\n\nexport interface FieldsetHTMLAttributes extends HTMLAttributes {\n  disabled?: boolean | undefined;\n  form?: string | undefined;\n  name?: string | undefined;\n}\n\nexport interface FormHTMLAttributes extends HTMLAttributes {\n  acceptCharset?: string | undefined;\n  action?: string | undefined;\n  autoComplete?: string | undefined;\n  encType?: string | undefined;\n  method?: string | undefined;\n  name?: string | undefined;\n  noValidate?: boolean | undefined;\n  target?: string | undefined;\n}\n\nexport interface HtmlHTMLAttributes extends HTMLAttributes {\n  manifest?: string | undefined;\n}\n\nexport interface IframeHTMLAttributes extends HTMLAttributes {\n  allow?: string | undefined;\n  allowFullScreen?: boolean | undefined;\n  allowTransparency?: boolean | undefined;\n  /** @deprecated */\n  frameBorder?: number | string | undefined;\n  height?: number | string | undefined;\n  loading?: \"eager\" | \"lazy\" | undefined;\n  /** @deprecated */\n  marginHeight?: number | undefined;\n  /** @deprecated */\n  marginWidth?: number | undefined;\n  name?: string | undefined;\n  referrerPolicy?: HTMLAttributeReferrerPolicy | undefined;\n  sandbox?: string | undefined;\n  /** @deprecated */\n  scrolling?: string | undefined;\n  seamless?: boolean | undefined;\n  src?: string | undefined;\n  srcDoc?: string | undefined;\n  width?: number | string | undefined;\n}\n\nexport interface ImgHTMLAttributes extends HTMLAttributes {\n  alt?: string | undefined;\n  crossOrigin?: \"anonymous\" | \"use-credentials\" | \"\" | undefined;\n  decoding?: \"async\" | \"auto\" | \"sync\" | undefined;\n  height?: number | string | undefined;\n  loading?: \"eager\" | \"lazy\" | undefined;\n  referrerPolicy?: HTMLAttributeReferrerPolicy | undefined;\n  sizes?: string | undefined;\n  src?: string | undefined;\n  srcSet?: string | undefined;\n  useMap?: string | undefined;\n  width?: number | string | undefined;\n}\n\nexport interface InsHTMLAttributes extends HTMLAttributes {\n  cite?: string | undefined;\n  dateTime?: string | undefined;\n}\n\ntype HTMLInputTypeAttribute =\n  | \"button\"\n  | \"checkbox\"\n  | \"color\"\n  | \"date\"\n  | \"datetime-local\"\n  | \"email\"\n  | \"file\"\n  | \"hidden\"\n  | \"image\"\n  | \"month\"\n  | \"number\"\n  | \"password\"\n  | \"radio\"\n  | \"range\"\n  | \"reset\"\n  | \"search\"\n  | \"submit\"\n  | \"tel\"\n  | \"text\"\n  | \"time\"\n  | \"url\"\n  | \"week\"\n  | (string & {});\n\nexport interface InputHTMLAttributes extends HTMLAttributes {\n  accept?: string | undefined;\n  alt?: string | undefined;\n  autoComplete?: string | undefined;\n  autoFocus?: boolean | undefined;\n  capture?: boolean | \"user\" | \"environment\" | undefined; // https://www.w3.org/TR/html-media-capture/#the-capture-attribute\n  checked?: boolean | undefined;\n  crossOrigin?: string | undefined;\n  disabled?: boolean | undefined;\n  enterKeyHint?:\n    | \"enter\"\n    | \"done\"\n    | \"go\"\n    | \"next\"\n    | \"previous\"\n    | \"search\"\n    | \"send\"\n    | undefined;\n  form?: string | undefined;\n  formAction?: string | undefined;\n  formEncType?: string | undefined;\n  formMethod?: string | undefined;\n  formNoValidate?: boolean | undefined;\n  formTarget?: string | undefined;\n  height?: number | string | undefined;\n  list?: string | undefined;\n  max?: number | string | undefined;\n  maxLength?: number | undefined;\n  min?: number | string | undefined;\n  minLength?: number | undefined;\n  multiple?: boolean | undefined;\n  name?: string | undefined;\n  pattern?: string | undefined;\n  placeholder?: string | undefined;\n  readOnly?: boolean | undefined;\n  required?: boolean | undefined;\n  size?: number | undefined;\n  src?: string | undefined;\n  step?: number | string | undefined;\n  type?: HTMLInputTypeAttribute | undefined;\n  value?: string | ReadonlyArray<string> | number | undefined;\n  width?: number | string | undefined;\n}\n\nexport interface KeygenHTMLAttributes extends HTMLAttributes {\n  autoFocus?: boolean | undefined;\n  challenge?: string | undefined;\n  disabled?: boolean | undefined;\n  form?: string | undefined;\n  keyType?: string | undefined;\n  keyParams?: string | undefined;\n  name?: string | undefined;\n}\n\nexport interface LabelHTMLAttributes extends HTMLAttributes {\n  form?: string | undefined;\n  htmlFor?: string | undefined;\n}\n\nexport interface LiHTMLAttributes extends HTMLAttributes {\n  value?: string | ReadonlyArray<string> | number | undefined;\n}\n\nexport interface LinkHTMLAttributes extends HTMLAttributes {\n  as?: string | undefined;\n  crossOrigin?: string | undefined;\n  href?: string | undefined;\n  hrefLang?: string | undefined;\n  integrity?: string | undefined;\n  media?: string | undefined;\n  imageSrcSet?: string | undefined;\n  referrerPolicy?: HTMLAttributeReferrerPolicy | undefined;\n  rel?: string | undefined;\n  sizes?: string | undefined;\n  type?: string | undefined;\n  charSet?: string | undefined;\n}\n\nexport interface MapHTMLAttributes extends HTMLAttributes {\n  name?: string | undefined;\n}\n\nexport interface MenuHTMLAttributes extends HTMLAttributes {\n  type?: string | undefined;\n}\n\nexport interface MediaHTMLAttributes extends HTMLAttributes {\n  autoPlay?: boolean | undefined;\n  controls?: boolean | undefined;\n  controlsList?: string | undefined;\n  crossOrigin?: string | undefined;\n  loop?: boolean | undefined;\n  mediaGroup?: string | undefined;\n  muted?: boolean | undefined;\n  playsInline?: boolean | undefined;\n  preload?: string | undefined;\n  src?: string | undefined;\n}\n\nexport interface MetaHTMLAttributes extends HTMLAttributes {\n  charSet?: string | undefined;\n  content?: string | undefined;\n  httpEquiv?: string | undefined;\n  name?: string | undefined;\n  media?: string | undefined;\n}\n\nexport interface MeterHTMLAttributes extends HTMLAttributes {\n  form?: string | undefined;\n  high?: number | undefined;\n  low?: number | undefined;\n  max?: number | string | undefined;\n  min?: number | string | undefined;\n  optimum?: number | undefined;\n  value?: string | ReadonlyArray<string> | number | undefined;\n}\n\nexport interface QuoteHTMLAttributes extends HTMLAttributes {\n  cite?: string | undefined;\n}\n\nexport interface ObjectHTMLAttributes extends HTMLAttributes {\n  classID?: string | undefined;\n  data?: string | undefined;\n  form?: string | undefined;\n  height?: number | string | undefined;\n  name?: string | undefined;\n  type?: string | undefined;\n  useMap?: string | undefined;\n  width?: number | string | undefined;\n  wmode?: string | undefined;\n}\n\nexport interface OlHTMLAttributes extends HTMLAttributes {\n  reversed?: boolean | undefined;\n  start?: number | undefined;\n  type?: \"1\" | \"a\" | \"A\" | \"i\" | \"I\" | undefined;\n}\n\nexport interface OptgroupHTMLAttributes extends HTMLAttributes {\n  disabled?: boolean | undefined;\n  label?: string | undefined;\n}\n\nexport interface OptionHTMLAttributes extends HTMLAttributes {\n  disabled?: boolean | undefined;\n  label?: string | undefined;\n  selected?: boolean | undefined;\n  value?: string | ReadonlyArray<string> | number | undefined;\n}\n\nexport interface OutputHTMLAttributes extends HTMLAttributes {\n  form?: string | undefined;\n  htmlFor?: string | undefined;\n  name?: string | undefined;\n}\n\nexport interface ParamHTMLAttributes extends HTMLAttributes {\n  name?: string | undefined;\n  value?: string | ReadonlyArray<string> | number | undefined;\n}\n\nexport interface ProgressHTMLAttributes extends HTMLAttributes {\n  max?: number | string | undefined;\n  value?: string | ReadonlyArray<string> | number | undefined;\n}\n\nexport interface SlotHTMLAttributes extends HTMLAttributes {\n  name?: string | undefined;\n}\n\nexport interface ScriptHTMLAttributes extends HTMLAttributes {\n  async?: boolean | undefined;\n  /** @deprecated */\n  charSet?: string | undefined;\n  crossOrigin?: string | undefined;\n  defer?: boolean | undefined;\n  integrity?: string | undefined;\n  noModule?: boolean | undefined;\n  nonce?: string | undefined;\n  referrerPolicy?: HTMLAttributeReferrerPolicy | undefined;\n  src?: string | undefined;\n  type?: string | undefined;\n}\n\nexport interface SelectHTMLAttributes extends HTMLAttributes {\n  autoComplete?: string | undefined;\n  autoFocus?: boolean | undefined;\n  disabled?: boolean | undefined;\n  form?: string | undefined;\n  multiple?: boolean | undefined;\n  name?: string | undefined;\n  required?: boolean | undefined;\n  size?: number | undefined;\n  value?: string | ReadonlyArray<string> | number | undefined;\n}\n\nexport interface SourceHTMLAttributes extends HTMLAttributes {\n  height?: number | string | undefined;\n  media?: string | undefined;\n  sizes?: string | undefined;\n  src?: string | undefined;\n  srcSet?: string | undefined;\n  type?: string | undefined;\n  width?: number | string | undefined;\n}\n\nexport interface StyleHTMLAttributes extends HTMLAttributes {\n  media?: string | undefined;\n  nonce?: string | undefined;\n  scoped?: boolean | undefined;\n  type?: string | undefined;\n}\n\nexport interface TableHTMLAttributes extends HTMLAttributes {\n  cellPadding?: number | string | undefined;\n  cellSpacing?: number | string | undefined;\n  summary?: string | undefined;\n  width?: number | string | undefined;\n}\n\nexport interface TextareaHTMLAttributes extends HTMLAttributes {\n  autoComplete?: string | undefined;\n  autoFocus?: boolean | undefined;\n  cols?: number | undefined;\n  dirName?: string | undefined;\n  disabled?: boolean | undefined;\n  form?: string | undefined;\n  maxLength?: number | undefined;\n  minLength?: number | undefined;\n  name?: string | undefined;\n  placeholder?: string | undefined;\n  readOnly?: boolean | undefined;\n  required?: boolean | undefined;\n  rows?: number | undefined;\n  value?: string | ReadonlyArray<string> | number | undefined;\n  wrap?: string | undefined;\n}\n\nexport interface TdHTMLAttributes extends HTMLAttributes {\n  align?: \"left\" | \"center\" | \"right\" | \"justify\" | \"char\" | undefined;\n  colSpan?: number | undefined;\n  headers?: string | undefined;\n  rowSpan?: number | undefined;\n  scope?: string | undefined;\n  abbr?: string | undefined;\n  height?: number | string | undefined;\n  width?: number | string | undefined;\n  valign?: \"top\" | \"middle\" | \"bottom\" | \"baseline\" | undefined;\n}\n\nexport interface ThHTMLAttributes extends HTMLAttributes {\n  align?: \"left\" | \"center\" | \"right\" | \"justify\" | \"char\" | undefined;\n  colSpan?: number | undefined;\n  headers?: string | undefined;\n  rowSpan?: number | undefined;\n  scope?: string | undefined;\n  abbr?: string | undefined;\n}\n\nexport interface TimeHTMLAttributes extends HTMLAttributes {\n  dateTime?: string | undefined;\n}\n\nexport interface TrackHTMLAttributes extends HTMLAttributes {\n  default?: boolean | undefined;\n  kind?: string | undefined;\n  label?: string | undefined;\n  src?: string | undefined;\n  srcLang?: string | undefined;\n}\n\nexport interface VideoHTMLAttributes extends MediaHTMLAttributes {\n  height?: number | string | undefined;\n  playsInline?: boolean | undefined;\n  poster?: string | undefined;\n  width?: number | string | undefined;\n  disablePictureInPicture?: boolean | undefined;\n  disableRemotePlayback?: boolean | undefined;\n}\n\nexport interface WebViewHTMLAttributes extends HTMLAttributes {\n  allowFullScreen?: boolean | undefined;\n  allowpopups?: boolean | undefined;\n  autoFocus?: boolean | undefined;\n  autosize?: boolean | undefined;\n  blinkfeatures?: string | undefined;\n  disableblinkfeatures?: string | undefined;\n  disableguestresize?: boolean | undefined;\n  disablewebsecurity?: boolean | undefined;\n  guestinstance?: string | undefined;\n  httpreferrer?: string | undefined;\n  nodeintegration?: boolean | undefined;\n  partition?: string | undefined;\n  plugins?: boolean | undefined;\n  preload?: string | undefined;\n  src?: string | undefined;\n  useragent?: string | undefined;\n  webpreferences?: string | undefined;\n}\n\nexport interface SVGAttributes extends AriaAttributes, EventHandlers<Events> {\n  innerHTML?: string;\n\n  /**\n   * SVG Styling Attributes\n   * @see https://www.w3.org/TR/SVG/styling.html#ElementSpecificStyling\n   */\n  class?: any;\n  className?: string | CSObject | CSArray | undefined;\n  color?: string | undefined;\n  height?: number | string | undefined;\n  id?: string | undefined;\n  lang?: string | undefined;\n  max?: number | string | undefined;\n  media?: string | undefined;\n  method?: string | undefined;\n  min?: number | string | undefined;\n  name?: string | undefined;\n  style?: CSSProperties | string | undefined;\n  target?: string | undefined;\n  type?: string | undefined;\n  width?: number | string | undefined;\n\n  // Other HTML properties supported by SVG elements in browsers\n  role?: AriaRole | undefined;\n  tabIndex?: number | undefined;\n  crossOrigin?: \"anonymous\" | \"use-credentials\" | \"\" | undefined;\n\n  // SVG Specific attributes\n  accentHeight?: number | string | undefined;\n  accumulate?: \"none\" | \"sum\" | undefined;\n  additive?: \"replace\" | \"sum\" | undefined;\n  alignmentBaseline?:\n    | \"auto\"\n    | \"baseline\"\n    | \"before-edge\"\n    | \"text-before-edge\"\n    | \"middle\"\n    | \"central\"\n    | \"after-edge\"\n    | \"text-after-edge\"\n    | \"ideographic\"\n    | \"alphabetic\"\n    | \"hanging\"\n    | \"mathematical\"\n    | \"inherit\"\n    | undefined;\n  allowReorder?: \"no\" | \"yes\" | undefined;\n  alphabetic?: number | string | undefined;\n  amplitude?: number | string | undefined;\n  arabicForm?: \"initial\" | \"medial\" | \"terminal\" | \"isolated\" | undefined;\n  ascent?: number | string | undefined;\n  attributeName?: string | undefined;\n  attributeType?: string | undefined;\n  autoReverse?: Booleanish | undefined;\n  azimuth?: number | string | undefined;\n  baseFrequency?: number | string | undefined;\n  baselineShift?: number | string | undefined;\n  baseProfile?: number | string | undefined;\n  bbox?: number | string | undefined;\n  begin?: number | string | undefined;\n  bias?: number | string | undefined;\n  by?: number | string | undefined;\n  calcMode?: number | string | undefined;\n  capHeight?: number | string | undefined;\n  clip?: number | string | undefined;\n  clipPath?: string | undefined;\n  clipPathUnits?: number | string | undefined;\n  clipRule?: number | string | undefined;\n  colorInterpolation?: number | string | undefined;\n  colorInterpolationFilters?:\n    | \"auto\"\n    | \"sRGB\"\n    | \"linearRGB\"\n    | \"inherit\"\n    | undefined;\n  colorProfile?: number | string | undefined;\n  colorRendering?: number | string | undefined;\n  contentScriptType?: number | string | undefined;\n  contentStyleType?: number | string | undefined;\n  cursor?: number | string | undefined;\n  cx?: number | string | undefined;\n  cy?: number | string | undefined;\n  d?: string | undefined;\n  decelerate?: number | string | undefined;\n  descent?: number | string | undefined;\n  diffuseConstant?: number | string | undefined;\n  direction?: number | string | undefined;\n  display?: number | string | undefined;\n  divisor?: number | string | undefined;\n  dominantBaseline?: number | string | undefined;\n  dur?: number | string | undefined;\n  dx?: number | string | undefined;\n  dy?: number | string | undefined;\n  edgeMode?: number | string | undefined;\n  elevation?: number | string | undefined;\n  enableBackground?: number | string | undefined;\n  end?: number | string | undefined;\n  exponent?: number | string | undefined;\n  externalResourcesRequired?: Booleanish | undefined;\n  fill?: string | undefined;\n  fillOpacity?: number | string | undefined;\n  fillRule?: \"nonzero\" | \"evenodd\" | \"inherit\" | undefined;\n  filter?: string | undefined;\n  filterRes?: number | string | undefined;\n  filterUnits?: number | string | undefined;\n  floodColor?: number | string | undefined;\n  floodOpacity?: number | string | undefined;\n  focusable?: Booleanish | \"auto\" | undefined;\n  fontFamily?: string | undefined;\n  fontSize?: number | string | undefined;\n  fontSizeAdjust?: number | string | undefined;\n  fontStretch?: number | string | undefined;\n  fontStyle?: number | string | undefined;\n  fontVariant?: number | string | undefined;\n  fontWeight?: number | string | undefined;\n  format?: number | string | undefined;\n  fr?: number | string | undefined;\n  from?: number | string | undefined;\n  fx?: number | string | undefined;\n  fy?: number | string | undefined;\n  g1?: number | string | undefined;\n  g2?: number | string | undefined;\n  glyphName?: number | string | undefined;\n  glyphOrientationHorizontal?: number | string | undefined;\n  glyphOrientationVertical?: number | string | undefined;\n  glyphRef?: number | string | undefined;\n  gradientTransform?: string | undefined;\n  gradientUnits?: string | undefined;\n  hanging?: number | string | undefined;\n  horizAdvX?: number | string | undefined;\n  horizOriginX?: number | string | undefined;\n  href?: string | undefined;\n  ideographic?: number | string | undefined;\n  imageRendering?: number | string | undefined;\n  in2?: number | string | undefined;\n  in?: string | undefined;\n  intercept?: number | string | undefined;\n  k1?: number | string | undefined;\n  k2?: number | string | undefined;\n  k3?: number | string | undefined;\n  k4?: number | string | undefined;\n  k?: number | string | undefined;\n  kernelMatrix?: number | string | undefined;\n  kernelUnitLength?: number | string | undefined;\n  kerning?: number | string | undefined;\n  keyPoints?: number | string | undefined;\n  keySplines?: number | string | undefined;\n  keyTimes?: number | string | undefined;\n  lengthAdjust?: number | string | undefined;\n  letterSpacing?: number | string | undefined;\n  lightingColor?: number | string | undefined;\n  limitingConeAngle?: number | string | undefined;\n  local?: number | string | undefined;\n  markerEnd?: string | undefined;\n  markerHeight?: number | string | undefined;\n  markerMid?: string | undefined;\n  markerStart?: string | undefined;\n  markerUnits?: number | string | undefined;\n  markerWidth?: number | string | undefined;\n  mask?: string | undefined;\n  maskContentUnits?: number | string | undefined;\n  maskUnits?: number | string | undefined;\n  mathematical?: number | string | undefined;\n  mode?: number | string | undefined;\n  numOctaves?: number | string | undefined;\n  offset?: number | string | undefined;\n  opacity?: number | string | undefined;\n  operator?: number | string | undefined;\n  order?: number | string | undefined;\n  orient?: number | string | undefined;\n  orientation?: number | string | undefined;\n  origin?: number | string | undefined;\n  overflow?: number | string | undefined;\n  overlinePosition?: number | string | undefined;\n  overlineThickness?: number | string | undefined;\n  paintOrder?: number | string | undefined;\n  panose1?: number | string | undefined;\n  path?: string | undefined;\n  pathLength?: number | string | undefined;\n  patternContentUnits?: string | undefined;\n  patternTransform?: number | string | undefined;\n  patternUnits?: string | undefined;\n  pointerEvents?: number | string | undefined;\n  points?: string | undefined;\n  pointsAtX?: number | string | undefined;\n  pointsAtY?: number | string | undefined;\n  pointsAtZ?: number | string | undefined;\n  preserveAlpha?: Booleanish | undefined;\n  preserveAspectRatio?: string | undefined;\n  primitiveUnits?: number | string | undefined;\n  r?: number | string | undefined;\n  radius?: number | string | undefined;\n  refX?: number | string | undefined;\n  refY?: number | string | undefined;\n  renderingIntent?: number | string | undefined;\n  repeatCount?: number | string | undefined;\n  repeatDur?: number | string | undefined;\n  requiredExtensions?: number | string | undefined;\n  requiredFeatures?: number | string | undefined;\n  restart?: number | string | undefined;\n  result?: string | undefined;\n  rotate?: number | string | undefined;\n  rx?: number | string | undefined;\n  ry?: number | string | undefined;\n  scale?: number | string | undefined;\n  seed?: number | string | undefined;\n  shapeRendering?: number | string | undefined;\n  slope?: number | string | undefined;\n  spacing?: number | string | undefined;\n  specularConstant?: number | string | undefined;\n  specularExponent?: number | string | undefined;\n  speed?: number | string | undefined;\n  spreadMethod?: string | undefined;\n  startOffset?: number | string | undefined;\n  stdDeviation?: number | string | undefined;\n  stemh?: number | string | undefined;\n  stemv?: number | string | undefined;\n  stitchTiles?: number | string | undefined;\n  stopColor?: string | undefined;\n  stopOpacity?: number | string | undefined;\n  strikethroughPosition?: number | string | undefined;\n  strikethroughThickness?: number | string | undefined;\n  string?: number | string | undefined;\n  stroke?: string | undefined;\n  strokeDasharray?: string | number | undefined;\n  strokeDashoffset?: string | number | undefined;\n  strokeLinecap?: \"butt\" | \"round\" | \"square\" | \"inherit\" | undefined;\n  strokeLinejoin?: \"miter\" | \"round\" | \"bevel\" | \"inherit\" | undefined;\n  strokeMiterlimit?: number | string | undefined;\n  strokeOpacity?: number | string | undefined;\n  strokeWidth?: number | string | undefined;\n  surfaceScale?: number | string | undefined;\n  systemLanguage?: number | string | undefined;\n  tableValues?: number | string | undefined;\n  targetX?: number | string | undefined;\n  targetY?: number | string | undefined;\n  textAnchor?: string | undefined;\n  textDecoration?: number | string | undefined;\n  textLength?: number | string | undefined;\n  textRendering?: number | string | undefined;\n  to?: number | string | undefined;\n  transform?: string | undefined;\n  u1?: number | string | undefined;\n  u2?: number | string | undefined;\n  underlinePosition?: number | string | undefined;\n  underlineThickness?: number | string | undefined;\n  unicode?: number | string | undefined;\n  unicodeBidi?: number | string | undefined;\n  unicodeRange?: number | string | undefined;\n  unitsPerEm?: number | string | undefined;\n  vAlphabetic?: number | string | undefined;\n  values?: string | undefined;\n  vectorEffect?: number | string | undefined;\n  version?: string | undefined;\n  vertAdvY?: number | string | undefined;\n  vertOriginX?: number | string | undefined;\n  vertOriginY?: number | string | undefined;\n  vHanging?: number | string | undefined;\n  vIdeographic?: number | string | undefined;\n  viewBox?: string | undefined;\n  viewTarget?: number | string | undefined;\n  visibility?: number | string | undefined;\n  vMathematical?: number | string | undefined;\n  widths?: number | string | undefined;\n  wordSpacing?: number | string | undefined;\n  writingMode?: number | string | undefined;\n  x1?: number | string | undefined;\n  x2?: number | string | undefined;\n  x?: number | string | undefined;\n  xChannelSelector?: string | undefined;\n  xHeight?: number | string | undefined;\n  xlinkActuate?: string | undefined;\n  xlinkArcrole?: string | undefined;\n  xlinkHref?: string | undefined;\n  xlinkRole?: string | undefined;\n  xlinkShow?: string | undefined;\n  xlinkTitle?: string | undefined;\n  xlinkType?: string | undefined;\n  xmlBase?: string | undefined;\n  xmlLang?: string | undefined;\n  xmlns?: string | undefined;\n  xmlnsXlink?: string | undefined;\n  xmlSpace?: string | undefined;\n  y1?: number | string | undefined;\n  y2?: number | string | undefined;\n  y?: number | string | undefined;\n  yChannelSelector?: string | undefined;\n  z?: number | string | undefined;\n  zoomAndPan?: string | undefined;\n}\n\nexport interface IntrinsicElementAttributes {\n  a: AnchorHTMLAttributes;\n  abbr: HTMLAttributes;\n  address: HTMLAttributes;\n  area: AreaHTMLAttributes;\n  article: HTMLAttributes;\n  aside: HTMLAttributes;\n  audio: AudioHTMLAttributes;\n  b: HTMLAttributes;\n  base: BaseHTMLAttributes;\n  bdi: HTMLAttributes;\n  bdo: HTMLAttributes;\n  blockquote: BlockquoteHTMLAttributes;\n  body: HTMLAttributes;\n  br: HTMLAttributes;\n  button: ButtonHTMLAttributes;\n  canvas: CanvasHTMLAttributes;\n  caption: HTMLAttributes;\n  cite: HTMLAttributes;\n  code: HTMLAttributes;\n  col: ColHTMLAttributes;\n  colgroup: ColgroupHTMLAttributes;\n  data: DataHTMLAttributes;\n  datalist: HTMLAttributes;\n  dd: HTMLAttributes;\n  del: DelHTMLAttributes;\n  details: DetailsHTMLAttributes;\n  dfn: HTMLAttributes;\n  dialog: DialogHTMLAttributes;\n  div: HTMLAttributes;\n  dl: HTMLAttributes;\n  dt: HTMLAttributes;\n  em: HTMLAttributes;\n  embed: EmbedHTMLAttributes;\n  fieldset: FieldsetHTMLAttributes;\n  figcaption: HTMLAttributes;\n  figure: HTMLAttributes;\n  footer: HTMLAttributes;\n  form: FormHTMLAttributes;\n  h1: HTMLAttributes;\n  h2: HTMLAttributes;\n  h3: HTMLAttributes;\n  h4: HTMLAttributes;\n  h5: HTMLAttributes;\n  h6: HTMLAttributes;\n  head: HTMLAttributes;\n  header: HTMLAttributes;\n  hgroup: HTMLAttributes;\n  hr: HTMLAttributes;\n  html: HtmlHTMLAttributes;\n  i: HTMLAttributes;\n  iframe: IframeHTMLAttributes;\n  img: ImgHTMLAttributes;\n  input: InputHTMLAttributes;\n  ins: InsHTMLAttributes;\n  kbd: HTMLAttributes;\n  keygen: KeygenHTMLAttributes;\n  label: LabelHTMLAttributes;\n  legend: HTMLAttributes;\n  li: LiHTMLAttributes;\n  link: LinkHTMLAttributes;\n  main: HTMLAttributes;\n  map: MapHTMLAttributes;\n  mark: HTMLAttributes;\n  menu: MenuHTMLAttributes;\n  meta: MetaHTMLAttributes;\n  meter: MeterHTMLAttributes;\n  nav: HTMLAttributes;\n  noindex: HTMLAttributes;\n  noscript: HTMLAttributes;\n  object: ObjectHTMLAttributes;\n  ol: OlHTMLAttributes;\n  optgroup: OptgroupHTMLAttributes;\n  option: OptionHTMLAttributes;\n  output: OutputHTMLAttributes;\n  p: HTMLAttributes;\n  param: ParamHTMLAttributes;\n  picture: HTMLAttributes;\n  pre: HTMLAttributes;\n  progress: ProgressHTMLAttributes;\n  q: QuoteHTMLAttributes;\n  rp: HTMLAttributes;\n  rt: HTMLAttributes;\n  ruby: HTMLAttributes;\n  s: HTMLAttributes;\n  samp: HTMLAttributes;\n  script: ScriptHTMLAttributes;\n  section: HTMLAttributes;\n  select: SelectHTMLAttributes;\n  slot: SlotHTMLAttributes;\n  small: HTMLAttributes;\n  source: SourceHTMLAttributes;\n  span: HTMLAttributes;\n  strong: HTMLAttributes;\n  style: StyleHTMLAttributes;\n  sub: HTMLAttributes;\n  summary: HTMLAttributes;\n  sup: HTMLAttributes;\n  table: TableHTMLAttributes;\n  template: HTMLAttributes;\n  tbody: HTMLAttributes;\n  td: TdHTMLAttributes;\n  textarea: TextareaHTMLAttributes;\n  tfoot: HTMLAttributes;\n  th: ThHTMLAttributes;\n  thead: HTMLAttributes;\n  time: TimeHTMLAttributes;\n  title: HTMLAttributes;\n  tr: HTMLAttributes;\n  track: TrackHTMLAttributes;\n  u: HTMLAttributes;\n  ul: HTMLAttributes;\n  var: HTMLAttributes;\n  video: VideoHTMLAttributes;\n  wbr: HTMLAttributes;\n  webview: WebViewHTMLAttributes;\n\n  // SVG\n  svg: SVGAttributes;\n\n  animate: SVGAttributes;\n  animateMotion: SVGAttributes;\n  animateTransform: SVGAttributes;\n  circle: SVGAttributes;\n  clipPath: SVGAttributes;\n  defs: SVGAttributes;\n  desc: SVGAttributes;\n  ellipse: SVGAttributes;\n  feBlend: SVGAttributes;\n  feColorMatrix: SVGAttributes;\n  feComponentTransfer: SVGAttributes;\n  feComposite: SVGAttributes;\n  feConvolveMatrix: SVGAttributes;\n  feDiffuseLighting: SVGAttributes;\n  feDisplacementMap: SVGAttributes;\n  feDistantLight: SVGAttributes;\n  feDropShadow: SVGAttributes;\n  feFlood: SVGAttributes;\n  feFuncA: SVGAttributes;\n  feFuncB: SVGAttributes;\n  feFuncG: SVGAttributes;\n  feFuncR: SVGAttributes;\n  feGaussianBlur: SVGAttributes;\n  feImage: SVGAttributes;\n  feMerge: SVGAttributes;\n  feMergeNode: SVGAttributes;\n  feMorphology: SVGAttributes;\n  feOffset: SVGAttributes;\n  fePointLight: SVGAttributes;\n  feSpecularLighting: SVGAttributes;\n  feSpotLight: SVGAttributes;\n  feTile: SVGAttributes;\n  feTurbulence: SVGAttributes;\n  filter: SVGAttributes;\n  foreignObject: SVGAttributes;\n  g: SVGAttributes;\n  image: SVGAttributes;\n  line: SVGAttributes;\n  linearGradient: SVGAttributes;\n  marker: SVGAttributes;\n  mask: SVGAttributes;\n  metadata: SVGAttributes;\n  mpath: SVGAttributes;\n  path: SVGAttributes;\n  pattern: SVGAttributes;\n  polygon: SVGAttributes;\n  polyline: SVGAttributes;\n  radialGradient: SVGAttributes;\n  rect: SVGAttributes;\n  stop: SVGAttributes;\n  switch: SVGAttributes;\n  symbol: SVGAttributes;\n  text: SVGAttributes;\n  textPath: SVGAttributes;\n  tspan: SVGAttributes;\n  use: SVGAttributes;\n  view: SVGAttributes;\n}\n\nexport interface Events {\n  // Clipboard Events\n  onCopy: ClipboardEvent;\n  onCut: ClipboardEvent;\n  onPaste: ClipboardEvent;\n\n  // Composition Events\n  onCompositionEnd: CompositionEvent;\n  onCompositionStart: CompositionEvent;\n  onCompositionUpdate: CompositionEvent;\n\n  // Focus Events\n  onFocus: FocusEvent;\n  onBlur: FocusEvent;\n\n  // Form Events\n  onChange: Event;\n  onBeforeInput: Event;\n  onInput: Event;\n  onReset: Event;\n  onSubmit: Event;\n  onInvalid: Event;\n\n  // Image Events\n  onLoad: Event;\n  onError: Event;\n\n  // Keyboard Events\n  onKeyDown: KeyboardEvent;\n  onKeyPress: KeyboardEvent;\n  onKeyUp: KeyboardEvent;\n\n  // Media Events\n  onAbort: Event;\n  onCanPlay: Event;\n  onCanPlayThrough: Event;\n  onDurationChange: Event;\n  onEmptied: Event;\n  onEncrypted: Event;\n  onEnded: Event;\n  onLoadedData: Event;\n  onLoadedMetadata: Event;\n  onLoadStart: Event;\n  onPause: Event;\n  onPlay: Event;\n  onPlaying: Event;\n  onProgress: Event;\n  onRateChange: Event;\n  onSeeked: Event;\n  onSeeking: Event;\n  onStalled: Event;\n  onSuspend: Event;\n  onTimeUpdate: Event;\n  onVolumeChange: Event;\n  onWaiting: Event;\n\n  // DragEvent\n  onDrag: DragEvent;\n  onDragEnd: DragEvent;\n  onDragEnter: DragEvent;\n  onDragExit: DragEvent;\n  onDragLeave: DragEvent;\n  onDragOver: DragEvent;\n  onDragStart: DragEvent;\n  onDrop: DragEvent;\n\n  // MouseEvents\n  onAuxClick: MouseEvent;\n  onClick: MouseEvent;\n  onContextMenu: MouseEvent;\n  onDoubleClick: MouseEvent;\n  onMouseDown: MouseEvent;\n  onMouseEnter: MouseEvent;\n  onMouseLeave: MouseEvent;\n  onMouseMove: MouseEvent;\n  onMouseOut: MouseEvent;\n  onMouseOver: MouseEvent;\n  onMouseUp: MouseEvent;\n\n  // Selection Events\n  onSelect: Event;\n\n  // Touch Events\n  onTouchCancel: TouchEvent;\n  onTouchEnd: TouchEvent;\n  onTouchMove: TouchEvent;\n  onTouchStart: TouchEvent;\n\n  // Pointer Events\n  onPointerDown: PointerEvent;\n  onPointerMove: PointerEvent;\n  onPointerUp: PointerEvent;\n  onPointerCancel: PointerEvent;\n  onPointerEnter: PointerEvent;\n  onPointerLeave: PointerEvent;\n  onPointerOver: PointerEvent;\n  onPointerOut: PointerEvent;\n\n  // UI Events\n  onScroll: UIEvent;\n\n  // Wheel Events\n  onWheel: WheelEvent;\n\n  // Animation Events\n  onAnimationStart: AnimationEvent;\n  onAnimationEnd: AnimationEvent;\n  onAnimationIteration: AnimationEvent;\n\n  // Transition Events\n  onTransitionEnd: TransitionEvent;\n  onTransitionStart: TransitionEvent;\n}\n\ntype EventHandlers<E> = {\n  [K in keyof E]?: E[K] extends Function ? E[K] : (payload: E[K]) => void;\n};\n\ntype ReservedProps = {\n  children?: unknown;\n  key?: string | number | symbol;\n  ref?: { current: any } | ((ref: Element | null) => void);\n};\n\nexport type ElementAttrs<T> = T & ReservedProps;\n\ntype NativeElements = {\n  [K in keyof IntrinsicElementAttributes]: ElementAttrs<\n    IntrinsicElementAttributes[K]\n  >;\n};\n\ndeclare global {\n  namespace JSX {\n    type ElementTypes =\n      | string\n      | number\n      | null\n      | boolean\n      | void\n      | undefined\n      | FiberNode;\n\n    type Element =\n      | Element[]\n      | ElementTypes\n      | ElementTypes[]\n      | (() => Element)\n      | (() => Element[]);\n    interface ElementClass {\n      props: {};\n    }\n    interface ElementAttributesProperty {\n      props: {};\n    }\n    interface ElementChildrenAttribute {\n      children: {};\n    }\n    interface IntrinsicElements extends NativeElements {\n      // allow arbitrary elements\n      // @ts-ignore suppress ts:2374 = Duplicate string index signature.\n      [name: string]: any;\n    }\n    interface IntrinsicAttributes extends ReservedProps {}\n  }\n}\n\n// suppress ts:2669\nexport {};\n"
  },
  {
    "path": "packages/unis-core/vitest.config.ts",
    "content": "import { defineConfig } from \"vitest/config\";\n\nexport default defineConfig({\n  test: {\n    include: [\"**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}\"],\n    coverage: {\n      reporter: [\"text\", \"json\", \"html\"],\n    },\n  },\n});\n"
  },
  {
    "path": "packages/unis-dom/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Microbundle cache\n.rpt2_cache/\n.rts2_cache_cjs/\n.rts2_cache_es/\n.rts2_cache_umd/\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n.env.test\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n.parcel-cache\n\n# Next.js build output\n.next\n\n# Nuxt.js build / generate output\n.nuxt\ndist\nbuild\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and *not* Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# TernJS port file\n.tern-port\n"
  },
  {
    "path": "packages/unis-dom/index.d.ts",
    "content": "import \"@unis/core\";\nexport * from \"./dist/browser\";\n"
  },
  {
    "path": "packages/unis-dom/package.json",
    "content": "{\n  \"name\": \"@unis/dom\",\n  \"version\": \"1.2.5\",\n  \"description\": \"Unis is a simpler and easier to use front-end framework than React\",\n  \"main\": \"dist/browser.js\",\n  \"module\": \"dist/browser.mjs\",\n  \"types\": \"index.d.ts\",\n  \"typings\": \"index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"require\": \"./dist/browser.js\",\n      \"import\": \"./dist/browser.mjs\"\n    },\n    \"./server\": {\n      \"require\": \"./dist/server.js\",\n      \"import\": \"./dist/server.mjs\"\n    }\n  },\n  \"scripts\": {\n    \"build\": \"rimraf build && rimraf dist && tsc -p tsconfig.build.json && rollup --config\",\n    \"build:dev\": \"cross-env NODE_ENV=development pnpm build\",\n    \"build:server\": \"rollup --config rollup.config.server.mjs\",\n    \"test\": \"vitest run --coverage\",\n    \"test:watch\": \"vitest -w\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/anuoua/unis.git\"\n  },\n  \"keywords\": [\n    \"frontend\",\n    \"web\",\n    \"framwork\"\n  ],\n  \"files\": [\n    \"dist\",\n    \"server.d.ts\",\n    \"index.d.ts\"\n  ],\n  \"author\": \"anuoua\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/anuoua/unis/issues\"\n  },\n  \"homepage\": \"https://github.com/anuoua/unis#readme\",\n  \"peerDependencies\": {\n    \"@unis/core\": \"workspace:^\"\n  },\n  \"devDependencies\": {\n    \"@rollup/plugin-node-resolve\": \"^15.0.2\",\n    \"@types/jsdom\": \"^21.1.1\",\n    \"@unis/core\": \"workspace:^\",\n    \"@unis/vite-preset\": \"workspace:^\",\n    \"@vitest/coverage-c8\": \"^0.28.5\",\n    \"cross-env\": \"^7.0.3\",\n    \"esbuild\": \"^0.17.15\",\n    \"jsdom\": \"^21.1.1\",\n    \"rimraf\": \"^4.4.1\",\n    \"rollup\": \"^3.20.2\",\n    \"rollup-plugin-dts\": \"^5.3.0\",\n    \"rollup-plugin-esbuild\": \"^5.0.0\",\n    \"tslib\": \"^2.5.0\",\n    \"typescript\": \"^4.9.5\",\n    \"vite\": \"^4.2.1\",\n    \"vitest\": \"^0.29.8\"\n  }\n}\n"
  },
  {
    "path": "packages/unis-dom/rollup.config.mjs",
    "content": "import esbuild from \"rollup-plugin-esbuild\";\nimport dts from \"rollup-plugin-dts\";\nimport { defineConfig } from \"rollup\";\nimport { nodeResolve } from \"@rollup/plugin-node-resolve\";\n\nconst configGen = (format, plateform) =>\n  defineConfig({\n    input: `src/${plateform}/index.ts`,\n    external: [/^@unis/],\n    output: [\n      {\n        dir: \"dist\",\n        entryFileNames: `${plateform}.${format === \"esm\" ? \"mjs\" : \"js\"}`,\n        format,\n        sourcemap: true,\n      },\n    ],\n    plugins: [\n      nodeResolve(),\n      esbuild({\n        sourceMap: true,\n        target: \"esnext\",\n      }),\n    ],\n  });\n\nconst dtsRollup = (which) =>\n  defineConfig({\n    input: `build/${which}/index.d.ts`,\n    output: [{ file: `dist/${which}.d.ts`, format: \"es\" }],\n    plugins: [dts()],\n  });\n\nconst config = [\n  configGen(\"cjs\", \"browser\"),\n  configGen(\"esm\", \"browser\"),\n  configGen(\"cjs\", \"server\"),\n  configGen(\"esm\", \"server\"),\n  dtsRollup(\"browser\"),\n  dtsRollup(\"server\"),\n];\n\nexport default config;\n"
  },
  {
    "path": "packages/unis-dom/server.d.ts",
    "content": "export * from \"./dist/server\";\n"
  },
  {
    "path": "packages/unis-dom/src/browser/__test__/context.test.tsx",
    "content": "/**\n * @vitest-environment jsdom\n */\nimport { afterEach, beforeEach, expect, it } from \"vitest\";\nimport { useContext } from \"@unis/core\";\nimport { useEffect } from \"@unis/core\";\nimport { useProps } from \"@unis/core\";\nimport { useState } from \"@unis/core\";\nimport { createContext } from \"@unis/core\";\nimport { Fragment, memo } from \"@unis/core\";\nimport { rendered, testRender } from \"./util\";\n\nlet root: Element;\n\nbeforeEach(() => {\n  root = document.createElement(\"div\");\n  document.body.append(root);\n});\n\nafterEach(() => {\n  root.innerHTML = \"\";\n});\n\nit(\"context\", async () => {\n  const AppContext = createContext<string>(\"initial\");\n\n  const Cpp = memo(() => {\n    let theme = useContext(AppContext);\n\n    return () => <div>Cpp: {theme}</div>;\n  });\n\n  const Dpp = () => {\n    return () => (\n      <AppContext.Consumer>\n        {(theme) => <div>Dpp: {theme}</div>}\n      </AppContext.Consumer>\n    );\n  };\n\n  const Epp = () => {\n    return () => (\n      <AppContext.Consumer>\n        {(theme) => <div>Epp: {theme}</div>}\n      </AppContext.Consumer>\n    );\n  };\n\n  const Bpp = () => {\n    let theme = useContext(AppContext);\n\n    return () => (\n      <div>\n        Bpp: {theme}\n        <AppContext.Provider value=\"gray\">\n          <Cpp />\n        </AppContext.Provider>\n      </div>\n    );\n  };\n\n  const App = () => {\n    let [theme, setTheme] = useState(\"light\");\n\n    useEffect(\n      () => {\n        setTheme(\"dark\");\n      },\n      () => []\n    );\n\n    return () => (\n      <Fragment>\n        <AppContext.Provider value={theme}>\n          <div>App</div>\n          <Bpp />\n          <Dpp />\n        </AppContext.Provider>\n        <Epp />\n      </Fragment>\n    );\n  };\n\n  testRender(<App />, root);\n\n  expect(root.innerHTML).toBe(\n    \"<div>App</div><div>Bpp: light<div>Cpp: gray</div></div><div>Dpp: light</div><div>Epp: initial</div>\"\n  );\n\n  await rendered();\n\n  expect(root.innerHTML).toBe(\n    \"<div>App</div><div>Bpp: dark<div>Cpp: gray</div></div><div>Dpp: dark</div><div>Epp: initial</div>\"\n  );\n});\n\nit(\"context pass through\", async () => {\n  const AppContext = createContext({} as any);\n\n  const App = () => {\n    let [hello, setHello] = useState(\"hello\");\n\n    return () => (\n      <AppContext.Provider value={{ hello, setHello }}>\n        <div>\n          <Bpp />\n        </div>\n      </AppContext.Provider>\n    );\n  };\n\n  const Bpp = () => {\n    let { hello, setHello } = useContext(AppContext);\n    return () => <Cpp msg={hello} setMsg={setHello} />;\n  };\n\n  const Cpp = (p: { msg: string; setMsg: (msg: string) => void }) => {\n    let { msg, setMsg } = useProps(p);\n    let [count, setCount] = useState(0);\n\n    useEffect(\n      () => {\n        setMsg(\"world\");\n        setCount(count + 1);\n      },\n      () => []\n    );\n\n    return () => msg;\n  };\n\n  testRender(<App />, root);\n\n  expect(root.innerHTML).toBe(\"<div>hello</div>\");\n\n  await rendered();\n\n  expect(root.innerHTML).toBe(\"<div>world</div>\");\n});\n"
  },
  {
    "path": "packages/unis-dom/src/browser/__test__/dom.test.tsx",
    "content": "/**\n * @vitest-environment jsdom\n */\nimport { afterEach, beforeEach, expect, it } from \"vitest\";\nimport { useEffect } from \"@unis/core\";\nimport { useState } from \"@unis/core\";\nimport { rendered, testRender } from \"./util\";\n\nlet root: Element;\n\nbeforeEach(() => {\n  root = document.createElement(\"div\");\n  document.body.append(root);\n});\n\nafterEach(() => {\n  root.innerHTML = \"\";\n});\n\nit(\"dom\", async () => {\n  const App = () => {\n    let [toggle, setToggle] = useState(true);\n\n    const getCurrentStyle = () => {\n      return toggle\n        ? {\n            style: {\n              background: \"yellow\",\n            },\n            tabindex: \"1\",\n            className: \"class1\",\n            onClick: () => {},\n          }\n        : {\n            style: {\n              background: \"red\",\n            },\n            tabindex: \"2\",\n            onClick: () => {},\n          };\n    };\n\n    useEffect(\n      () => {\n        setToggle(false);\n      },\n      () => []\n    );\n\n    return () => {\n      return <div {...getCurrentStyle()}>hello</div>;\n    };\n  };\n\n  testRender(<App />, root);\n  expect(root.innerHTML).toBe(\n    '<div style=\"background: yellow;\" tabindex=\"1\" class=\"class1\">hello</div>'\n  );\n  await rendered();\n  expect(root.innerHTML).toBe(\n    '<div style=\"background: red;\" tabindex=\"2\">hello</div>'\n  );\n});\n"
  },
  {
    "path": "packages/unis-dom/src/browser/__test__/effect.test.tsx",
    "content": "/**\n * @vitest-environment jsdom\n */\nimport { afterEach, beforeEach, expect, it } from \"vitest\";\nimport { useEffect } from \"@unis/core\";\nimport { useState } from \"@unis/core\";\nimport { rendered, testRender } from \"./util\";\n\nlet root: Element;\n\nbeforeEach(() => {\n  root = document.createElement(\"div\");\n  document.body.append(root);\n});\n\nafterEach(() => {\n  root.innerHTML = \"\";\n});\n\nit(\"effect\", async () => {\n  const Bpp = () => {\n    useEffect(\n      () => {\n        return () => {};\n      },\n      () => []\n    );\n    return () => \"bpp\";\n  };\n\n  const App = () => {\n    let [visible, setVisible] = useState(true);\n\n    useEffect(\n      () => {\n        setVisible(false);\n      },\n      () => []\n    );\n\n    return () => (visible ? <Bpp /> : null);\n  };\n\n  testRender(<App />, root);\n  expect(root.innerHTML).toBe(\"bpp\");\n  await rendered();\n  expect(root.innerHTML).toBe(\"\");\n});\n"
  },
  {
    "path": "packages/unis-dom/src/browser/__test__/hydrate.test.tsx",
    "content": "/**\n * @vitest-environment jsdom\n */\nimport { afterEach, beforeEach, expect, it } from \"vitest\";\nimport { rendered, testRender } from \"./util\";\nimport { use, useState } from \"@unis/core\";\n\nlet root: Element;\n\nbeforeEach(() => {\n  root = document.createElement(\"div\");\n  document.body.append(root);\n});\n\nafterEach(() => {\n  root.innerHTML = \"\";\n});\n\nit(\"hydrate\", async () => {\n  root.innerHTML = \"<div>App<span>hello</span></div>\";\n\n  let setMsgOutter: any;\n\n  const App = () => {\n    let [msg, setMsg] = useState(\"hello\");\n\n    use(() => {\n      setMsgOutter = setMsg;\n    });\n\n    return () => (\n      <div>\n        App<span>{msg}</span>\n      </div>\n    );\n  };\n\n  testRender(<App />, root, true);\n\n  expect(root.innerHTML).toBe(\"<div>App<span>hello</span></div>\");\n\n  setMsgOutter(\"world\");\n\n  await rendered();\n\n  expect(root.innerHTML).toBe(\"<div>App<span>world</span></div>\");\n});\n"
  },
  {
    "path": "packages/unis-dom/src/browser/__test__/memo.test.tsx",
    "content": "/**\n * @vitest-environment jsdom\n */\nimport { afterEach, beforeEach, expect, it } from \"vitest\";\nimport { useEffect } from \"@unis/core\";\nimport { useState } from \"@unis/core\";\nimport { h2, memo } from \"@unis/core\";\nimport { rendered, testRender } from \"./util\";\n\nlet root: Element;\n\nbeforeEach(() => {\n  root = document.createElement(\"div\");\n  document.body.append(root);\n});\n\nafterEach(() => {\n  root.innerHTML = \"\";\n});\n\nit(\"memo\", async () => {\n  const Bpp = memo(() => {\n    let renderCount = 0;\n\n    return () => {\n      return <div>{renderCount++}</div>;\n    };\n  });\n  const App = () => {\n    let [msg, setMsg] = useState(\"hello\");\n\n    useEffect(\n      () => {\n        setMsg(\"hello world\");\n      },\n      () => []\n    );\n\n    return () => (\n      <div>\n        {msg}\n        {h2(Bpp, {}, \"key\")}\n      </div>\n    );\n  };\n\n  testRender(<App />, root);\n  expect(root.innerHTML).toBe(\"<div>hello<div>0</div></div>\");\n  await rendered();\n  expect(root.innerHTML).toBe(\"<div>hello world<div>0</div></div>\");\n});\n"
  },
  {
    "path": "packages/unis-dom/src/browser/__test__/portal.test.tsx",
    "content": "/**\n * @vitest-environment jsdom\n */\nimport { afterEach, beforeEach, expect, it } from \"vitest\";\nimport { useEffect } from \"@unis/core\";\nimport { useState } from \"@unis/core\";\nimport { createPortal, Fragment } from \"@unis/core\";\nimport { rendered, testRender } from \"./util\";\n\nlet root: Element;\nlet dialog: Element;\n\nbeforeEach(() => {\n  root = document.createElement(\"div\");\n  dialog = document.createElement(\"div\");\n  document.body.append(root, dialog);\n});\n\nafterEach(() => {\n  root.innerHTML = \"\";\n  dialog.innerHTML = \"\";\n});\n\nit(\"portal\", async () => {\n  const App = () => {\n    let [visible, setVisible] = useState(true);\n\n    useEffect(\n      () => {\n        setVisible(false);\n      },\n      () => []\n    );\n\n    return () => (\n      <Fragment>\n        <div>hello</div>\n        {visible && createPortal(<main>hello dialog</main>, dialog)}\n      </Fragment>\n    );\n  };\n\n  testRender(<App />, root);\n  expect(document.body.innerHTML).toBe(\n    \"<div><div>hello</div></div><div><main>hello dialog</main></div>\"\n  );\n  await rendered();\n  expect(document.body.innerHTML).toBe(\n    \"<div><div>hello</div></div><div></div>\"\n  );\n});\n"
  },
  {
    "path": "packages/unis-dom/src/browser/__test__/reconcile.test.tsx",
    "content": "/**\n * @vitest-environment jsdom\n */\nimport { afterEach, beforeEach, expect, it } from \"vitest\";\nimport { useEffect } from \"@unis/core\";\nimport { useState } from \"@unis/core\";\nimport { rendered, testRender } from \"./util\";\n\nlet root: Element;\n\nbeforeEach(() => {\n  root = document.createElement(\"div\");\n  document.body.append(root);\n});\n\nafterEach(() => {\n  root.innerHTML = \"\";\n});\n\nit(\"diff with key\", async () => {\n  const App = () => {\n    let [toggle, setToggle] = useState(false);\n\n    useEffect(\n      () => {\n        setToggle(true);\n      },\n      () => []\n    );\n\n    return () =>\n      !toggle ? (\n        <div>\n          <span>1</span>\n          <span key=\"2\">2</span>\n          <span key=\"3\">3</span>\n          <div>del</div>\n          <span key=\"4\">4</span>\n          <div key=\"5\">5</div>\n          <div>6</div>\n        </div>\n      ) : (\n        <div>\n          <span>1</span>\n          <div key=\"5\">5</div>\n          <span key=\"4\">4</span>\n          <span key=\"2\">2</span>\n          <span key=\"3\">3</span>\n          <div>6</div>\n        </div>\n      );\n  };\n\n  testRender(<App />, root);\n  expect(root.innerHTML).toBe(\n    '<div><span>1</span><span key=\"2\">2</span><span key=\"3\">3</span><div>del</div><span key=\"4\">4</span><div key=\"5\">5</div><div>6</div></div>'\n  );\n  await rendered();\n  expect(root.innerHTML).toBe(\n    '<div><span>1</span><div key=\"5\">5</div><span key=\"4\">4</span><span key=\"2\">2</span><span key=\"3\">3</span><div>6</div></div>'\n  );\n});\n"
  },
  {
    "path": "packages/unis-dom/src/browser/__test__/util.ts",
    "content": "import { readyForWork, createRoot, createTokTik } from \"@unis/core\";\nimport { createOperator } from \"../operator\";\n\nconst toktik = createTokTik({\n  nextTick: (cb: VoidFunction) =>\n    Promise.resolve()\n      .catch((err) => console.error(err))\n      .then(() => cb()),\n  now: () => 0,\n});\nconst operator = createOperator();\n\nexport const testRender = (\n  element: any,\n  container: Element,\n  hydrate = false\n) => {\n  const rootFiber = createRoot(element, container);\n  rootFiber.runtime = {\n    toktik,\n    operator,\n  };\n  readyForWork(rootFiber, hydrate);\n};\n\nexport const rendered = () =>\n  new Promise((resolve) => {\n    setTimeout(resolve, 0);\n  });\n"
  },
  {
    "path": "packages/unis-dom/src/browser/__test__/utils.test.ts",
    "content": "/**\n * @vitest-environment jsdom\n */\nimport { expect, it } from \"vitest\";\nimport { classes, svgKey, styleStr } from \"@unis/core\";\n\nit(\"classes\", () => {\n  expect(classes([\"a\", \"b\", 1, [\"c\", { d: true }]])).toBe(\"a b 1 c d\");\n  expect(classes({ a: true, b: undefined, c: null })).toBe(\"a\");\n  expect(classes({ a: false, b: true, c: null })).toBe(\"b\");\n});\n\nit(\"realSVGAttr\", () => {\n  expect(svgKey(\"glyphOrientationVertical\")).toBe(\"glyph-orientation-vertical\");\n});\n\nit(\"style2String\", () => {\n  expect(styleStr({ background: \"yellow\", fontSize: \"14px\" })).toBe(\n    \"background: yellow; font-size: 14px;\"\n  );\n});\n"
  },
  {
    "path": "packages/unis-dom/src/browser/const.ts",
    "content": "export const UNIS_ROOT = Symbol(\"unis_root\");\n"
  },
  {
    "path": "packages/unis-dom/src/browser/index.ts",
    "content": "export { UNIS_ROOT } from \"./const\";\nexport { render } from \"./render\";\n"
  },
  {
    "path": "packages/unis-dom/src/browser/operator.ts",
    "content": "import { Fiber, findEls, isPortal, isText, Operator } from \"@unis/core\";\nimport { getEventName, isEvent, isNullish } from \"@unis/core\";\nimport { UNIS_ROOT } from \"./const\";\n\ntype FiberDomEl = Element | DocumentFragment | SVGAElement | Text | ParentNode;\n\ninterface FiberDom extends Fiber {\n  el?: FiberDomEl;\n}\n\nexport const createOperator = (): Operator => {\n  const createElement = (fiber: FiberDom) => {\n    const { tag: type, isSvg } = fiber;\n    return isText(fiber)\n      ? document.createTextNode(fiber.props.nodeValue + \"\")\n      : isSvg\n      ? document.createElementNS(\"http://www.w3.org/2000/svg\", type as string)\n      : document.createElement(type as string);\n  };\n\n  const nextElement = (el: FiberDomEl | null) => {\n    while (el) {\n      if (el.firstChild) return el.firstChild;\n      if (el.nextSibling) return el.nextSibling;\n      while ((el = el.parentNode)) {\n        if ((el as any)[UNIS_ROOT]) return null;\n        if (el.nextSibling) return el.nextSibling;\n      }\n    }\n    return null;\n  };\n\n  const matchElement = (fiber: FiberDom, el: Element | Text) =>\n    el.nodeType === Node.TEXT_NODE\n      ? isText(fiber)\n      : (el as Element).tagName.toLocaleLowerCase() === fiber.tag;\n\n  const insertBefore = (\n    containerFiber: FiberDom,\n    insertElement: FiberDomEl,\n    targetElement: FiberDomEl | null\n  ) => {\n    (\n      (isPortal(containerFiber)\n        ? containerFiber.to\n        : containerFiber.el)! as FiberDomEl\n    ).insertBefore(insertElement, targetElement);\n  };\n\n  const nextSibling = (fiber: FiberDom) => fiber.el!.nextSibling;\n\n  const firstChild = (fiber: FiberDom) => fiber.el!.firstChild;\n\n  const remove = (fiber: FiberDom) => {\n    const [first, ...rest] = findEls(fiber) as FiberDomEl[];\n    const parentNode = first?.parentNode;\n    if (parentNode) {\n      for (const el of [first, ...rest]) {\n        parentNode.removeChild(el);\n      }\n    }\n  };\n\n  const updateTextProperties = (fiber: FiberDom) => {\n    (fiber.el! as Text).nodeValue = fiber.props.nodeValue + \"\";\n  };\n\n  const setAttr = (\n    el: SVGAElement | HTMLElement,\n    isSvg: boolean,\n    key: string,\n    value: string\n  ) =>\n    isSvg\n      ? (el as SVGAElement).setAttributeNS(null, key, value)\n      : (el as HTMLElement).setAttribute(key, value);\n\n  const removeAttr = (\n    el: SVGAElement | HTMLElement,\n    isSvg: boolean,\n    key: string\n  ) =>\n    isSvg\n      ? (el as SVGAElement).removeAttributeNS(null, key)\n      : (el as HTMLElement).removeAttribute(key);\n\n  const updateElementProperties = (fiber: FiberDom) => {\n    let { el, isSvg, attrDiff } = fiber;\n\n    for (const [key, newValue, oldValue] of attrDiff || []) {\n      const newExist = !isNullish(newValue);\n      const oldExist = !isNullish(oldValue);\n      if (key === \"ref\") {\n        oldExist && (oldValue.current = undefined);\n        newExist && (newValue.current = el);\n      } else if (isEvent(key)) {\n        const [eventName, capture] = getEventName(key);\n        oldExist && el!.removeEventListener(eventName, oldValue);\n        newExist && el!.addEventListener(eventName, newValue, capture);\n      } else {\n        newExist\n          ? setAttr(el as SVGAElement | HTMLElement, isSvg!, key, newValue)\n          : removeAttr(el as SVGAElement | HTMLElement, isSvg!, key);\n      }\n    }\n  };\n\n  return {\n    createElement,\n    nextElement,\n    matchElement,\n    insertBefore,\n    nextSibling,\n    firstChild,\n    remove,\n    updateTextProperties,\n    updateElementProperties,\n  };\n};\n"
  },
  {
    "path": "packages/unis-dom/src/browser/render.ts",
    "content": "import { readyForWork, createRoot, createTokTik } from \"@unis/core\";\nimport { createOperator } from \"./operator\";\nimport { UNIS_ROOT } from \"./const\";\nimport { nextTick, now } from \"./toktik\";\n\nconst operator = createOperator();\nconst toktik = createTokTik({\n  now,\n  nextTick,\n  interval: (window as any).UNIS_INTERVAL,\n});\n\nexport const render = (element: any, container: Element, hydrate = false) => {\n  (container as any)[UNIS_ROOT] = true;\n  const rootFiber = createRoot(element, container);\n  rootFiber.runtime = {\n    toktik,\n    operator,\n  };\n  readyForWork(rootFiber, hydrate);\n};\n"
  },
  {
    "path": "packages/unis-dom/src/browser/toktik.ts",
    "content": "export const nextTick = (cb: VoidFunction, pending = false) => {\n  if (pending) {\n    queueMicrotask(cb);\n  } else if (window.MessageChannel) {\n    const { port1, port2 } = new window.MessageChannel();\n    port1.postMessage(\"\");\n    port2.onmessage = () => cb();\n  } else {\n    setTimeout(() => cb());\n  }\n};\n\nexport const now = () => performance.now();\n"
  },
  {
    "path": "packages/unis-dom/src/server/__test__/server.test.tsx",
    "content": "import { expect, it } from \"vitest\";\nimport { renderToString } from \"..\";\n\nit(\"render to string\", () => {\n  const App = () => {\n    return () => (\n      <div className=\"test\">\n        <>\n          <h1>hello</h1>\n          <span style={{ background: \"yellow\" }}>world</span>\n        </>\n      </div>\n    );\n  };\n\n  const result = renderToString(<App />);\n\n  expect(result).toBe(\n    '<div class=\"test\"><h1>hello</h1><span style=\"background: yellow;\">world</span></div>'\n  );\n});\n"
  },
  {
    "path": "packages/unis-dom/src/server/index.ts",
    "content": "import { createRoot, createTokTik, readyForWork } from \"@unis/core\";\nimport { createOperator, ElementNode } from \"./operator\";\n\nconst operator = createOperator();\n\nconst toktik = createTokTik({\n  nextTick: (cb: VoidFunction) =>\n    Promise.resolve()\n      .catch((err) => console.error(err))\n      .then(() => cb()),\n  now: () => 0,\n});\n\nexport const renderToString = (element: any) => {\n  const rootNode = new ElementNode(\"\");\n  const rootFiber = createRoot(element, rootNode);\n  rootFiber.runtime = {\n    toktik,\n    operator,\n  };\n  readyForWork(rootFiber);\n  return rootNode.renderToString();\n};\n"
  },
  {
    "path": "packages/unis-dom/src/server/operator.ts",
    "content": "import { isEvent, isNullish, Operator, Fiber, isText } from \"@unis/core\";\n\nexport class ElementNode {\n  children: ServerNode[] = [];\n\n  properties: Record<string, string> = {};\n\n  constructor(public tagName: string) {}\n\n  insertBefore(\n    node: ElementNode | TextNode,\n    child: ElementNode | TextNode | null\n  ) {\n    this.children.push(node);\n  }\n\n  append(...nodes: ServerNode[]) {\n    this.children.push(...nodes);\n  }\n\n  renderToString(): string {\n    const children = this.children\n      .map((child) => child.renderToString())\n      .join(\"\");\n\n    const propertiesStr = Object.keys(this.properties)\n      .map((key) => `${key}=\"${this.properties[key]}\"`)\n      .join(\" \");\n\n    const gap = propertiesStr ? \" \" : \"\";\n\n    return this.tagName\n      ? `<${this.tagName}${gap}${propertiesStr}>${children}</${this.tagName}>`\n      : children;\n  }\n}\n\nexport class TextNode {\n  constructor(public nodeValue: string) {}\n  renderToString() {\n    return this.nodeValue;\n  }\n}\n\nexport type ServerNode = ElementNode | TextNode;\n\ninterface FiberDomServer extends Fiber {\n  el?: ServerNode;\n}\n\nexport const createOperator = (): Operator => {\n  const createElement = (fiber: FiberDomServer) => {\n    const { tag: type } = fiber;\n    return isText(fiber)\n      ? new TextNode(fiber.props.nodeValue + \"\")\n      : new ElementNode(type as string);\n  };\n\n  const insertBefore = (\n    containerFiber: FiberDomServer,\n    insertElement: ServerNode,\n    targetElement: ServerNode\n  ) => {\n    (containerFiber.el as ElementNode).insertBefore(\n      insertElement,\n      targetElement\n    );\n  };\n\n  const firstChild = (fiber: FiberDomServer) =>\n    (fiber.el as ElementNode).children[0] ?? null;\n\n  const updateTextProperties = (fiber: FiberDomServer) => {\n    (fiber.el as TextNode).nodeValue = fiber.props.nodeValue + \"\";\n  };\n\n  const updateElementProperties = (fiber: FiberDomServer) => {\n    let { el, attrDiff } = fiber;\n\n    for (const [key, newValue, oldValue] of attrDiff || []) {\n      const newExist = !isNullish(newValue);\n      const oldExist = !isNullish(oldValue);\n      if (key === \"ref\") {\n        oldExist && (oldValue.current = undefined);\n        newExist && (newValue.current = el);\n      } else if (isEvent(key)) {\n        // nothing...\n      } else {\n        newExist\n          ? ((el as ElementNode).properties[key] = newValue)\n          : delete (el as ElementNode).properties[key];\n      }\n    }\n  };\n\n  return {\n    nextElement() {},\n    matchElement: () => false,\n    remove() {},\n    nextSibling() {},\n    createElement,\n    insertBefore,\n    firstChild,\n    updateTextProperties,\n    updateElementProperties,\n  };\n};\n"
  },
  {
    "path": "packages/unis-dom/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"exclude\": [\"**/*.test.*\", \"**/__test__\"]\n}\n"
  },
  {
    "path": "packages/unis-dom/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"build\"\n  },\n  \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "packages/unis-dom/vitest.config.ts",
    "content": "import { defineConfig } from \"vitest/config\";\nimport { unisPreset } from \"@unis/vite-preset\";\n\nexport default defineConfig({\n  plugins: [unisPreset()],\n  test: {\n    include: [\"**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}\"],\n    coverage: {\n      reporter: [\"text\", \"json\", \"html\"],\n    },\n  },\n});\n"
  },
  {
    "path": "packages/unis-example/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Microbundle cache\n.rpt2_cache/\n.rts2_cache_cjs/\n.rts2_cache_es/\n.rts2_cache_umd/\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n.env.test\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n.parcel-cache\n\n# Next.js build output\n.next\n\n# Nuxt.js build / generate output\n.nuxt\ndist\nbuild\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and *not* Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# TernJS port file\n.tern-port\n\n.DS_Store\n"
  },
  {
    "path": "packages/unis-example/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Unis</title>\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <div id=\"dialog\"></div>\n    <script type=\"module\" src=\"./src/index.tsx\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/unis-example/other.d.ts",
    "content": "declare module \"*.css\";\n"
  },
  {
    "path": "packages/unis-example/package.json",
    "content": "{\n  \"name\": \"@unis/unis-example\",\n  \"version\": \"0.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"private\": \"true\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/anuoua/unis.git\"\n  },\n  \"author\": \"anuoua\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/anuoua/unis/issues\"\n  },\n  \"homepage\": \"https://github.com/anuoua/unis#readme\",\n  \"dependencies\": {\n    \"@unis/core\": \"workspace:^\",\n    \"@unis/dom\": \"workspace:^\",\n    \"@unis/router\": \"workspace:^\",\n    \"@unis/transition\": \"workspace:^\"\n  },\n  \"devDependencies\": {\n    \"@types/lodash\": \"^4.14.182\",\n    \"@unis/vite-preset\": \"workspace:^\",\n    \"autoprefixer\": \"^10.4.0\",\n    \"postcss\": \"^8.3.11\",\n    \"rollup-plugin-reassign\": \"^1.0.2\",\n    \"tailwindcss\": \"^3.3.1\",\n    \"vite\": \"^4.1.2\"\n  }\n}\n"
  },
  {
    "path": "packages/unis-example/postcss.config.js",
    "content": "module.exports = {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n};\n"
  },
  {
    "path": "packages/unis-example/src/Dialog.tsx",
    "content": "import { createPortal, useProps, useRef } from \"@unis/core\";\nimport { Item } from \"./TodoItem\";\n\ninterface DialogProps {\n  onClose: () => void;\n  onConfirm: (item: Item) => void;\n  item: Item | null;\n}\n\nexport function Dialog(props: DialogProps) {\n  let { item, onClose, onConfirm } = useProps(props);\n\n  const portalRef = useRef<HTMLElement>();\n\n  const handleClose = (e: MouseEvent) => {\n    if ((e.target as HTMLElement) === portalRef.current) {\n      onClose();\n    }\n  };\n\n  const handleConfirm = () => {\n    onConfirm(item!);\n  };\n\n  return () =>\n    createPortal(\n      <div\n        ref={portalRef}\n        className=\"bg-gray-900 bg-opacity-40 fixed left-0 top-0 h-full w-full flex items-center justify-center\"\n        onClick={handleClose}\n      >\n        <div className=\"w-96 bg-white rounded-md flex flex-col shadow-md\">\n          <div className=\"flex-shrink-0 text-right px-4 pt-4\">\n            <button onClick={() => props.onClose()}>\n              <svg\n                xmlns=\"http://www.w3.org/2000/svg\"\n                className=\"h-6 w-6\"\n                fill=\"none\"\n                viewBox=\"0 0 24 24\"\n                stroke=\"currentColor\"\n              >\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M6 18L18 6M6 6l12 12\"\n                />\n              </svg>\n            </button>\n          </div>\n          <div className=\"flex-1 p-10 flex\">\n            <svg\n              xmlns=\"http://www.w3.org/2000/svg\"\n              className=\"h-10 w-10 text-gray-400\"\n              fill=\"none\"\n              viewBox=\"0 0 24 24\"\n              stroke=\"currentColor\"\n            >\n              <path\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n                strokeWidth={2}\n                d=\"M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n              />\n            </svg>\n            <div className=\"p-2 text-gray-700\">\n              {\" \"}\n              Delete <span className=\"text-red-400\">{item?.name}</span> ?\n            </div>\n          </div>\n          <div className=\"flex-shrink-0 text-right\">\n            <button\n              className=\"m-2 p-2 px-5 bg-blue-500 text-gray-100 text-sm rounded-md focus:border-4 border-blue-300\"\n              onClick={handleConfirm}\n            >\n              Confirm\n            </button>\n          </div>\n        </div>\n      </div>,\n      document.querySelector(\"#dialog\")!\n    );\n}\n"
  },
  {
    "path": "packages/unis-example/src/Todo.tsx",
    "content": "import { useState } from \"@unis/core\";\nimport { CSSTransition, TransitionGroup } from \"@unis/transition\";\nimport { Dialog } from \"./Dialog\";\nimport { Item, TodoItem } from \"./TodoItem\";\n\nlet count = 0;\n\nlet todos: any[] = [];\n\nfor (; count < 0; count++) {\n  todos.push({\n    id: count,\n    name: \"\",\n    editing: false,\n    canceled: false,\n  });\n}\n\nexport function ToDo() {\n  let [todoList, setTodoList] = useState<any[]>(todos);\n  let [dialogVisible, setDialogVisible] = useState(false);\n  let [titleVisible, setTitleVisible] = useState(true);\n  let [currentItem, setCurrentItem] = useState<Item | null>(null);\n\n  const handleToggleTitle = () => {\n    setTitleVisible(!titleVisible);\n    setTimeout(() => {\n      setTitleVisible(true);\n    }, 200);\n  };\n\n  const handleAdd = (e: any) => {\n    if (e.key !== \"Enter\") return;\n    setTodoList([\n      ...todoList,\n      {\n        id: ++count,\n        name: e.target.value,\n        editing: false,\n        canceled: false,\n      },\n    ]);\n    e.target.value = \"\";\n  };\n\n  const handleClose = () => {\n    setDialogVisible(false);\n  };\n\n  const handleConfirm = (item: Item) => {\n    setDialogVisible(false);\n    setTodoList(todoList.filter((i) => i !== item));\n  };\n\n  const handleDelete = (item: Item) => {\n    setCurrentItem(item);\n    setTodoList(todoList.filter((i) => i !== item));\n    // setDialogVisible(true);\n  };\n\n  return () => (\n    <div className=\"w-80\">\n      <CSSTransition timeout={400} in={titleVisible} classNames=\"scale\">\n        <h1\n          className=\"font-mono text-white font-bold text-4xl mb-10 w-full text-center cursor-pointer\"\n          onClick={handleToggleTitle}\n        >\n          TODO\n        </h1>\n      </CSSTransition>\n      <input\n        type=\"text\"\n        placeholder=\"Input here\"\n        className=\"h-14 border-2 rounded-md px-2 mb-10 w-full\"\n        onKeyPress={handleAdd}\n      />\n      <ul className=\"h-80 w-full flex flex-col gap-5 overflow-auto\">\n        <TransitionGroup>\n          {todoList.map((i: any) => (\n            <CSSTransition key={i.id} timeout={400} classNames=\"scale\" appear>\n              <TodoItem item={i} onDelete={handleDelete} />\n            </CSSTransition>\n          ))}\n        </TransitionGroup>\n      </ul>\n      {dialogVisible && (\n        <Dialog\n          item={currentItem}\n          onClose={handleClose}\n          onConfirm={handleConfirm}\n        />\n      )}\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/unis-example/src/TodoItem/index.module.css",
    "content": ".deleteIcon {\n  color: white;\n}\n"
  },
  {
    "path": "packages/unis-example/src/TodoItem/index.tsx",
    "content": "import { use, memo, useEffect, useProps, useRef } from \"@unis/core\";\nimport { Update } from \"../hooks/update\";\nimport s from \"./index.module.css\";\n\nexport interface Item {\n  id: number;\n  name: string;\n  editing: boolean;\n  canceled: boolean;\n}\n\ninterface TodoItemProps {\n  item: Item;\n  onDelete: (item: Item) => any;\n}\n\nexport const TodoItem = memo((props: TodoItemProps) => {\n  let { item, onDelete } = useProps(props);\n  let [render] = use(Update());\n  let { editing, canceled, name } = use(() => item);\n\n  const inputRef = useRef();\n\n  const handleEditing = () => {\n    if (canceled) return;\n    item.editing = true;\n    render();\n  };\n\n  const handleClick = () => {\n    onDelete(item);\n  };\n\n  const handleCancel = () => {\n    console.log(inputRef.current);\n    item.canceled = !item.canceled;\n    render();\n  };\n\n  const handleKeyDown = (e: any) => {\n    if (e.key !== \"Enter\") return;\n    item.name = e.target.value;\n    item.editing = false;\n    render();\n  };\n\n  const handleBlur = () => {\n    item.editing = false;\n    render();\n  };\n\n  useEffect(\n    () => {\n      item.name = item.name + \"x\";\n      render();\n    },\n    () => [item.canceled]\n  );\n\n  return () => {\n    // console.log(\"TodoItem render\");\n    return (\n      <li className=\"flex flex-row items-center justify-between gap-5 bg-white bg-opacity-50 rounded-md p-5 shadow-md\">\n        {editing ? (\n          <input\n            ref={inputRef}\n            value={name}\n            className=\"flex-grow min-w-0\"\n            type=\"text\"\n            onKeyDown={handleKeyDown}\n            onBlur={handleBlur}\n          ></input>\n        ) : canceled ? (\n          <del\n            className=\"flex-grow min-w-0 overflow-ellipsis overflow-hidden\"\n            onClick={handleEditing}\n          >\n            {name}\n          </del>\n        ) : (\n          <span\n            className=\"flex-grow min-w-0 overflow-ellipsis overflow-hidden\"\n            onClick={handleEditing}\n          >\n            {name}\n          </span>\n        )}\n        <i\n          className={`${s.deleteIcon} cursor-pointer`}\n          onClick={handleCancel}\n          title={canceled ? \"Revert\" : \"Cancel\"}\n        >\n          {canceled ? (\n            <svg\n              xmlns=\"http://www.w3.org/2000/svg\"\n              className=\"h-6 w-6 text-gray-500\"\n              fill=\"none\"\n              viewBox=\"0 0 24 24\"\n              stroke=\"currentColor\"\n            >\n              <path\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n                strokeWidth={2}\n                d=\"M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6\"\n              />\n            </svg>\n          ) : (\n            <svg\n              xmlns=\"http://www.w3.org/2000/svg\"\n              className=\"h-6 w-6 text-gray-500\"\n              fill=\"none\"\n              viewBox=\"0 0 24 24\"\n              stroke=\"currentColor\"\n            >\n              <path\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n                strokeWidth={2}\n                d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"\n              />\n            </svg>\n          )}\n        </i>\n        <i\n          className={`${s.deleteIcon} cursor-pointer`}\n          onClick={handleClick}\n          title=\"Delete\"\n        >\n          <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            className=\"h-6 w-6 text-gray-500\"\n            fill=\"none\"\n            viewBox=\"0 0 24 24\"\n            stroke=\"currentColor\"\n          >\n            <path\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              strokeWidth={2}\n              d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n            />\n          </svg>\n        </i>\n      </li>\n    );\n  };\n});\n"
  },
  {
    "path": "packages/unis-example/src/Welcome/index.module.css",
    "content": ".msg {\n  font-size: 50px;\n  font-weight: bold;\n  background: -webkit-linear-gradient(0deg,#e339bc 25%,#4f5b94);\n  background-clip: text;\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  transition: all .3s ease;\n}\n\n.msg:hover {\n  cursor: pointer;\n  transform: scale(1.2);\n  background: -webkit-linear-gradient(0deg,#4f5b94 25%,#e339bc);\n  background-clip: text;\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n}"
  },
  {
    "path": "packages/unis-example/src/Welcome/index.tsx",
    "content": "import { Link } from \"@unis/router\";\nimport s from \"./index.module.css\";\n\nexport const Welcome = () => {\n  return () => (\n    <Link to=\"main\" className={s.msg}>\n      Unis Todo\n    </Link>\n  );\n};\n"
  },
  {
    "path": "packages/unis-example/src/global.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\nhtml,\nbody,\n#root {\n  height: 100%;\n}\n\n.scale-appear {\n  transform: scale(0) translateZ(0);\n}\n\n.scale-appear-active {\n  transform: scale(1) translateZ(0);\n  transition: all 0.4s ease;\n}\n\n.scale-appear-done {\n  transform: scale(1) translateZ(0);\n}\n\n.scale-enter {\n  transform: scale(0) translateZ(0);\n}\n\n.scale-enter-active {\n  transform: scale(1) translateZ(0);\n  transition: all 0.4s ease;\n}\n\n.scale-enter-done {\n  transform: scale(1) translateZ(0);\n}\n\n.scale-exit {\n  transform: scale(1) translateZ(0);\n}\n\n.scale-exit-active {\n  transform: scale(0) translateZ(0);\n  transition: all 0.4s ease;\n}\n\n.scale-exit-done {\n  transform: scale(0) translateZ(0);\n}\n\n.fade-enter {\n  opacity: 0;\n}\n\n.fade-enter-active {\n  opacity: 1;\n  transition: all 0.4s ease;\n}\n\n.fade-enter-done {\n  opacity: 1;\n}\n\n.fade-exit {\n  opacity: 1;\n}\n\n.fade-exit-active {\n  opacity: 0;\n  transition: all 0.4s ease;\n}\n\n.fade-exit-done {\n  opacity: 0;\n}\n\n"
  },
  {
    "path": "packages/unis-example/src/hooks/update.ts",
    "content": "import { useState } from \"@unis/core\";\n\nexport const Update = () => {\n  let [count, setCount] = useState(1);\n  const update = () => setCount(++count);\n  return () => [update];\n};\n"
  },
  {
    "path": "packages/unis-example/src/index.module.css",
    "content": ".background_img {\n  background: url(./bg.jpeg);\n  z-index: -1;\n  background-size: cover;\n  background-position: center;\n}\n"
  },
  {
    "path": "packages/unis-example/src/index.tsx",
    "content": "import {\n  Fragment,\n  // useProps,\n  // useState,\n  // useEffect\n} from \"@unis/core\";\nimport { render } from \"@unis/dom\";\nimport { ToDo } from \"./Todo\";\nimport \"./global.css\";\nimport s from \"./index.module.css\";\nimport { BrowserRouter, Redirect, Outlet, Route, Routes } from \"@unis/router\";\nimport { Welcome } from \"./Welcome\";\n\n// const Bpp = (props: { time: number; msg: string }) => {\n//   let { time, msg } = useProps(props);\n//   let [visible, setVisible] = useState(false);\n\n//   useEffect(\n//     () => {\n//       setVisible(true);\n//       setTimeout(() => {\n//         console.log(\"timeout\");\n//         setVisible(false);\n//       }, 0);\n//     },\n//     () => []\n//   );\n\n//   setTimeout(() => {\n//     setVisible(true);\n//   }, time);\n\n//   return () => (visible ? <div>{msg}</div> : false);\n// };\n\nconst App = () => {\n  return () => (\n    <Fragment>\n      <div className={`${s.background_img} absolute h-full w-full`}></div>\n      <>\n        {/* <Bpp time={0} msg=\"Bpp\" /> */}\n        {/* <Bpp time={1000} msg=\"Bpp2\" /> */}\n      </>\n      {/* <Bpp time={1500} msg=\"Bpp3\" /> */}\n      <div\n        className={`flex justify-center flex-col items-center h-full relative backdrop-filter backdrop-blur-lg`}\n      >\n        <Outlet />\n      </div>\n    </Fragment>\n  );\n};\n\nrender(\n  <BrowserRouter>\n    <Routes path=\"/\" element={<App />}>\n      <Route element={<Welcome />} />\n      <Route path=\"main\" element={<ToDo />} />\n      <Route path=\"*\" element={<Redirect to=\"main\" />} />\n    </Routes>\n  </BrowserRouter>,\n  document.querySelector(\"#root\")!\n);\n"
  },
  {
    "path": "packages/unis-example/tailwind.config.js",
    "content": "module.exports = {\n  content: [\"./public/**/*.html\", \"./src/**/*.{js,jsx,ts,tsx,vue}\"],\n  theme: {\n    extend: {},\n  },\n  variants: {\n    extend: {},\n  },\n  plugins: [],\n};\n"
  },
  {
    "path": "packages/unis-example/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"src\", \"other.d.ts\"]\n}\n"
  },
  {
    "path": "packages/unis-example/vite.config.js",
    "content": "import { defineConfig } from \"vite\";\nimport { unisPreset } from \"@unis/vite-preset\";\n\nexport default defineConfig({\n  plugins: [unisPreset()],\n});\n"
  },
  {
    "path": "packages/unis-router/.gitignore",
    "content": "build/\ncoverage/\ndist/"
  },
  {
    "path": "packages/unis-router/README.md",
    "content": "# Unis Router\n\nRouter for unis, inspire by [React Router V6](https://github.com/remix-run/react-router).\n\n## Install\n\n```shell\nnpm i @unis/router\n```\n\n## Usage\n\nUnis router's api is partial same as React Router V6.\n\nexample\n\n```javascript\nimport { BrowserRouter, Routes, Route, Outlet } from '@unis/router'\n\nconst Dashboard = () => {\n  \n  return () => (\n    <div>\n      dashboard\n      <Outlet /> // hello\n    </div>\n  )\n}\n\nconst App = () => {\n\n  return () => (\n    <div>\n      <header>App</header>\n      <Routes path=\"dashboard\" element={<Dashboard />}>\n        <Route path=\"hello\" element={<div>hello</div>} />\n      </Routes>\n    </div>\n  )\n}\n\nrender(\n  <BrowserRouter basename=\"admin\">\n    <App />\n  </BrowserRouter>, document.querySelector('#app'))\n```\n\n\n"
  },
  {
    "path": "packages/unis-router/package.json",
    "content": "{\n  \"name\": \"@unis/router\",\n  \"version\": \"0.1.0\",\n  \"description\": \"Unis router component\",\n  \"main\": \"dist/index.js\",\n  \"module\": \"dist/index.mjs\",\n  \"types\": \"dist/index.d.ts\",\n  \"typings\": \"dist/index.d.ts\",\n  \"scripts\": {\n    \"build\": \"rimraf build && rimraf dist && tsc -p tsconfig.json && rollup --config\",\n    \"build:dev\": \"cross-env NODE_ENV=development pnpm build\",\n    \"test\": \"vitest run --coverage\",\n    \"test:watch\": \"vitest -w\"\n  },\n  \"exports\": {\n    \".\": {\n      \"require\": \"./dist/index.js\",\n      \"import\": \"./dist/index.mjs\"\n    }\n  },\n  \"keywords\": [\n    \"unis\",\n    \"router\"\n  ],\n  \"files\": [\n    \"dist\"\n  ],\n  \"author\": \"anuoua\",\n  \"peerDependencies\": {\n    \"@unis/core\": \"workspace:^\"\n  },\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/anuoua/unis/issues\"\n  },\n  \"homepage\": \"https://github.com/anuoua/unis/tree/main/packages/unis-router\",\n  \"devDependencies\": {\n    \"@rollup/plugin-node-resolve\": \"^15.0.2\",\n    \"@types/node\": \"^18.15.11\",\n    \"@unis/core\": \"workspace:^\",\n    \"@unis/vite-preset\": \"workspace:^\",\n    \"@vitest/coverage-c8\": \"^0.29.8\",\n    \"cross-env\": \"^7.0.3\",\n    \"esbuild\": \"^0.17.15\",\n    \"rimraf\": \"^4.4.1\",\n    \"rollup\": \"^3.20.2\",\n    \"rollup-plugin-dts\": \"^5.3.0\",\n    \"rollup-plugin-esbuild\": \"^5.0.0\",\n    \"rollup-plugin-reassign\": \"^1.0.3\",\n    \"typescript\": \"^5.0.3\",\n    \"vitest\": \"^0.29.8\"\n  },\n  \"dependencies\": {\n    \"history\": \"^5.3.0\"\n  }\n}\n"
  },
  {
    "path": "packages/unis-router/rollup.config.mjs",
    "content": "import esbuild from \"rollup-plugin-esbuild\";\nimport dts from \"rollup-plugin-dts\";\nimport { defineConfig } from \"rollup\";\nimport { nodeResolve } from \"@rollup/plugin-node-resolve\";\nimport { reassign } from \"rollup-plugin-reassign\";\nimport { unisFns } from \"@unis/core\";\n\nconst configGen = (format) =>\n  defineConfig({\n    input: \"src/index.ts\",\n    external: [/^@unis/, \"history\"],\n    output: [\n      {\n        dir: \"dist\",\n        entryFileNames: `index.${format === \"esm\" ? \"mjs\" : \"js\"}`,\n        format,\n        sourcemap: true,\n      },\n    ],\n    plugins: [\n      nodeResolve(),\n      esbuild({\n        sourceMap: true,\n        target: \"esnext\",\n        jsx: \"automatic\",\n        jsxImportSource: \"@unis/core\",\n      }),\n      reassign({\n        include: [\"**/*.(t|j)s?(x)\"],\n        targetFns: {\n          \"@unis/core\": unisFns,\n        },\n      }),\n    ],\n  });\n\nconst dtsRollup = () =>\n  defineConfig({\n    input: \"build/index.d.ts\",\n    output: [{ file: \"dist/index.d.ts\", format: \"es\" }],\n    plugins: [dts()],\n  });\n\nconst config = [configGen(\"cjs\"), configGen(\"esm\"), dtsRollup()];\n\nexport default config;\n"
  },
  {
    "path": "packages/unis-router/src/components/BrowserRouter.tsx",
    "content": "import { useProps, useLayoutEffect, useState, useMemo } from \"@unis/core\";\nimport { createBrowserHistory, BrowserHistory } from \"history\";\nimport { LocationContext, RouterContext } from \"../context\";\n\nexport interface BrowserRouterProps {\n  children?: JSX.Element | JSX.Element[];\n  history?: BrowserHistory;\n  basename?: string;\n}\n\nexport const BrowserRouter = (p: BrowserRouterProps) => {\n  let { children, history, basename } = useProps(p);\n\n  const historyInstance = history ?? createBrowserHistory();\n\n  let [location, setLocation] = useState(historyInstance.location);\n\n  const navigationContextValue = {\n    basename: basename ?? \"\",\n    history: historyInstance,\n  };\n\n  let locationContextValue = useMemo(\n    () => ({ location }),\n    () => [location]\n  );\n\n  useLayoutEffect(\n    () => {\n      const unlisten = historyInstance.listen(({ location }) => {\n        setLocation(location);\n      });\n      return () => unlisten();\n    },\n    () => []\n  );\n\n  return () => (\n    <RouterContext.Provider value={navigationContextValue}>\n      <LocationContext.Provider value={locationContextValue}>\n        {children}\n      </LocationContext.Provider>\n    </RouterContext.Provider>\n  );\n};\n"
  },
  {
    "path": "packages/unis-router/src/components/Link.tsx",
    "content": "import {\n  AnchorHTMLAttributes,\n  ElementAttrs,\n  use,\n  useContext,\n  useProps,\n} from \"@unis/core\";\nimport { RouterContext } from \"../context\";\nimport { uTargetPath } from \"../hooks/uTargetPath\";\n\nexport type LinkProps = Partial<\n  Omit<ElementAttrs<AnchorHTMLAttributes>, \"href\"> & {\n    to: string;\n  }\n>;\n\nexport const Link = (p: LinkProps) => {\n  let { to, children, onClick, ...rest } = useProps(p);\n\n  let { history } = useContext(RouterContext);\n\n  let targetPath = use(uTargetPath(() => ({ to })));\n\n  const handleJump = (e: MouseEvent) => {\n    const target = (e.target as HTMLAnchorElement).target;\n    if (\n      e.button === 0 &&\n      (!target || target === \"_self\") &&\n      !(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n    ) {\n      if (history.location.pathname !== targetPath) {\n        history.push(targetPath);\n      } else {\n        history.replace(targetPath);\n      }\n      e.preventDefault();\n    }\n    onClick?.(e);\n  };\n\n  return () => (\n    <a {...rest} href={targetPath} onClick={handleJump}>\n      {children}\n    </a>\n  );\n};\n"
  },
  {
    "path": "packages/unis-router/src/components/NavLink.tsx",
    "content": "import { HTMLAttributes, use, useContext, useProps } from \"@unis/core\";\nimport { RouteContext } from \"../context\";\nimport { uTargetPath } from \"../hooks/uTargetPath\";\nimport { Link, LinkProps } from \"./Link\";\n\nexport type LinkStyle = (isActive: boolean) => HTMLAttributes[\"style\"];\nexport type LinkClassName = (isActive: boolean) => HTMLAttributes[\"className\"];\n\nexport type NavLinkProps = Omit<LinkProps, \"style\" | \"className\"> & {\n  style?: LinkStyle;\n  className?: LinkClassName;\n};\n\nexport const NavLink = (p: NavLinkProps) => {\n  let { style, className, to, ...rest } = useProps(p);\n  let { matches } = useContext(RouteContext);\n  let targetPath = use(uTargetPath(() => ({ to })));\n\n  let isActive = use(() => !!matches.find((i) => i.pathname === targetPath));\n\n  return () => (\n    <Link\n      {...rest}\n      to={to}\n      style={style?.(isActive)}\n      className={className?.(isActive)}\n    />\n  );\n};\n"
  },
  {
    "path": "packages/unis-router/src/components/Outlet.tsx",
    "content": "import { use, useContext } from \"@unis/core\";\nimport { RouteContext } from \"../context\";\n\nexport const Outlet = () => {\n  let { matches, route } = useContext(RouteContext);\n\n  let nextRoute = use(() => matches[matches.findIndex((i) => i === route) + 1]);\n\n  let { element, ...rest } = use(() => route ?? {});\n\n  return () =>\n    route ? (\n      <RouteContext.Provider value={{ route: nextRoute ?? rest, matches }}>\n        {element}\n      </RouteContext.Provider>\n    ) : null;\n};\n"
  },
  {
    "path": "packages/unis-router/src/components/Redirect.tsx",
    "content": "import { useContext, useEffect, useProps } from \"@unis/core\";\nimport { RouteContext, RouterContext } from \"../context\";\nimport { resolvePath } from \"../utils\";\n\nexport interface RedirectProps {\n  to?: string;\n  replace?: boolean;\n}\n\nexport const Redirect = (p: RedirectProps) => {\n  let { to, replace = true } = useProps(p);\n  let { history } = useContext(RouterContext);\n  let { route } = useContext(RouteContext);\n  useEffect(\n    () => {\n      if (route) {\n        const pathname = resolvePath(route.pathname!, to ?? \"\");\n        replace ? history.replace(pathname) : history.push(pathname);\n      }\n    },\n    () => []\n  );\n  return () => null;\n};\n"
  },
  {
    "path": "packages/unis-router/src/components/Route.tsx",
    "content": "import { RouteData } from \"../types\";\n\nexport type RouteProps = Omit<RouteData, \"children\"> & {\n  children?: JSX.Element | JSX.Element[];\n};\n\nexport const Route = (p: RouteProps) => null;\n"
  },
  {
    "path": "packages/unis-router/src/components/Routes.tsx",
    "content": "import { cloneElement, FiberNode, use, useProps } from \"@unis/core\";\nimport { uRouter } from \"../hooks/uRouter\";\nimport { Route } from \"./Route\";\nimport { RouteData } from \"../types\";\n\nexport type RoutesProps = Omit<RouteData, \"children\"> & {\n  children?: JSX.Element | JSX.Element[];\n};\n\nexport const Routes = (p: RoutesProps) => {\n  let { children, path, element: incomeElement } = useProps(p);\n\n  let realChildren = use(() => flatChildren(children));\n  let routes = use(() => realChildren.map((node) => pick(node)));\n  let element = use(\n    uRouter(() => [\n      {\n        path,\n        element: incomeElement,\n        children: routes,\n      } as RouteData,\n    ])\n  );\n\n  function pick(node: FiberNode): RouteData {\n    return {\n      ...node.props,\n      path: node.props.path,\n      element: cloneElement(node.props.element),\n      children: flatChildren(node.props.children).map(pick),\n    };\n  }\n\n  function flatChildren(children: JSX.Element | JSX.Element[]) {\n    return ([] as FiberNode[])\n      .concat(children as FiberNode[])\n      .filter((child) => child?.tag === Route);\n  }\n\n  return () => element;\n};\n"
  },
  {
    "path": "packages/unis-router/src/context.tsx",
    "content": "import { createContext } from \"@unis/core\";\nimport { BrowserHistory, Location } from \"history\";\nimport { MatchRoute } from \"./types\";\n\nexport interface RouteContextValue {\n  route: MatchRoute;\n  matches: MatchRoute[];\n}\n\nexport const RouteContext = createContext<RouteContextValue>({\n  route: undefined!,\n  matches: [],\n});\n\nexport interface RouterContextValue {\n  history: BrowserHistory;\n  basename: string;\n}\n\nexport const RouterContext = createContext<RouterContextValue>(undefined!);\n\nexport interface LocationContextValue {\n  location: Location;\n}\n\nexport const LocationContext = createContext<LocationContextValue>(undefined!);\n"
  },
  {
    "path": "packages/unis-router/src/hooks/uHistory.ts",
    "content": "import { useContext } from \"@unis/core\";\nimport { RouterContext } from \"../context\";\n\nexport const uHistory = () => {\n  let { history } = useContext(RouterContext);\n  return () => history!;\n};\n"
  },
  {
    "path": "packages/unis-router/src/hooks/uLocation.ts",
    "content": "import { use } from \"@unis/core\";\nimport { uHistory } from \"./uHistory\";\n\nexport const uLocation = () => {\n  let { location } = use(uHistory());\n  return () => location;\n};\n"
  },
  {
    "path": "packages/unis-router/src/hooks/uParams.ts",
    "content": "import { useContext } from \"@unis/core\";\nimport { RouteContext } from \"../context\";\n\nexport const uParams = <T = Record<string, any>>() => {\n  let { route } = useContext(RouteContext);\n  return () => route?.params as unknown as T;\n};\n"
  },
  {
    "path": "packages/unis-router/src/hooks/uRouter.tsx",
    "content": "import { use, useContext } from \"@unis/core\";\nimport { RouteContext, RouterContext } from \"../context\";\nimport { Outlet } from \"../components/Outlet\";\nimport { RouteData } from \"../types\";\nimport { matchRoutes } from \"../utils\";\n\nexport const uRouter = (configFn: () => RouteData[]) => {\n  let routerData = use(configFn);\n  let { history, basename } = useContext(RouterContext);\n\n  let location = use(() => history?.location!);\n\n  let wrapedRouterData = use(() => [\n    {\n      path: basename,\n      element: <Outlet />,\n      children: routerData,\n    } as RouteData,\n  ]);\n\n  let matches = use(() => matchRoutes(location.pathname, wrapedRouterData));\n\n  return () => (\n    <RouteContext.Provider value={{ route: matches.at(0)!, matches }}>\n      <Outlet />\n    </RouteContext.Provider>\n  );\n};\n"
  },
  {
    "path": "packages/unis-router/src/hooks/uTargetPath.tsx",
    "content": "import { use, useContext } from \"@unis/core\";\r\nimport { RouteContext } from \"../context\";\r\nimport { resolvePath } from \"../utils\";\r\n\r\nexport interface Options {\r\n  to?: string;\r\n}\r\n\r\nexport const uTargetPath = (opts: () => Options) => {\r\n  let { to } = use(opts);\r\n  let { route } = useContext(RouteContext);\r\n\r\n  let targetPath = use(() => resolvePath(route.pathname ?? \"\", to ?? \"\"));\r\n\r\n  return () => targetPath;\r\n};\r\n"
  },
  {
    "path": "packages/unis-router/src/index.ts",
    "content": "export * from \"./components/BrowserRouter\";\nexport * from \"./context\";\nexport * from \"./components/Routes\";\nexport * from \"./components/Route\";\nexport * from \"./components/Outlet\";\nexport * from \"./components/Link\";\nexport * from \"./components/NavLink\";\nexport * from \"./components/Redirect\";\nexport * from \"./hooks/uHistory\";\nexport * from \"./hooks/uRouter\";\nexport * from \"./hooks/uLocation\";\nexport * from \"./hooks/uHistory\";\nexport * from \"./hooks/uParams\";\n"
  },
  {
    "path": "packages/unis-router/src/types.ts",
    "content": "export interface RouteData {\n  path?: string;\n  element?: JSX.Element;\n  children?: RouteData[];\n}\n\nexport interface MatchRoute extends RouteData {\n  pathname?: string;\n  params?: Record<string, string>;\n}\n"
  },
  {
    "path": "packages/unis-router/src/utils.test.tsx",
    "content": "import { expect, it } from \"vitest\";\nimport { RouteData } from \"./types\";\nimport { matchRoutes, resolvePath } from \"./utils\";\n\nconst getRoutes = (): RouteData[] => [\n  {\n    path: \"/\",\n    children: [\n      {\n        path: \"home/:from/\",\n        children: [\n          { path: \"*\" },\n          {\n            path: \"post/:id\",\n          },\n          {\n            path: \"post/1\",\n            children: [\n              {\n                children: [{ path: \"xx\" }],\n              },\n            ],\n          },\n        ],\n      },\n    ],\n  },\n];\n\nit(\"root match\", () => {\n  const matchedRoutes = matchRoutes(\"/home/www\", getRoutes());\n  expect(matchedRoutes).toMatchObject([\n    { path: \"/\", params: {}, pathname: \"/\" },\n    {\n      path: \"home/:from/\",\n      params: { from: \"www\" },\n      pathname: \"/home/www\",\n    },\n  ]);\n});\n\nit(\"match test1\", () => {\n  const matchedRoutes = matchRoutes(\"/home/www/post\", getRoutes());\n  expect(matchedRoutes).toMatchObject([\n    { path: \"/\", params: {}, pathname: \"/\" },\n    {\n      path: \"home/:from/\",\n      params: { from: \"www\" },\n      pathname: \"/home/www\",\n    },\n    { path: \"*\", params: { from: \"www\" }, pathname: \"/home/www/post\" },\n  ]);\n});\n\nit(\"match test2\", () => {\n  const matchedRoutes = matchRoutes(\"/home/www/post/1\", getRoutes());\n  expect(matchedRoutes).toMatchObject([\n    { path: \"/\", params: {}, pathname: \"/\" },\n    {\n      path: \"home/:from/\",\n      params: { from: \"www\" },\n      pathname: \"/home/www\",\n    },\n    {\n      path: \"post/1\",\n      params: { from: \"www\" },\n      pathname: \"/home/www/post/1\",\n    },\n    { params: { from: \"www\" }, pathname: \"/home/www/post/1\" },\n  ]);\n});\n\nit(\"match test3\", () => {\n  const matchedRoutes = matchRoutes(\"/home/www/post/2\", getRoutes());\n  expect(matchedRoutes).toMatchObject([\n    { path: \"/\", params: {}, pathname: \"/\" },\n    {\n      path: \"home/:from/\",\n      params: { from: \"www\" },\n      pathname: \"/home/www\",\n    },\n    {\n      path: \"post/:id\",\n      params: { from: \"www\", id: \"2\" },\n      pathname: \"/home/www/post/2\",\n    },\n  ]);\n});\n\nit(\"match test4\", () => {\n  const matchedRoutes = matchRoutes(\"/home/www/post/1/x\", getRoutes());\n  expect(matchedRoutes).toMatchObject([\n    { path: \"/\", params: {}, pathname: \"/\" },\n    {\n      path: \"home/:from/\",\n      params: { from: \"www\" },\n      pathname: \"/home/www\",\n    },\n    {\n      path: \"*\",\n      params: { from: \"www\" },\n      pathname: \"/home/www/post/1/x\",\n    },\n  ]);\n});\n\nit(\"match test5\", () => {\n  const matchedRoutes = matchRoutes(\"/home/www/post/1/xx\", getRoutes());\n  expect(matchedRoutes).toMatchObject([\n    { path: \"/\", params: {}, pathname: \"/\" },\n    {\n      path: \"home/:from/\",\n      params: { from: \"www\" },\n      pathname: \"/home/www\",\n    },\n    {\n      path: \"post/1\",\n      params: { from: \"www\" },\n      pathname: \"/home/www/post/1\",\n    },\n    {\n      params: { from: \"www\" },\n      pathname: \"/home/www/post/1\",\n    },\n    {\n      path: \"xx\",\n      params: { from: \"www\" },\n      pathname: \"/home/www/post/1/xx\",\n    },\n  ]);\n});\n\nit(\"match test6\", () => {\n  const matchedRoutes = matchRoutes(\"/app/home/www/post/1/x\", getRoutes(), [\n    { path: \"/app\" },\n  ]);\n  expect(matchedRoutes).toMatchObject([\n    { path: \"/app\", params: {}, pathname: \"/app\" },\n    { path: \"/\", params: {}, pathname: \"/app\" },\n    {\n      path: \"home/:from/\",\n      params: { from: \"www\" },\n      pathname: \"/app/home/www\",\n    },\n    {\n      path: \"*\",\n      params: { from: \"www\" },\n      pathname: \"/app/home/www/post/1/x\",\n    },\n  ]);\n});\n\nit(\"resolvePath\", () => {\n  const path = resolvePath(\"/home/c\", \"../a\");\n  expect(path).toBe(\"/a\");\n  const path2 = resolvePath(\"/home/c\", \"./a\");\n  expect(path2).toBe(\"/home/a\");\n  const path3 = resolvePath(\"/home/c\", \"/a\");\n  expect(path3).toBe(\"/a\");\n});\n"
  },
  {
    "path": "packages/unis-router/src/utils.ts",
    "content": "import { MatchRoute, RouteData } from \"./types\";\n\nconst SLASH = \"/\";\nconst DOT = \".\";\n\nconst trimSlash = (str: string) => {\n  const reg = new RegExp(`^[${SLASH}${DOT}]*`);\n  const reg2 = new RegExp(`[${SLASH}${DOT}]*$`);\n  return str.replace(reg, \"\").replace(reg2, \"\");\n};\n\nconst split = (path: string) =>\n  trimSlash(path) ? trimSlash(path).split(SLASH) : [];\n\nconst analysePath = (locationPathname: string, routePath: string) => {\n  const locationChunks = split(locationPathname);\n  const routeChunks = split(routePath);\n\n  const params: Record<string, any> = {};\n\n  for (let i = 0; i < routeChunks.length; i++) {\n    const routeChunk = routeChunks[i];\n    if (routeChunk.startsWith(\":\")) {\n      params[routeChunk.slice(1)] = locationChunks[i];\n    }\n  }\n\n  return {\n    params,\n    pathname:\n      SLASH +\n      (locationChunks\n        .slice(\n          0,\n          routeChunks?.at(-1) === \"*\" ? undefined : routeChunks?.length ?? 0\n        )\n        .join(SLASH) ?? \"\"),\n  };\n};\n\nconst testPath = (\n  locationPathname: string,\n  routePath: string,\n  final = false\n) => {\n  const locationChunks = split(locationPathname);\n  const routeChunks = split(routePath);\n\n  for (let i = 0; i < routeChunks.length; i++) {\n    const routeChunk = routeChunks[i]!;\n    const locationChunk = locationChunks[i];\n\n    if (\n      !locationChunk ||\n      (!routeChunk.startsWith(\":\") &&\n        routeChunk !== \"*\" &&\n        routeChunk !== locationChunk)\n    ) {\n      return false;\n    }\n  }\n\n  if (final && locationChunks.length > routeChunks.length) {\n    return routeChunks.at(-1) === \"*\";\n  }\n\n  return true;\n};\n\nconst getScore = (locationPathname: string, routeChain: RouteData[]) => {\n  const routePath = resolveRoutesPath(routeChain);\n  const locationChunks = split(locationPathname);\n  const routeChunks = split(routePath);\n  let score = 0;\n\n  routeChunks.forEach((chunk, index) => {\n    let base = 10 ^ ((locationChunks.length ?? 0) - index);\n    if (chunk === \"*\") score += 1 * base;\n    if (chunk.startsWith(\":\")) score += 2 * base;\n    if (chunk === locationChunks[index]) score += 3 * base;\n  });\n  return score;\n};\n\nconst resolveRoutesPath = (routes: RouteData[]) =>\n  routes.reduce((pre, cur) => {\n    const path = trimSlash(cur.path ?? \"\");\n    return `${pre}${path ? SLASH + path : \"\"}`;\n  }, \"\") || \"/\";\n\nconst isLocationEnd = (locationPathname: string, routePath: string) => {\n  return split(locationPathname).length === split(routePath).length;\n};\n\nconst matchRoute = (\n  locationPathname: string,\n  route: RouteData,\n  parentRouteChain: RouteData[] = []\n) => {\n  const routeStack: RouteData[] = parentRouteChain;\n  let matchedRouteChains: RouteData[][] = [];\n\n  const walk = (route: RouteData) => {\n    const routeChain = [...routeStack, route];\n    const routePath = resolveRoutesPath(routeChain);\n    const isEnd = (route.children?.length ?? 0) === 0;\n    const result = testPath(locationPathname, routePath, isEnd);\n\n    if (result) {\n      if (isEnd) {\n        matchedRouteChains.push(routeChain);\n      } else {\n        const preChainSize = matchedRouteChains.length;\n        route.children?.forEach((childRoute) => {\n          routeStack.push(route);\n          walk(childRoute);\n          routeStack.pop();\n        });\n        const afterChainSize = matchedRouteChains.length;\n        if (\n          afterChainSize === preChainSize &&\n          isLocationEnd(locationPathname, routePath)\n        ) {\n          matchedRouteChains.push(routeChain);\n        }\n      }\n    }\n  };\n\n  walk(route);\n\n  return matchedRouteChains;\n};\n\nexport const matchRoutes = (\n  locationPathname: string,\n  routes: RouteData[],\n  parentRouteChain: RouteData[] = []\n) => {\n  const matchedRouteChains: RouteData[][] = [];\n  routes.forEach((route) => {\n    matchedRouteChains.push(\n      ...matchRoute(locationPathname, route, parentRouteChain)\n    );\n  });\n  matchedRouteChains.sort((a, b) => {\n    const result =\n      getScore(locationPathname, b) - getScore(locationPathname, a);\n    if (result !== 0) return result;\n    return b.length - a.length;\n  });\n  const finalChain = matchedRouteChains.at(0) ?? [];\n  if (finalChain) {\n    finalChain.forEach((route, index) => {\n      const subChain = finalChain.slice(0, index + 1);\n      const { params, pathname } = analysePath(\n        locationPathname,\n        resolveRoutesPath(subChain)\n      );\n      (route as MatchRoute).params = params;\n      (route as MatchRoute).pathname = pathname;\n    });\n  }\n  return finalChain;\n};\n\nexport const resolvePath = (from: string, to: string) =>\n  new URL(to, `http://x${from}`).pathname;\n"
  },
  {
    "path": "packages/unis-router/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"build\"\n  },\n  \"include\": [\"src\"]\n}"
  },
  {
    "path": "packages/unis-router/vitest.config.ts",
    "content": "import { defineConfig } from \"vitest/config\";\nimport { unisPreset } from \"@unis/vite-preset\";\n\nexport default defineConfig({\n  plugins: [unisPreset()],\n  test: {\n    include: [\"**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}\"],\n    coverage: {\n      reporter: [\"text\", \"json\", \"html\"],\n    },\n  },\n});\n"
  },
  {
    "path": "packages/unis-transition/.gitignore",
    "content": "build/\ndist/"
  },
  {
    "path": "packages/unis-transition/README.md",
    "content": "# Unis Transition\n\nTransition component for unis inspired by  `React Transition Group`.\n\n## Install\n\n```shell\nnpm i @unis/transition\n```\n\n## Usage\n\n```javascript\nimport { useState } from '@unis/unis';\nimport { CSSTransition, TransitionGroup } from '@unis/transition'\n\nconst App = () => {\n  let [visible, setVisible] = useState(false);\n\n  const handleToggle = () => {\n    setVisible(!visible);\n  }\n\n  return () => (\n    <Fragment>\n      <button onClick={handleToggle}>toggle</button>\n      <CSSTransition in={visible} timeout={400} classNames=\"fade\">\n        <div>\n          hello\n        </div>\n      </CSSTransition>\n    </Fragment>\n  )\n}\n```\n\n```css\n.fade-appear {\n  opacity: 0;\n}\n\n.fade-appear-active {\n  opacity: 1;\n  transition: all 0.4s ease;\n}\n\n.fade-appear-done {\n  opacity: 1;\n}\n\n.fade-enter {\n  opacity: 0;\n}\n\n.fade-enter-active {\n  opacity: 1;\n  transition: all 0.4s ease;\n}\n\n.fade-enter-done {\n  opacity: 1;\n}\n\n.fade-exit {\n  opacity: 1;\n}\n\n.fade-exit-active {\n  opacity: 0;\n  transition: all 0.4s ease;\n}\n\n.fade-exit-done {\n  opacity: 0;\n}\n```\n\nOnline [demo](https://stackblitz.com/edit/vitejs-vite-4cfy2b) here\n\n## CSSTransition\n\nComponent API as close to `React Transition Group` as possible.\n\n### in\n\nShow the component.\n\ntype: `boolean`\ndefault: `false`\n\n### mountOnEnter\n\nBy default the child component is mounted on the first `in={true}`. you can set `mountOnEnter={false}` child component will be mounted immediately with parent component.\n\ntype: `boolean`\ndefault: `true`\n\n### unmountOnExit\n\nBy default the child component is unmounted after it finishes exiting. you can set `unmountOnExit={false}` child component stays mounted after it reaches the 'exited' state.\n\ntype: `boolean`\ndefault: `true`\n\n### classNames\n\ntype:\n\n```typescript\nstring | {\n  appear?: string,\n  appearActive?: string,\n  appearDone?: string,\n  enter?: string,\n  enterActive?: string,\n  enterDone?: string,\n  exit?: string,\n  exitActive?: string,\n  exitDone?: string,\n}\n```\n\ndefault: `''`\n\nfor example `classNames=\"fade\"` it will apply classes below\n\n- `fade-appear`, `fade-appear-active`, `fade-appear-done`\n- `fade-enter`, `fade-enter-active`, `fade-enter-done`\n- `fade-exit`, `fade-exit-active`, `fade-exit-done`\n\n### onEnter\n\nCallback fired immediately after the 'enter' or 'appear' class is applied.\n\ntype: `Function(node: HtmlElement)`\n\n### onEntering\n\nCallback fired immediately after the 'enter-active' or 'appear-active' class is applied.\n\ntype: `Function(node: HtmlElement)`\n\n### onEntered\n\nCallback fired immediately after the 'enter' or 'appear' classes are removed and the done class is added to the DOM node.\n\ntype: `Function(node: HtmlElement)`\n\n### onExit\n\nCallback fired immediately after the 'exit' class is applied.\n\ntype: `Function(node: HtmlElement)`\n\n### onExiting\n\nCallback fired immediately after the 'exit-active' is applied.\n\ntype: `Function(node: HtmlElement)`\n\n### onExited\n\nCallback fired immediately after the 'exit' classes are removed and the exit-done class is added to the DOM node.\n\ntype: `Function(node?: HtmlElement)`\n\n## TransitionGroup\n\nEasy to use, just wrap on `CSSTransition` with key.\n\n```javascript\n<TransitionGroup>\n  {list.map((item, index) => (\n    <CSSTransition key={item.id} timeout={400} classNames=\"fade\">\n      <div>{item.name}</div>\n    </CSSTransition>\n  ))}\n</TransitionGroup>\n```\n\n"
  },
  {
    "path": "packages/unis-transition/package.json",
    "content": "{\n  \"name\": \"@unis/transition\",\n  \"version\": \"0.1.0\",\n  \"description\": \"Unis transition component\",\n  \"main\": \"dist/index.js\",\n  \"module\": \"dist/index.mjs\",\n  \"types\": \"dist/index.d.ts\",\n  \"typings\": \"dist/index.d.ts\",\n  \"scripts\": {\n    \"build\": \"rimraf build && rimraf dist && tsc -p tsconfig.json && rollup --config\",\n    \"build:dev\": \"cross-env NODE_ENV=development pnpm build\"\n  },\n  \"exports\": {\n    \".\": {\n      \"require\": \"./dist/index.js\",\n      \"import\": \"./dist/index.mjs\"\n    }\n  },\n  \"keywords\": [\n    \"transition\",\n    \"animation\",\n    \"unis\"\n  ],\n  \"files\": [\n    \"dist\"\n  ],\n  \"author\": \"anuoua\",\n  \"peerDependencies\": {\n    \"@unis/core\": \"workspace:^\"\n  },\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/anuoua/unis/issues\"\n  },\n  \"homepage\": \"https://github.com/anuoua/unis/tree/main/packages/unis-transition\",\n  \"devDependencies\": {\n    \"@rollup/plugin-node-resolve\": \"^15.0.2\",\n    \"@unis/core\": \"workspace:^\",\n    \"cross-env\": \"^7.0.3\",\n    \"esbuild\": \"^0.17.15\",\n    \"rimraf\": \"^4.4.1\",\n    \"rollup\": \"^3.20.2\",\n    \"rollup-plugin-dts\": \"^5.3.0\",\n    \"rollup-plugin-esbuild\": \"^5.0.0\",\n    \"rollup-plugin-reassign\": \"^1.0.3\",\n    \"typescript\": \"^5.0.3\"\n  }\n}\n"
  },
  {
    "path": "packages/unis-transition/rollup.config.mjs",
    "content": "import dts from \"rollup-plugin-dts\";\nimport esbuild from \"rollup-plugin-esbuild\";\nimport { defineConfig } from \"rollup\";\nimport { nodeResolve } from \"@rollup/plugin-node-resolve\";\nimport { reassign } from \"rollup-plugin-reassign\";\nimport { unisFns } from \"@unis/core\";\n\nconst configGen = (format) =>\n  defineConfig({\n    input: \"src/index.ts\",\n    external: [/^@unis/],\n    output: [\n      {\n        dir: \"dist\",\n        entryFileNames: `index.${format === \"esm\" ? \"mjs\" : \"js\"}`,\n        format,\n        sourcemap: true,\n      },\n    ],\n    plugins: [\n      nodeResolve(),\n      esbuild({\n        sourceMap: true,\n        target: \"esnext\",\n        jsx: \"automatic\",\n        jsxImportSource: \"@unis/core\",\n      }),\n      reassign({\n        include: [\"**/*.(t|j)s?(x)\"],\n        targetFns: {\n          \"@unis/core\": unisFns,\n        },\n      }),\n    ],\n  });\n\nconst dtsRollup = () =>\n  defineConfig({\n    input: \"build/index.d.ts\",\n    output: [{ file: \"dist/index.d.ts\", format: \"es\" }],\n    plugins: [dts()],\n  });\n\nconst config = [configGen(\"cjs\"), configGen(\"esm\"), dtsRollup()];\n\nexport default config;\n"
  },
  {
    "path": "packages/unis-transition/src/CSSTransition.ts",
    "content": "import { findEls, use, useLayoutEffect, useProps } from \"@unis/core\";\nimport { uInstance } from \"./hooks/uInstance\";\nimport {\n  APPEARED,\n  APPEARING,\n  ENTERED,\n  ENTERING,\n  EXITED,\n  EXITING,\n  TransitionTimeout,\n  uTransition,\n} from \"./hooks/uTransition\";\nimport { uWatch } from \"./hooks/uWatch\";\n\nexport interface TransitionProps {\n  children: JSX.Element;\n  classNames: string;\n  timeout?: TransitionTimeout;\n  in?: boolean;\n  mountOnEnter?: boolean;\n  unmountOnExit?: boolean;\n  appear?: boolean;\n  enter?: boolean;\n  onEnter?: (el: HTMLElement) => void;\n  onEntering?: (el: HTMLElement) => void;\n  onEntered?: (el: HTMLElement) => void;\n  onExit?: (el: HTMLElement) => void;\n  onExiting?: (el: HTMLElement) => void;\n  onExited?: (el?: HTMLElement) => void;\n}\n\nexport const CSSTransition = (p: TransitionProps) => {\n  let {\n    children,\n    timeout,\n    in: inProp,\n    classNames,\n    unmountOnExit,\n    mountOnEnter,\n    appear,\n    enter,\n    onEnter,\n    onEntering,\n    onEntered,\n    onExit,\n    onExiting,\n    onExited,\n  } = useProps(p);\n\n  let [instance] = use(uInstance());\n\n  let { childrenState, status } = use(\n    uTransition(() => ({\n      in: inProp,\n      timeout,\n      enter,\n      unmountOnExit,\n      mountOnEnter,\n      appear,\n    }))\n  );\n\n  let currentChildren = use(() => (childrenState ? children : null));\n\n  let cls = use(() => ({\n    appear: `${classNames}-appear`,\n    appearActive: `${classNames}-appear-active`,\n    appearDone: `${classNames}-appear-done`,\n    enter: `${classNames}-enter`,\n    enterActive: `${classNames}-enter-active`,\n    enterDone: `${classNames}-enter-done`,\n    exit: `${classNames}-exit`,\n    exitActive: `${classNames}-exit-active`,\n    exitDone: `${classNames}-exit-done`,\n  }));\n\n  let el: HTMLElement | undefined;\n\n  const getElement = () => {\n    const els = findEls(instance, true).filter(\n      (el) => el instanceof HTMLElement\n    ) as HTMLElement[];\n    return els[0] as HTMLElement | undefined;\n  };\n\n  const clearAll = () => {\n    if (!el) return;\n    el.classList.remove(\n      cls.appear,\n      cls.appearActive,\n      cls.appearDone,\n      cls.enter,\n      cls.enterActive,\n      cls.enterDone,\n      cls.exit,\n      cls.exitActive,\n      cls.exitDone\n    );\n  };\n\n  const entered = (appear: boolean) => {\n    if (!el) return;\n    clearAll();\n    el.classList.add(appear ? cls.appearDone : cls.enterDone);\n    onEntered?.(el);\n  };\n\n  const exited = () => {\n    if (el) {\n      clearAll();\n      el.classList.add(cls.exitDone);\n    }\n    onExited?.(el);\n  };\n\n  const entering = (reflow = false, apear: boolean) => {\n    if (!el) return;\n\n    clearAll();\n\n    el.classList.add(apear ? cls.appear : cls.enter);\n\n    onEnter?.(el);\n\n    reflow && forceReflow(el);\n\n    clearAll();\n\n    el.classList.add(apear ? cls.appearActive : cls.enterActive);\n\n    onEntering?.(el);\n  };\n\n  const exiting = (reflow = false) => {\n    if (!el) return;\n\n    clearAll();\n\n    el.classList.add(cls.exit);\n\n    onExit?.(el);\n\n    reflow && forceReflow(el);\n\n    clearAll();\n\n    el.classList.add(cls.exitActive);\n\n    onExiting?.(el);\n  };\n\n  useLayoutEffect(\n    () => {\n      el = getElement();\n    },\n    () => [status, inProp]\n  );\n\n  uWatch(\n    (current, previous) => {\n      switch (current) {\n        case APPEARING:\n          entering(previous !== EXITING, true);\n          break;\n        case APPEARED:\n          entered(true);\n          break;\n        case ENTERING:\n          entering(previous !== EXITING, false);\n          break;\n        case EXITING:\n          exiting(previous !== ENTERING);\n          break;\n        case ENTERED:\n          entered(false);\n          break;\n        case EXITED:\n          exited();\n          break;\n      }\n    },\n    () => [status]\n  );\n\n  return () => currentChildren;\n};\n\nconst forceReflow = (el: HTMLElement) => el.scrollTop;\n"
  },
  {
    "path": "packages/unis-transition/src/TransitionGroup.ts",
    "content": "import { FiberNode, use, useEffect, useProps, useState } from \"@unis/core\";\nimport { CSSTransition } from \"./CSSTransition\";\n\nexport interface TransitionGroupProps {\n  children: JSX.Element | JSX.Element[];\n}\n\nexport const TransitionGroup = (p: TransitionGroupProps) => {\n  let { children } = useProps(p);\n\n  let [transitionChildren, setTransitionChildren] = useState<FiberNode[]>([]);\n\n  let flatChildren = use(() =>\n    ([] as FiberNode[])\n      .concat(children as unknown as FiberNode)\n      .filter((child) => child.tag === CSSTransition)\n  );\n\n  let childrenKeys = use(() =>\n    flatChildren.map((child) => child.props.key).join(\",\")\n  );\n\n  const remove = (key: string) => {\n    setTransitionChildren(\n      transitionChildren.filter((child) => child.props.key !== key)\n    );\n  };\n\n  const handleChildren = () => {\n    const flatMap: Record<string, FiberNode> = {};\n    flatChildren.forEach((child) => {\n      flatMap[child.props.key] = child;\n    });\n\n    const transitionMap: Record<string, FiberNode> = {};\n    transitionChildren.forEach((child) => {\n      transitionMap[child.props.key] = child;\n    });\n\n    const newFlatChildren = flatChildren.map((child) => {\n      const existingNode = transitionMap[child.props.key];\n      if (existingNode) return existingNode;\n      const newChild = { ...child };\n      const originProps = newChild.props;\n      const onExited = newChild.props.onExited;\n      newChild.props = {\n        ...originProps,\n        in: true,\n        onExited: (...args: unknown[]) => {\n          onExited?.(...args);\n          remove(originProps.key);\n        },\n      };\n      return newChild;\n    });\n\n    transitionChildren.forEach((child, index) => {\n      const newChild = { ...child };\n      if (!flatMap[newChild.props.key]) {\n        newChild.props = {\n          ...newChild.props,\n          in: false,\n        };\n        newFlatChildren.splice(index, 0, newChild);\n      }\n    });\n\n    setTransitionChildren(newFlatChildren);\n  };\n\n  useEffect(\n    () => {\n      handleChildren();\n    },\n    () => [childrenKeys]\n  );\n\n  return () => transitionChildren;\n};\n"
  },
  {
    "path": "packages/unis-transition/src/hooks/uInstance.ts",
    "content": "import { Fiber, use } from \"@unis/core\";\n\nexport const uInstance = () => {\n  let instance = use((WF: Fiber) => WF);\n  return () => [instance];\n};\n"
  },
  {
    "path": "packages/unis-transition/src/hooks/uTransition.ts",
    "content": "import { use, useEffect, useState } from \"@unis/core\";\n\nexport const UNMOUNTED = \"unmounted\";\nexport const APPEARING = \"appearing\";\nexport const APPEARED = \"appeared\";\nexport const ENTERING = \"entering\";\nexport const ENTERED = \"entered\";\nexport const EXITING = \"exiting\";\nexport const EXITED = \"exited\";\n\nexport type TimeoutObject = {\n  appear?: number;\n  enter?: number;\n  exit?: number;\n};\n\nexport type TransitionTimeout = number | TimeoutObject;\n\nexport interface uTransitionProps {\n  in?: boolean;\n  enter?: boolean;\n  unmountOnExit?: boolean;\n  mountOnEnter?: boolean;\n  appear?: boolean;\n  timeout?: TransitionTimeout;\n}\n\nexport const uTransition = (optsFn: () => uTransitionProps) => {\n  let {\n    in: inProp = false,\n    enter = true,\n    unmountOnExit = true,\n    mountOnEnter = true,\n    timeout = 0,\n    appear = false,\n  } = use(optsFn);\n\n  let timer: number;\n  let mounted = false;\n\n  let realMountOnEnter = use(() => (unmountOnExit ? true : mountOnEnter));\n  let timeoutObject = use(() => {\n    if (typeof timeout === \"number\") {\n      return {\n        appear: timeout,\n        enter: timeout,\n        exit: timeout,\n      } as TimeoutObject;\n    } else {\n      const enter = timeout.enter ?? 0;\n      return {\n        appear: enter,\n        enter,\n        exit: timeout.exit ?? 0,\n      } as TimeoutObject;\n    }\n  });\n\n  let [childrenState, setChildrenState] = useState(\n    !realMountOnEnter ? true : inProp\n  );\n\n  let [initialStatus] = useState(\n    childrenState && appear && inProp\n      ? enter\n        ? APPEARING\n        : ENTERED\n      : UNMOUNTED\n  );\n\n  useEffect(\n    () => {\n      if (childrenState && initialStatus === APPEARING) {\n        setTimer(timeoutObject.appear!);\n      }\n    },\n    () => []\n  );\n\n  let [status, setStatus] = useState(initialStatus);\n\n  const switchChildren = () => {\n    if (status === ENTERING) setStatus(ENTERED);\n    if (status === EXITING) setStatus(EXITED);\n    if (status === APPEARING) setStatus(APPEARED);\n    setChildrenState(inProp ? true : !unmountOnExit);\n  };\n\n  function setTimer(statusTimeout: number) {\n    clearTimeout(timer);\n    timer = setTimeout(() => {\n      switchChildren();\n    }, statusTimeout);\n  }\n\n  useEffect(\n    () => {\n      if (!mounted) {\n        mounted = true;\n        return;\n      }\n      if (inProp) {\n        if (!enter) return setStatus(ENTERED);\n        setStatus(ENTERING);\n        setChildrenState(true);\n        setTimer(timeoutObject.enter!);\n      } else {\n        setStatus(EXITING);\n        setTimer(timeoutObject.exit!);\n      }\n    },\n    () => [inProp]\n  );\n\n  return () => ({\n    childrenState,\n    status,\n  });\n};\n"
  },
  {
    "path": "packages/unis-transition/src/hooks/uUpdate.ts",
    "content": "import { useReducer } from \"@unis/core\";\n\nexport const uUpdate = () => {\n  let [, dispatch] = useReducer((a) => a + 1, 0);\n\n  const update = () => dispatch(undefined);\n\n  return () => [update];\n};\n"
  },
  {
    "path": "packages/unis-transition/src/hooks/uWatch.ts",
    "content": "import { use, useLayoutEffect } from \"@unis/core\";\n\nexport const uWatch = <T extends any>(\n  handler: (currentValue: T, previousValue: T | undefined) => void,\n  depsFn: () => [T]\n) => {\n  let [value] = use(depsFn);\n\n  let preValue: T | undefined = undefined;\n\n  useLayoutEffect(\n    () => {\n      handler(value, preValue);\n      preValue = value;\n    },\n    () => [value]\n  );\n};\n"
  },
  {
    "path": "packages/unis-transition/src/index.ts",
    "content": "export * from \"./CSSTransition\";\nexport * from \"./TransitionGroup\";\nexport * from \"./hooks/uTransition\";\n"
  },
  {
    "path": "packages/unis-transition/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"build\"\n  },\n  \"include\": [\"src\"]\n}"
  },
  {
    "path": "packages/unis-vite-preset/.gitignore",
    "content": "build/"
  },
  {
    "path": "packages/unis-vite-preset/README.md",
    "content": "# Unis Vite Preset\n\nUnis develop preset for vite.\n\n## Install\n\n```shell\nnpm add -D @unis/vite-preset\n```\n\n## Usage\n\nvite.config.js\n\n```javascript\nimport { defineConfig } from \"vite\";\nimport { unisPreset } from '@unis/vite-preset'\n\nexport default defineConfig({\n  plugins: [\n    unisPreset()\n  ]\n});\n```\n\n"
  },
  {
    "path": "packages/unis-vite-preset/package.json",
    "content": "{\n  \"name\": \"@unis/vite-preset\",\n  \"version\": \"0.1.0\",\n  \"description\": \"Unis vite preset\",\n  \"main\": \"build/index.js\",\n  \"module\": \"build/index.mjs\",\n  \"types\": \"build/index.d.ts\",\n  \"typings\": \"build/index.d.ts\",\n  \"scripts\": {\n    \"build\": \"rimraf build && rollup --config && tsc\",\n    \"build:dev\": \"cross-env NODE_ENV=development pnpm build\"\n  },\n  \"exports\": {\n    \".\": {\n      \"require\": \"./build/index.js\",\n      \"import\": \"./build/index.mjs\"\n    }\n  },\n  \"keywords\": [\n    \"vite\",\n    \"preset\",\n    \"unis\"\n  ],\n  \"files\": [\n    \"build\"\n  ],\n  \"author\": \"anuoua\",\n  \"peerDependencies\": {\n    \"@unis/core\": \"workspace:^\",\n    \"vite\": \"^4.2.1\"\n  },\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/anuoua/unis/issues\"\n  },\n  \"homepage\": \"https://github.com/anuoua/unis/tree/main/packages/unis-vite-preset\",\n  \"dependencies\": {\n    \"@callback-reassign/rollup-plugin\": \"^0.0.1\"\n  },\n  \"devDependencies\": {\n    \"@rollup/plugin-node-resolve\": \"^13.0.6\",\n    \"@unis/core\": \"workspace:^\",\n    \"cross-env\": \"^7.0.3\",\n    \"esbuild\": \"^0.13.13\",\n    \"rimraf\": \"^3.0.2\",\n    \"rollup\": \"^2.72.0\",\n    \"rollup-plugin-esbuild\": \"^4.6.0\",\n    \"typescript\": \"^4.4.4\",\n    \"vite\": \"^4.2.1\"\n  }\n}\n"
  },
  {
    "path": "packages/unis-vite-preset/rollup.config.js",
    "content": "import { defineConfig } from \"rollup\";\nimport { nodeResolve } from \"@rollup/plugin-node-resolve\";\nimport esbuild from \"rollup-plugin-esbuild\";\n\nconst configGen = (format) =>\n  defineConfig({\n    input: \"src/index.ts\",\n    external: [/^@unis/, \"@callback-reassign/rollup-plugin\"],\n    output: [\n      {\n        dir: \"build\",\n        entryFileNames: `index.${format === \"esm\" ? \"mjs\" : \"js\"}`,\n        format,\n        sourcemap: true,\n      },\n    ],\n    plugins: [\n      nodeResolve(),\n      esbuild({\n        sourceMap: true,\n        minify: process.env.NODE_ENV === \"development\" ? false : true,\n        target: \"esnext\",\n      }),\n    ],\n  });\n\nconst config = [configGen(\"cjs\"), configGen(\"esm\")];\n\nexport default config;\n"
  },
  {
    "path": "packages/unis-vite-preset/src/index.ts",
    "content": "import type { PluginOption } from \"vite\";\nimport { reassign } from \"@callback-reassign/rollup-plugin\";\nimport { unisFns } from \"@unis/core\";\n\nexport function unisPreset(): PluginOption[] {\n  return [\n    {\n      name: \"unis-preset\",\n\n      enforce: \"pre\",\n\n      config(config) {\n        return {\n          esbuild: {\n            jsx: \"automatic\",\n            jsxImportSource: \"@unis/core\",\n            ...config.esbuild,\n          },\n        };\n      },\n    },\n    reassign({\n      include: [\"**/*.(t|j)s?(x)\"],\n      targetFns: {\n        \"@unis/core\": unisFns,\n      },\n    }) as PluginOption,\n  ];\n}\n"
  },
  {
    "path": "packages/unis-vite-preset/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"emitDeclarationOnly\": true,\n    \"declarationMap\": false,\n    \"outDir\": \"build\"\n  },\n  \"include\": [\"src\"]\n}"
  },
  {
    "path": "pnpm-workspace.yaml",
    "content": "packages:\n  - \"packages/**\"\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ESNext\",\n    \"lib\": [\n      \"DOM\",\n      \"ESNext\"\n    ],\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"@unis/core\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"node\",\n    \"declaration\": true,\n    \"emitDeclarationOnly\": true,\n    \"sourceMap\": true,\n    \"esModuleInterop\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"strict\": true,\n    \"noUnusedLocals\": true,\n    \"skipLibCheck\": false\n  },\n}\n"
  }
]