├── .github └── workflows │ └── publish_gh.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── _components ├── EmojiComponent.jsx ├── EnvironmentReadingComponent.jsx ├── MyComponent.jsx ├── MyNestedComponent.jsx ├── MyStyledComponent.jsx ├── RandomWordsComponent.jsx ├── emojiservice.js ├── fetchingservice.ts └── style.css ├── _environment ├── _extensions └── qreacto │ ├── README.md │ ├── _extension.yml │ ├── babel-presets.js │ ├── babel.min.js │ ├── qreacto.lua │ ├── react-dom.min.js │ └── react.min.js └── example.qmd /.github/workflows/publish_gh.yml: -------------------------------------------------------------------------------- 1 | name: Demo site 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: main 6 | jobs: 7 | build-deploy: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | contents: write 11 | steps: 12 | - name: Check out repository 13 | uses: actions/checkout@v3 14 | 15 | - name: Set up Quarto 16 | uses: quarto-dev/quarto-actions/setup@v2 17 | 18 | - name: 'Create' 19 | env: 20 | QUARTO_PRINT_STACK: true 21 | run: | 22 | quarto create project website . 23 | shell: bash 24 | 25 | - name: Render and Publish 26 | uses: quarto-dev/quarto-actions/publish@v2 27 | with: 28 | target: gh-pages 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.pdf 3 | *_files/ 4 | /.luarc.json 5 | 6 | /.quarto/ 7 | 8 | # For development the following files are ignored 9 | example.html 10 | _quarto.yml 11 | qreacto.qmd 12 | index.qmd 13 | _site/ -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, caste, color, religion, or sexual 11 | identity and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the overall 27 | community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or advances of 32 | any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email address, 36 | without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at [opensource@clearmatics.com](mailto:opensource@clearmatics.com). 64 | 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series of 87 | actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or permanent 94 | ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within the 114 | community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.1, available at 120 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 121 | 122 | Community Impact Guidelines were inspired by 123 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 127 | [https://www.contributor-covenant.org/translations][translations]. 128 | 129 | [homepage]: https://www.contributor-covenant.org 130 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 131 | [Mozilla CoC]: https://github.com/mozilla/diversity 132 | [FAQ]: https://www.contributor-covenant.org/faq 133 | [translations]: https://www.contributor-covenant.org/translations 134 | 135 | 136 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Pull Request Process 9 | 10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a 11 | build. 12 | 2. Update the README.md with details of changes to the interface, this includes new environment 13 | variables, exposed ports, useful file locations and container parameters. 14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this 15 | Pull Request would represent. The versioning scheme we use is [SemVer][semver]. 16 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you 17 | do not have permission to do that, you may request the second reviewer to merge it for you. 18 | 19 | ## Code of Conduct 20 | 21 | This project and everyone participating in it is governed by the [Code of Conduct][codeofconduct]. By participating, you are expected to uphold this code. Please report unacceptable behavior to [opensource@clearmatics.com][email]. 22 | 23 | [codeofconduct]: CODE_OF_CONDUCT.md 24 | [semver]: http://semver.org/ 25 | [email]: mailto:opensource@clearmatics.com 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Clearmatics Technologies Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React components in Quarto 2 | 3 | Run standalone React components in your Quarto project! 4 | 5 | Check out the [demo](https://clearmatics.github.io/qreacto/example.html)! 6 | 7 | ## Installation 8 | 9 | To install this extension in your current directory (or into the Quarto project that you're currently working in), use the following command: 10 | 11 | ``` bash 12 | quarto add clearmatics/qreacto 13 | ``` 14 | 15 | ## Running a React component 16 | 17 | To run a React component, first, create a folder called `_components/` in the root of the project. 18 | Then in that folder, create your component in a .jsx or .tsx file. For example: 19 | 20 | 21 | ``` javascript 22 | /** 23 | * An example of React with fetch 24 | * @returns 25 | */ 26 | function FetchComponent() { 27 | // ... 28 | } 29 | 30 | ``` 31 | 32 | Next, add the shortcode into the .qmd file where you want the component to be displayed: 33 | 34 | ``` bash 35 | {{< react FetchComponent >}} 36 | ``` 37 | 38 | If you are using TypeScript, the extension will automatically detect the file type and use the correct Babel preset. 39 | 40 | However, you can also be explicit: 41 | 42 | ``` bash 43 | {{< react FetchComponent type="typescript" >}} 44 | ``` 45 | 46 | Ensure that the name of the component and the name of the file match for the filter to work correctly. **It is also case sensitive.** 47 | 48 | For example, if the component is named `FetchComponent`, save it in the file `_components/FetchComponent.jsx` for JavaScript or `_components/FetchComponent.tsx` for TypeScript. 49 | 50 | ## Adding thirdparty imports 51 | 52 | You can leverage ES modules and Content Delivery Networks (CDNs) to import third-party packages directly into your react component, without the need for local installations or bundling. CDNs offer several benefits for importing dependencies. 53 | 54 | ``` javascript 55 | import * as math from 'https://esm.run/math'; 56 | 57 | function MyComponent() { 58 | // ... 59 | } 60 | 61 | ``` 62 | 63 | Make sure the third-party package is available as an ES6 module, either from jsdelivr or esm.run (or any other ES6 module CDN). Import and use the package accordingly. 64 | 65 | ## Adding local imports 66 | 67 | You can also import components from the same folder: 68 | 69 | ``` javascript 70 | import ButtonExample from "./ButtonExample"; 71 | 72 | function FetchComponent() { 73 | // ... 74 | } 75 | ``` 76 | 77 | ## Configuring 78 | 79 | In your `_quarto.yml` file, you can configure react to look in a different folder for components and resources: 80 | 81 | ``` yaml 82 | react: 83 | components: _components 84 | resources: _components 85 | ``` 86 | 87 | Currently, components can only be imported from the same folder. If you have a component in a subfolder, you will need to move it to the same folder as the component you are importing it into. 88 | 89 | **Note:** The files should use the same extension as the component you are importing into. For instance, if you are importing into a `.tsx` file, the files you are importing should also be `.tsx` files. 90 | 91 | ## Supporting files and scripts 92 | 93 | JavaScript and CSS files are automatically included in the page. If your component requires a CSS file, include it in the same folder as the component, and it will be included in the page. 94 | 95 | Supported files are currently pulled from the `_components` folder (or the folder you specified in your _quarto.yml file). The accepted extensions include `.css`, `.js`, and `.ts`. 96 | 97 | ## Gotchas 98 | 99 | - Avoid including imports of React in your component, as Babel will already provide this on the window. 100 | - Importing and using some ESM React components can cause the compiler to fail. This can be a bit hit and miss. Some components like [react-google-recaptcha](https://www.npmjs.com/package/react-google-recaptcha) worked fine, but others had compilation issues. Remember, this extension is designed to build small lightweight components to compliment your Quarto project. If you're pulling in lots of outside React components, consider creating a react app instead. 101 | 102 | ## Known issues and tasks still to do 103 | - [ ] Arrow functions are not currently supported. The Babel plugin `transform-arrow-functions` conflicts with the Babel TypeScript preset. This is currently being investigated. 104 | - [ ] Allow deep imports 105 | - [x] infer the file type (and then set the preset) during the lua filter rather than having to specify it in the shortcode (eg don't need to specify `type="typescript"` in the shortcode) 106 | - [ ] Named imports are not currently supported `import { NamedButton } from './Button';` will not work but `import Button from './Button'` will. 107 | - [ ] Typescript types and type casting not working as expected. for example `as unknown as MyType` will throw 108 | 109 | ## Getting started with development 110 | 111 | If you would like to contribute, there's a [readme](https://github.com/clearmatics/qreacto/blob/main/_extensions/qreacto/README.md) in the `_extension/qreacto` folder that explains the codeflow for the qreacto.lua script, its a great place to start. 112 | 113 | To develop the extension, you need to run it in a Quarto project. The quickest way to set up a project is by running the following command in the root directory: 114 | 115 | ``` bash 116 | quarto create project 117 | ``` 118 | 119 | This command will set up a project that allows you to test the functionality. 120 | 121 | React components are to be located in the components/ folder at the root of the project. Some basic examples are already provided. 122 | 123 | The script `qreacto.lua` is the main script that is run when the shortcode is encountered. It is located in the `_extension/qreacto` folder. 124 | 125 | ## Contributing 126 | We welcome contributions from the community to help improve and enhance this project. Whether you want to report a bug, suggest a new feature, or submit code changes, your efforts are highly appreciated. 127 | 128 | ## Reporting Issues 129 | If you encounter any bugs, glitches, or unexpected behaviour while using this project, please open an issue on the GitHub repository. When reporting issues, please provide as much information as possible, including the steps to reproduce the problem and details about your environment. 130 | 131 | ## Suggesting Enhancements 132 | If you have ideas for new features or improvements, feel free to create an enhancement request in the GitHub repository. We value creative ideas that can add value to the project and its users. 133 | 134 | ## Code Contributions 135 | We encourage contributions from developers of all skill levels. If you want to contribute code changes, please follow our [Contributing](CONTRIBUTING.md) guidelines. 136 | 137 | ## Code of Conduct 138 | Please note that we adhere to a Code of Conduct in this project. All contributors are expected to follow these guidelines to ensure a friendly, inclusive, and respectful environment for everyone. 139 | 140 | By contributing to this project, you agree to abide by the Code of Conduct, which can be found in the repository's [Code of Conduct](CODE_OF_CONDUCT.md) file. 141 | 142 | ## Getting Help 143 | If you need help or have questions about contributing, feel free to reach out to us by creating an issue or joining our community channels. We are more than happy to assist you throughout the process. 144 | 145 | Thank you for your interest in contributing to this project! Your contributions play a vital role in making this project better for the community. We look forward to your involvement and collaboration. Happy contributing! 146 | -------------------------------------------------------------------------------- /_components/EmojiComponent.jsx: -------------------------------------------------------------------------------- 1 | import './style.css'; 2 | import getRandomEmoji from './emojiservice'; 3 | function EmojiComponent() { 4 | const [text, setText] = React.useState([getRandomEmoji()]) 5 | return ( 6 |
setText((previous) => [...previous, getRandomEmoji()])}> 7 |
8 | {text.map(value => {value})} 9 |
10 |
11 | ); 12 | } 13 | 14 | export default EmojiComponent -------------------------------------------------------------------------------- /_components/EnvironmentReadingComponent.jsx: -------------------------------------------------------------------------------- 1 | import "./style.css"; 2 | import * as randomWords from "https://cdn.jsdelivr.net/npm/random-words/+esm"; 3 | function EnvironmentReadingComponent() { 4 | const [text, setText] = React.useState([ 5 | randomWords.generate({ maxLength: 8 }), 6 | ]); 7 | return ( 8 |
10 | setText((previous) => [ 11 | ...previous, 12 | randomWords.generate({ maxLength: 8 }), 13 | ]) 14 | } 15 | > 16 |
17 | {text.map((value) => ( 18 | {value} 19 | ))} 20 |
21 |
Environment variables: {process.env.QREACTO_FOO}
22 |
Environment variables: {process.env.QREACTO_TEST}
23 |
24 | ); 25 | } 26 | 27 | export default EnvironmentReadingComponent; 28 | -------------------------------------------------------------------------------- /_components/MyComponent.jsx: -------------------------------------------------------------------------------- 1 | function MyComponent() { 2 | const [text, setText] = React.useState(['Click me']) 3 | return ( 4 |
setText((previous) => [previous, ...[' and me']])}> 5 |

{text.map(value => {value})}

6 |
7 | ); 8 | } 9 | 10 | export default MyComponent -------------------------------------------------------------------------------- /_components/MyNestedComponent.jsx: -------------------------------------------------------------------------------- 1 | import RandomWordsComponent from "./RandomWordsComponent"; 2 | import EmojiComponent from "./EmojiComponent"; 3 | 4 | function MyNestedComponent() { 5 | return ( 6 |
7 | 8 | 9 |
10 | ); 11 | } 12 | 13 | export default MyNestedComponent -------------------------------------------------------------------------------- /_components/MyStyledComponent.jsx: -------------------------------------------------------------------------------- 1 | import './style.css'; 2 | function MyStyledComponent() { 3 | const [text, setText] = React.useState([]) 4 | return ( 5 |
setText((previous) => [...previous, ' and this one'])}> 6 |
7 | Click this one 8 | {text.map(value => {value})} 9 |
10 |
11 | ); 12 | } 13 | 14 | export default MyStyledComponent -------------------------------------------------------------------------------- /_components/RandomWordsComponent.jsx: -------------------------------------------------------------------------------- 1 | import './style.css'; 2 | import * as randomWords from 'https://cdn.jsdelivr.net/npm/random-words/+esm'; 3 | function RandomWordsComponent() { 4 | const [text, setText] = React.useState([randomWords.generate({ maxLength: 8 })]) 5 | return ( 6 |
setText((previous) => [...previous, randomWords.generate({ maxLength: 8 })])}> 7 |
8 | {text.map(value => {value})} 9 |
10 |
11 | ); 12 | } 13 | 14 | export default RandomWordsComponent -------------------------------------------------------------------------------- /_components/emojiservice.js: -------------------------------------------------------------------------------- 1 | function getRandomEmoji() { 2 | const emojis = ["😀", "😁", "😂", "🤣", "😃", "😄", "😅", "😆", "😉", "😊", "😋", "😎", "😍", "😘", "🥰", "😗", "😙", "😚", "🙂", "🤗", "🤩", "🤔", "🤨", "😐", "😑", "😶", "🙄", "😏", "😣", "😥", "😮", "🤐", "😯", "😪", "😫", "😴", "😌", "😛", "😜", "😝", "🤤", "😒", "😓", "😔", "😕", "🙃", "🤑", "😲", "🙁", "😖", "😞", "😟", "😤", "😢", "😭", "😦", "😧", "😨", "😩", "🤯", "😬", "😰", "😱", "🥵", "🥶", "😳", "🤪", "😵", "😡", "😠", "🤬", "😷", "🤒", "🤕", "🤢", "🤮", "🤧", "😇", "🥳", "🥴", "🥺", "🤠", "🤡", "🤥", "🤫", "🤭", "🧐", "🤓", "😈", "👿", "🤖", "🎃", "👏", "🙌", "👍", "👎", "👊", "✊", "🤛", "🤜", "🤚", "👋", "✋", "🖖", "👌", "✌️", "🤞", "🤟", "🤘", "🤙", "💪", "🖕", "✍️", "🙏", "💍", "💄", "💋", "👄", "👅", "👂", "👃", "👣", "👁", "👀", "🧠", "🦷", "🦴", "👦", "👧", "🧒", "👶", "👩", "🧑", "👨"] 3 | return emojis[Math.floor(Math.random() * emojis.length)] 4 | } 5 | 6 | export default getRandomEmoji 7 | 8 | -------------------------------------------------------------------------------- /_components/fetchingservice.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Basic fetch service example 3 | * Notice how this file is a typescript file, but the rest of the project is javascript 4 | */ 5 | function fetchData() { 6 | return fetch(`https://dummyjson.com/products?limit=10`) 7 | .then(response => { 8 | if (!response.ok) { 9 | throw new Error('Network response was not ok'); 10 | } 11 | return response.json(); 12 | }) 13 | .catch(error => { 14 | console.error('Error fetching data:', error); 15 | }); 16 | } 17 | 18 | export default fetchData; -------------------------------------------------------------------------------- /_components/style.css: -------------------------------------------------------------------------------- 1 | .wrapper-for-other-component { 2 | border: 1px solid tomato; 3 | border-radius: 6px; 4 | padding: 80px; 5 | cursor: pointer; 6 | } 7 | 8 | .styled-component-container { 9 | display: flex; 10 | flex-direction: row; 11 | flex-wrap: wrap; 12 | gap: 12px; 13 | } -------------------------------------------------------------------------------- /_environment: -------------------------------------------------------------------------------- 1 | QREACTO_FOO=bar 2 | QREACTO_TEST=Very true -------------------------------------------------------------------------------- /_extensions/qreacto/README.md: -------------------------------------------------------------------------------- 1 | # qreacto.lua 2 | This is the main script that runs when the shortcode is encountered. 3 | 4 | ## Script overview 5 | 6 | It defines various helper functions, they are documented in the script. 7 | 8 | These functions handle the process of reading files, injecting scripts, ensuring dependencies, and more. 9 | 10 | The main entry point of the filter is executed when the filter encounters a react shortcode in the Markdown file. 11 | 12 | The react function first checks if the output format is HTML with JavaScript (html:js), which indicates that it should include React components in the document. If the format is not HTML with JavaScript, it returns pandoc.Null() to exclude the react shortcode from the output. 13 | 14 | If the output format is HTML with JavaScript, it proceeds with the following steps, It: 15 | 16 | 1. Ensures the necessary React, ReactDOM, and Babel dependencies are included in the document. 17 | 18 | 2. Scans the components folder for supporting files (JavaScript and CSS) and injects their content into the document using the raw_add_script function. 19 | 20 | 3. Reads the content of the specified React component file and modifies it to handle local imports recursively using the `modify_with_imports` function. 21 | 22 | 4. Generates a unique componentId to identify the div element where the React component will be rendered. 23 | 24 | 5. Adds the React component to the document by using ReactDOM.render, injecting the component into the div element with the generated componentId. 25 | 26 | 6. It creates a div element with the generated componentId to be included in the document as a placeholder for the React component. 27 | 28 | The modified content with the React components and supporting resources is then included in the final output. -------------------------------------------------------------------------------- /_extensions/qreacto/_extension.yml: -------------------------------------------------------------------------------- 1 | title: Qreacto 2 | author: Jay Martin 3 | version: 0.0.6 4 | quarto-required: ">=1.2.280" 5 | contributes: 6 | shortcodes: 7 | - qreacto.lua 8 | -------------------------------------------------------------------------------- /_extensions/qreacto/babel-presets.js: -------------------------------------------------------------------------------- 1 | // Define a preset 2 | Babel.registerPreset("env-plus", { 3 | presets: [[Babel.availablePresets["env"], { modules: false }]], 4 | }); -------------------------------------------------------------------------------- /_extensions/qreacto/qreacto.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | # MIT License 3 | # 4 | # Copyright (c) Clearmatics Technologies Ltd 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | ]] 24 | 25 | Styles_to_import = {} 26 | 27 | local component_folder = '_components' 28 | local resources_folder = '_components' 29 | local react_component_extensions = { '.jsx', '.tsx', '.js', '.ts' } 30 | 31 | 32 | --[[ 33 | ============================================================================ 34 | Add react dependencies: 35 | react, babel, transpiler and react-dom 36 | ============================================================================ 37 | ]] 38 | 39 | -- include react dependencies 40 | local function ensure_react() 41 | quarto.doc.add_html_dependency({ 42 | name = 'react', 43 | version = '17.0.2', 44 | scripts = { "react.min.js" } 45 | }) 46 | end 47 | 48 | -- include react dom dependencies 49 | local function ensure_react_dom() 50 | quarto.doc.add_html_dependency({ 51 | name = 'react-dom', 52 | version = '17.0.2', 53 | scripts = { "react-dom.min.js" } 54 | }) 55 | end 56 | 57 | -- include babel transpiler (standalone) 58 | local function ensure_babel_transpiler() 59 | quarto.doc.add_html_dependency({ 60 | name = 'babel', 61 | version = '6.26.0', 62 | scripts = { "babel.min.js" } 63 | }) 64 | end 65 | 66 | -- Change babel presets to use imports rather than require (esm) 67 | local function ensure_imports_babel_preset() 68 | quarto.doc.add_html_dependency({ 69 | name = 'babel-presets', 70 | version = '1.0.0', 71 | scripts = { "babel-presets.js" } 72 | }) 73 | end 74 | 75 | --[[ 76 | ============================================================================ 77 | Helper functions: 78 | Handle loading of files, reading of files, and injecting of scripts 79 | ============================================================================ 80 | ]] 81 | 82 | -- Function to check if a table contains a specific element 83 | local function contains(table, element) 84 | for _, value in ipairs(table) do 85 | if value == element then 86 | return true 87 | end 88 | end 89 | return false 90 | end 91 | 92 | -- Function to generate a random string of given length 93 | -- we use this to asign a unique id to the react component and the div to inject the component into 94 | local function randomString(length) 95 | local chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 96 | local str = "" 97 | for i = 1, length do 98 | local randomIndex = math.random(1, #chars) 99 | str = str .. string.sub(chars, randomIndex, randomIndex) 100 | end 101 | return str 102 | end 103 | 104 | -- check if string is empty 105 | local function is_empty(s) 106 | return s == nil or s == '' 107 | end 108 | 109 | -- returns the full file path if it exists 110 | local function tryLoadFile(filename, extensions) 111 | for _, ext in ipairs(extensions) do 112 | local fullFilename = filename .. ext 113 | local file = io.open(fullFilename, "r") 114 | -- print('trying (case-sensitive): ' .. fullFilename) 115 | if file then 116 | file:close() 117 | return fullFilename 118 | end 119 | end 120 | 121 | return nil -- File not found with any of the extensions 122 | end 123 | 124 | -- given content and a type, add it to the document 125 | local function include_text_in_document(content, type) 126 | -- if its js add it to the body 127 | if type == '.js' then 128 | quarto.doc.include_text('after-body', '') 129 | end 130 | 131 | -- if its css add it to the head 132 | if type == '.css' then 133 | quarto.doc.include_text('in-header', '') 134 | end 135 | 136 | -- if its typescript babel transpile it 137 | if type == '.ts' then 138 | quarto.doc.include_text('after-body', 139 | '' 142 | ) 143 | end 144 | end 145 | 146 | -- Read the contents of a file and return it as a string 147 | local function read_file_to_string(filename) 148 | local file = io.open(filename, "r") -- Open the file in read mode 149 | if not file then 150 | print("Error: File not found or unable to open.") 151 | return nil 152 | end 153 | 154 | local content = file:read("*all") -- Read the entire content of the file 155 | file:close() -- Close the file before handling imports (as it can recurse and we -may- end up with multiple open file streams ) 156 | return content 157 | end 158 | 159 | --[[ 160 | ============================================================================ 161 | Content manipulation and react component injection: 162 | Handle imports, exports, injecting nested dependencies, stylesheets 163 | and injecting the component 164 | ============================================================================ 165 | ]] 166 | 167 | -- look for local imports 168 | -- inject the contents of that local import component (js, ts, jsx or tsx) 169 | -- return the content, modified to include the imports 170 | local function modify_with_imports(content) 171 | local imported_content = {} 172 | local modified_content = content 173 | 174 | -- look for import keyword 175 | local import = string.find(content, "import") 176 | 177 | if import then 178 | for line in content:gmatch("[^\r\n]+") do 179 | -- check for css imports 180 | local csslocation = line:match("^%s*import%s+['\"]([^'\"]+%.css)['\"].*$") 181 | if csslocation then 182 | -- normalize location as it could be './' 183 | local normalizedCssLocation = string.gsub(csslocation, './', '') 184 | 185 | -- get the path of the file 186 | local cssPath = quarto.project.directory .. '/' .. resources_folder .. '/' .. normalizedCssLocation 187 | 188 | -- print('local stylesheet found: ' .. cssPath) 189 | 190 | -- add the css file to the list of styles to import if it is not already there 191 | if not contains(Styles_to_import, csslocation) then 192 | table.insert(Styles_to_import, csslocation) 193 | end 194 | 195 | -- remove the import from the content to prevent some browsers trying to fetch local files 196 | modified_content = string.gsub(modified_content, line, '') 197 | end 198 | 199 | -- get the import variable and the location of the file 200 | local importVar, location = line:match("^%s*import%s+([%w_]+)%s+from%s+['\"]([^'\"]+)['\"].*$") 201 | 202 | -- add a local import candidate if the import isn't making a CDN http request 203 | if importVar and location and not string.find(location, 'http') then 204 | -- normalize location as it could be './' 205 | local normalizedLocation = string.gsub(location, './', '') 206 | 207 | -- get the path of the file 208 | local path = quarto.project.directory .. '/' .. component_folder .. '/' .. normalizedLocation 209 | 210 | -- check for nested react components 211 | local scriptFile = tryLoadFile(path, react_component_extensions) 212 | 213 | -- only import if jsx or tsx file exists 214 | if scriptFile then 215 | -- print('local import found: ' .. path) 216 | 217 | -- recursive call to get the content of the import 218 | local importContent = modify_with_imports(read_file_to_string(scriptFile)) 219 | 220 | -- push results to array (as there might be more then one import to handle) 221 | table.insert(imported_content, importContent) 222 | 223 | -- remove the import from the content to prevent some browsers trying to fetch local files 224 | modified_content = string.gsub(modified_content, line, '') 225 | else 226 | error('local import not found: ' .. path) 227 | end 228 | end 229 | end 230 | end 231 | 232 | -- find line with export default and remove the entire line 233 | modified_content = string.gsub(modified_content, "export default[^\r\n]*\r?\n?", '') 234 | 235 | -- find line with export and remove it 236 | local export = string.find(modified_content, "export") 237 | if export then 238 | modified_content = string.gsub(modified_content, "export", '') 239 | end 240 | 241 | -- concat the array of import content with the modified content (the content without the imports) 242 | -- return it 243 | return table.concat(imported_content, "\n") .. modified_content 244 | end 245 | 246 | -- includes reactDOM.render into the document, with provided component name and element id 247 | -- inject the component into the script tag 248 | local function add_react_element(ComponentName, elementId) 249 | print(ComponentName .. " > " .. elementId) 250 | local path = quarto.project.directory .. '/' .. component_folder .. '/' .. ComponentName 251 | 252 | local foundFile = tryLoadFile(path, react_component_extensions) 253 | -- default presets env-plus is needed for imports to work with esms 254 | -- react is required because... React 255 | local presets = 'env-plus,react,typescript' 256 | 257 | if not foundFile then 258 | error("react: component not found: " .. path) 259 | end 260 | local content = read_file_to_string(foundFile) 261 | quarto.doc.include_text('after-body', 262 | '' 271 | ) 272 | end 273 | 274 | -- add css files to the document 275 | local function inject_imported_stylesheets() 276 | local path = quarto.project.directory .. '/' .. resources_folder 277 | 278 | -- loop over the styles_to_import array 279 | for _, filename in ipairs(Styles_to_import) do 280 | -- print('injecting stylesheet: ' .. filename) 281 | local content = read_file_to_string(path .. '/' .. filename) 282 | return include_text_in_document(content, '.css') 283 | end 284 | end 285 | 286 | local function trimString(content) 287 | return content:gsub("^%s*(.-)%s*$", "%1") 288 | end 289 | 290 | -- Function to convert Pandoc Inlines to plain string 291 | local function inlines_to_string(inlines) 292 | local buffer = {} 293 | for _, inline in ipairs(inlines) do 294 | if inline.t == "Str" then 295 | table.insert(buffer, inline.text) 296 | end 297 | end 298 | return table.concat(buffer) 299 | end 300 | 301 | -- sets the configuration for the react component folder and resources folder 302 | local function set_configuration(reactSettings) 303 | local resourcesPath = reactSettings and inlines_to_string(reactSettings["resources"]) 304 | local componentsPath = reactSettings and inlines_to_string(reactSettings["components"]) 305 | if resourcesPath then 306 | print('setting resources path..') 307 | resources_folder = trimString(resourcesPath) 308 | end 309 | 310 | if componentsPath then 311 | print('setting components path..') 312 | component_folder = trimString(componentsPath) 313 | end 314 | end 315 | 316 | --[[ 317 | checks for existance of Quarto environment file and then creates a global object from it 318 | only inject variables that begin with "QREACTO_" 319 | Accessible from react with process.env.QREACTO_VARIABLE_NAME 320 | see Quarto for details on how to implement environment variables https://quarto.org/docs/projects/environment.html 321 | ]]-- 322 | local function get_environment_variables() 323 | 324 | -- load environment variables from _environment if it exists 325 | local env = quarto.project.directory .. '/_environment' 326 | local envFile = io.open(env, "r") -- Open the file in read mode 327 | -- check if it exists 328 | if envFile then 329 | local envContent = envFile:read("*all") 330 | envFile:close() 331 | 332 | local envVars = {} 333 | for line in envContent:gmatch("[^\r\n]+") do 334 | local key, value = line:match("^([^=]+)=(.*)$") 335 | -- Check if the key starts with 'QREACTO_' 336 | if key and value and key:sub(1, 8) == "QREACTO_" then 337 | table.insert(envVars, '"' .. key .. '":"' .. value .. '"') 338 | end 339 | end 340 | 341 | local envJSON = '{' .. table.concat(envVars, ',') .. '}' 342 | local jsContent = 'window.process = { env: ' .. envJSON .. '};' 343 | quarto.doc.include_text('in-header', '') 344 | end 345 | end 346 | 347 | 348 | --[[ 349 | ============================================================================ 350 | Script entry point 351 | ============================================================================ 352 | ]] 353 | return { 354 | ["react"] = function(args, kwargs, meta) 355 | -- Accessing the `react` object from the metadata (_quarto.yml) 356 | local reactSettings = meta["react"] 357 | if reactSettings then 358 | set_configuration(reactSettings) 359 | end 360 | 361 | if quarto.doc.is_format("html:js") then 362 | -- add dependencies for react 363 | ensure_react() 364 | ensure_react_dom() 365 | ensure_babel_transpiler() 366 | ensure_imports_babel_preset() 367 | get_environment_variables() 368 | 369 | -- setup react component 370 | local componentname = pandoc.utils.stringify(args[1]) 371 | if is_empty(componentname) then 372 | error("react: component name is required") 373 | end 374 | 375 | local componentId = 'react-' .. componentname .. '-' .. randomString(8) 376 | 377 | -- Add the React injection 378 | add_react_element(componentname, componentId) 379 | 380 | -- A list of css files to import will have been created when the component was injected, add these to the document 381 | inject_imported_stylesheets() 382 | 383 | -- Create the div element to place the component in 384 | return pandoc.RawInline( 385 | 'html', 386 | '
' 387 | ) 388 | else 389 | return pandoc.Null() 390 | end 391 | end 392 | } 393 | -------------------------------------------------------------------------------- /_extensions/qreacto/react-dom.min.js: -------------------------------------------------------------------------------- 1 | /** @license React v17.0.2 2 | * react-dom.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | (function(){/* 10 | Modernizr 3.0.0pre (Custom Build) | MIT 11 | */ 12 | 'use strict';(function(M,ha){"object"===typeof exports&&"undefined"!==typeof module?ha(exports,require("react")):"function"===typeof define&&define.amd?define(["exports","react"],ha):(M=M||self,ha(M.ReactDOM={},M.React))})(this,function(M,ha){function m(a){for(var b="https://reactjs.org/docs/error-decoder.html?invariant="+a,c=1;cb}return!1}function Q(a,b,c,d,e,f,g){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f;this.removeEmptyString=g}function Ed(a,b,c,d){var e=I.hasOwnProperty(b)?I[b]:null;var f=null!==e?0===e.type:d?!1:!(2h||e[g]!==f[h])return"\n"+e[g].replace(" at new "," at ");while(1<=g&&0<=h)}break}}}finally{Gd=!1,Error.prepareStackTrace=c}return(a=a?a.displayName||a.name:"")?Kb(a):""}function pi(a){switch(a.tag){case 5:return Kb(a.type);case 16:return Kb("Lazy");case 13:return Kb("Suspense"); 18 | case 19:return Kb("SuspenseList");case 0:case 2:case 15:return a=Bc(a.type,!1),a;case 11:return a=Bc(a.type.render,!1),a;case 22:return a=Bc(a.type._render,!1),a;case 1:return a=Bc(a.type,!0),a;default:return""}}function hb(a){if(null==a)return null;if("function"===typeof a)return a.displayName||a.name||null;if("string"===typeof a)return a;switch(a){case wa:return"Fragment";case Ua:return"Portal";case Lb:return"Profiler";case Hd:return"StrictMode";case Mb:return"Suspense";case Cc:return"SuspenseList"}if("object"=== 19 | typeof a)switch(a.$$typeof){case Id:return(a.displayName||"Context")+".Consumer";case Jd:return(a._context.displayName||"Context")+".Provider";case Dc:var b=a.render;b=b.displayName||b.name||"";return a.displayName||(""!==b?"ForwardRef("+b+")":"ForwardRef");case Ec:return hb(a.type);case Kd:return hb(a._render);case Ld:b=a._payload;a=a._init;try{return hb(a(b))}catch(c){}}return null}function xa(a){switch(typeof a){case "boolean":case "number":case "object":case "string":case "undefined":return a; 20 | default:return""}}function Ef(a){var b=a.type;return(a=a.nodeName)&&"input"===a.toLowerCase()&&("checkbox"===b||"radio"===b)}function qi(a){var b=Ef(a)?"checked":"value",c=Object.getOwnPropertyDescriptor(a.constructor.prototype,b),d=""+a[b];if(!a.hasOwnProperty(b)&&"undefined"!==typeof c&&"function"===typeof c.get&&"function"===typeof c.set){var e=c.get,f=c.set;Object.defineProperty(a,b,{configurable:!0,get:function(){return e.call(this)},set:function(a){d=""+a;f.call(this,a)}});Object.defineProperty(a, 21 | b,{enumerable:c.enumerable});return{getValue:function(){return d},setValue:function(a){d=""+a},stopTracking:function(){a._valueTracker=null;delete a[b]}}}}function Fc(a){a._valueTracker||(a._valueTracker=qi(a))}function Ff(a){if(!a)return!1;var b=a._valueTracker;if(!b)return!0;var c=b.getValue();var d="";a&&(d=Ef(a)?a.checked?"true":"false":a.value);a=d;return a!==c?(b.setValue(a),!0):!1}function Gc(a){a=a||("undefined"!==typeof document?document:void 0);if("undefined"===typeof a)return null;try{return a.activeElement|| 22 | a.body}catch(b){return a.body}}function Md(a,b){var c=b.checked;return B({},b,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=c?c:a._wrapperState.initialChecked})}function Gf(a,b){var c=null==b.defaultValue?"":b.defaultValue,d=null!=b.checked?b.checked:b.defaultChecked;c=xa(null!=b.value?b.value:c);a._wrapperState={initialChecked:d,initialValue:c,controlled:"checkbox"===b.type||"radio"===b.type?null!=b.checked:null!=b.value}}function Hf(a,b){b=b.checked;null!=b&&Ed(a,"checked", 23 | b,!1)}function Nd(a,b){Hf(a,b);var c=xa(b.value),d=b.type;if(null!=c)if("number"===d){if(0===c&&""===a.value||a.value!=c)a.value=""+c}else a.value!==""+c&&(a.value=""+c);else if("submit"===d||"reset"===d){a.removeAttribute("value");return}b.hasOwnProperty("value")?Od(a,b.type,c):b.hasOwnProperty("defaultValue")&&Od(a,b.type,xa(b.defaultValue));null==b.checked&&null!=b.defaultChecked&&(a.defaultChecked=!!b.defaultChecked)}function If(a,b,c){if(b.hasOwnProperty("value")||b.hasOwnProperty("defaultValue")){var d= 24 | b.type;if(!("submit"!==d&&"reset"!==d||void 0!==b.value&&null!==b.value))return;b=""+a._wrapperState.initialValue;c||b===a.value||(a.value=b);a.defaultValue=b}c=a.name;""!==c&&(a.name="");a.defaultChecked=!!a._wrapperState.initialChecked;""!==c&&(a.name=c)}function Od(a,b,c){if("number"!==b||Gc(a.ownerDocument)!==a)null==c?a.defaultValue=""+a._wrapperState.initialValue:a.defaultValue!==""+c&&(a.defaultValue=""+c)}function ri(a){var b="";ha.Children.forEach(a,function(a){null!=a&&(b+=a)});return b} 25 | function Pd(a,b){a=B({children:void 0},b);if(b=ri(b.children))a.children=b;return a}function ib(a,b,c,d){a=a.options;if(b){b={};for(var e=0;e=c.length))throw Error(m(93));c=c[0]}b=c}null==b&&(b="");c=b}a._wrapperState={initialValue:xa(c)}}function Kf(a,b){var c=xa(b.value),d=xa(b.defaultValue);null!=c&&(c=""+c,c!==a.value&&(a.value=c),null==b.defaultValue&&a.defaultValue!== 27 | c&&(a.defaultValue=c));null!=d&&(a.defaultValue=""+d)}function Lf(a,b){b=a.textContent;b===a._wrapperState.initialValue&&""!==b&&null!==b&&(a.value=b)}function Mf(a){switch(a){case "svg":return"http://www.w3.org/2000/svg";case "math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function Rd(a,b){return null==a||"http://www.w3.org/1999/xhtml"===a?Mf(b):"http://www.w3.org/2000/svg"===a&&"foreignObject"===b?"http://www.w3.org/1999/xhtml":a}function Nf(a,b,c){return null== 28 | b||"boolean"===typeof b||""===b?"":c||"number"!==typeof b||0===b||Nb.hasOwnProperty(a)&&Nb[a]?(""+b).trim():b+"px"}function Of(a,b){a=a.style;for(var c in b)if(b.hasOwnProperty(c)){var d=0===c.indexOf("--"),e=Nf(c,b[c],d);"float"===c&&(c="cssFloat");d?a.setProperty(c,e):a[c]=e}}function Sd(a,b){if(b){if(si[a]&&(null!=b.children||null!=b.dangerouslySetInnerHTML))throw Error(m(137,a));if(null!=b.dangerouslySetInnerHTML){if(null!=b.children)throw Error(m(60));if(!("object"===typeof b.dangerouslySetInnerHTML&& 29 | "__html"in b.dangerouslySetInnerHTML))throw Error(m(61));}if(null!=b.style&&"object"!==typeof b.style)throw Error(m(62));}}function Td(a,b){if(-1===a.indexOf("-"))return"string"===typeof b.is;switch(a){case "annotation-xml":case "color-profile":case "font-face":case "font-face-src":case "font-face-uri":case "font-face-format":case "font-face-name":case "missing-glyph":return!1;default:return!0}}function Ud(a){a=a.target||a.srcElement||window;a.correspondingUseElement&&(a=a.correspondingUseElement); 30 | return 3===a.nodeType?a.parentNode:a}function Pf(a){if(a=Ob(a)){if("function"!==typeof Vd)throw Error(m(280));var b=a.stateNode;b&&(b=Hc(b),Vd(a.stateNode,a.type,b))}}function Qf(a){jb?kb?kb.push(a):kb=[a]:jb=a}function Rf(){if(jb){var a=jb,b=kb;kb=jb=null;Pf(a);if(b)for(a=0;ad?0:1<c;c++)b.push(a);return b}function Oc(a,b,c){a.pendingLanes|=b;var d=b-1;a.suspendedLanes&=d;a.pingedLanes&=d;a=a.eventTimes;b=31-Ba(b);a[b]=c}function Hi(a){return 0===a?32:31-(Ii(a)/Ji|0)|0}function Ki(a,b,c,d){Xa||Xd();var e=he,f=Xa;Xa=!0;try{fg(e,a,b,c,d)}finally{(Xa=f)||Wd()}}function Li(a,b,c,d){Mi(Ni,he.bind(null,a,b,c,d))}function he(a, 45 | b,c,d){if(Pc){var e;if((e=0===(b&4))&&0=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=ug(c)}}function wg(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?wg(a,b.parentNode):"contains"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}function xg(){for(var a=window,b=Gc();b instanceof a.HTMLIFrameElement;){try{var c= 54 | "string"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow;else break;b=Gc(a.document)}return b}function ne(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&("input"===b&&("text"===a.type||"search"===a.type||"tel"===a.type||"url"===a.type||"password"===a.type)||"textarea"===b||"true"===a.contentEditable)}function yg(a,b,c){var d=c.window===c?c.document:9===c.nodeType?c:c.ownerDocument;oe||null==qb||qb!==Gc(d)||(d=qb,"selectionStart"in d&&ne(d)?d={start:d.selectionStart, 55 | end:d.selectionEnd}:(d=(d.ownerDocument&&d.ownerDocument.defaultView||window).getSelection(),d={anchorNode:d.anchorNode,anchorOffset:d.anchorOffset,focusNode:d.focusNode,focusOffset:d.focusOffset}),$b&&Zb($b,d)||($b=d,d=Tc(pe,"onSelect"),0ub||(a.current=ve[ub],ve[ub]=null,ub--)}function A(a,b,c){ub++;ve[ub]=a.current;a.current=b}function vb(a,b){var c=a.type.contextTypes;if(!c)return Ha;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext= 71 | b,a.__reactInternalMemoizedMaskedChildContext=e);return e}function S(a){a=a.childContextTypes;return null!==a&&void 0!==a}function Sg(a,b,c){if(D.current!==Ha)throw Error(m(168));A(D,b);A(J,c)}function Tg(a,b,c){var d=a.stateNode;a=b.childContextTypes;if("function"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in a))throw Error(m(108,hb(b)||"Unknown",e));return B({},c,d)}function Xc(a){a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||Ha;Ya=D.current; 72 | A(D,a);A(J,J.current);return!0}function Ug(a,b,c){var d=a.stateNode;if(!d)throw Error(m(169));c?(a=Tg(a,b,Ya),d.__reactInternalMemoizedMergedChildContext=a,t(J),t(D),A(D,a)):t(J);A(J,c)}function wb(){switch(oj()){case Yc:return 99;case Vg:return 98;case Wg:return 97;case Xg:return 96;case Yg:return 95;default:throw Error(m(332));}}function Zg(a){switch(a){case 99:return Yc;case 98:return Vg;case 97:return Wg;case 96:return Xg;case 95:return Yg;default:throw Error(m(332));}}function Za(a,b){a=Zg(a); 73 | return pj(a,b)}function bc(a,b,c){a=Zg(a);return we(a,b,c)}function ja(){if(null!==Zc){var a=Zc;Zc=null;xe(a)}$g()}function $g(){if(!ye&&null!==pa){ye=!0;var a=0;try{var b=pa;Za(99,function(){for(;ap?(x=l,l=null):x=l.sibling;var C=r(e,l,h[p],k);if(null===C){null===l&&(l=x);break}a&&l&&null=== 90 | C.alternate&&b(e,l);g=f(C,g,p);null===v?m=C:v.sibling=C;v=C;l=x}if(p===h.length)return c(e,l),m;if(null===l){for(;px?(C=p,p=null):C=p.sibling;var Da=r(e,p,q.value,k);if(null===Da){null===p&&(p=C);break}a&&p&&null===Da.alternate&&b(e,p);g=f(Da,g,x);null===v?l=Da:v.sibling=Da;v=Da;p=C}if(q.done)return c(e,p),l;if(null===p){for(;!q.done;x++,q=h.next())q=n(e,q.value,k),null!==q&&(g=f(q,g,x),null===v?l=q:v.sibling=q,v=q);return l}for(p=d(e,p);!q.done;x++,q=h.next())q=t(p,e,x,q.value,k),null!==q&&(a&&null!== 92 | q.alternate&&p.delete(null===q.key?x:q.key),g=f(q,g,x),null===v?l=q:v.sibling=q,v=q);a&&p.forEach(function(a){return b(e,a)});return l}return function(a,d,f,h){var k="object"===typeof f&&null!==f&&f.type===wa&&null===f.key;k&&(f=f.props.children);var l="object"===typeof f&&null!==f;if(l)switch(f.$$typeof){case ec:a:{l=f.key;for(k=d;null!==k;){if(k.key===l){switch(k.tag){case 7:if(f.type===wa){c(a,k.sibling);d=e(k,f.props.children);d.return=a;a=d;break a}break;default:if(k.elementType===f.type){c(a, 93 | k.sibling);d=e(k,f.props);d.ref=dc(a,k,f);d.return=a;a=d;break a}}c(a,k);break}else b(a,k);k=k.sibling}f.type===wa?(d=zb(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=fd(f.type,f.key,f.props,null,a.mode,h),h.ref=dc(a,d,f),h.return=a,a=h)}return g(a);case Ua:a:{for(k=f.key;null!==d;){if(d.key===k)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[]);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d= 94 | d.sibling}d=Ee(f,a.mode,h);d.return=a;a=d}return g(a)}if("string"===typeof f||"number"===typeof f)return f=""+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f),d.return=a,a=d):(c(a,d),d=De(f,a.mode,h),d.return=a,a=d),g(a);if(gd(f))return w(a,d,f,h);if(Jb(f))return z(a,d,f,h);l&&ed(a,f);if("undefined"===typeof f&&!k)switch(a.tag){case 1:case 22:case 0:case 11:case 15:throw Error(m(152,hb(a.type)||"Component"));}return c(a,d)}}function $a(a){if(a===fc)throw Error(m(174));return a}function Fe(a,b){A(gc, 95 | b);A(hc,a);A(ka,fc);a=b.nodeType;switch(a){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:Rd(null,"");break;default:a=8===a?b.parentNode:b,b=a.namespaceURI||null,a=a.tagName,b=Rd(b,a)}t(ka);A(ka,b)}function Ab(a){t(ka);t(hc);t(gc)}function jh(a){$a(gc.current);var b=$a(ka.current);var c=Rd(b,a.type);b!==c&&(A(hc,a),A(ka,c))}function Ge(a){hc.current===a&&(t(ka),t(hc))}function hd(a){for(var b=a;null!==b;){if(13===b.tag){var c=b.memoizedState;if(null!==c&&(c=c.dehydrated,null===c||"$?"===c.data|| 96 | "$!"===c.data))return b}else if(19===b.tag&&void 0!==b.memoizedProps.revealOrder){if(0!==(b.flags&64))return b}else if(null!==b.child){b.child.return=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}return null}function kh(a,b){var c=Z(5,null,null,0);c.elementType="DELETED";c.type="DELETED";c.stateNode=b;c.return=a;c.flags=8;null!==a.lastEffect?(a.lastEffect.nextEffect=c,a.lastEffect=c):a.firstEffect= 97 | a.lastEffect=c}function lh(a,b){switch(a.tag){case 5:var c=a.type;b=1!==b.nodeType||c.toLowerCase()!==b.nodeName.toLowerCase()?null:b;return null!==b?(a.stateNode=b,!0):!1;case 6:return b=""===a.pendingProps||3!==b.nodeType?null:b,null!==b?(a.stateNode=b,!0):!1;case 13:return!1;default:return!1}}function He(a){if(la){var b=Na;if(b){var c=b;if(!lh(a,b)){b=tb(c.nextSibling);if(!b||!lh(a,b)){a.flags=a.flags&-1025|2;la=!1;ra=a;return}kh(ra,c)}ra=a;Na=tb(b.firstChild)}else a.flags=a.flags&-1025|2,la=!1, 98 | ra=a}}function mh(a){for(a=a.return;null!==a&&5!==a.tag&&3!==a.tag&&13!==a.tag;)a=a.return;ra=a}function id(a){if(a!==ra)return!1;if(!la)return mh(a),la=!0,!1;var b=a.type;if(5!==a.tag||"head"!==b&&"body"!==b&&!se(b,a.memoizedProps))for(b=Na;b;)kh(a,b),b=tb(b.nextSibling);mh(a);if(13===a.tag){a=a.memoizedState;a=null!==a?a.dehydrated:null;if(!a)throw Error(m(317));a:{a=a.nextSibling;for(b=0;a;){if(8===a.nodeType){var c=a.data;if("/$"===c){if(0===b){Na=tb(a.nextSibling);break a}b--}else"$"!==c&&"$!"!== 99 | c&&"$?"!==c||b++}a=a.nextSibling}Na=null}}else Na=ra?tb(a.stateNode.nextSibling):null;return!0}function Ie(){Na=ra=null;la=!1}function Je(){for(var a=0;af))throw Error(m(301));f+=1;K=N=null;b.updateQueue=null;jc.current=sj;a=c(d,e)}while(kc)}jc.current=jd;b=null!==N&&null!==N.next;ic=0;K=N=y=null;kd=!1;if(b)throw Error(m(300));return a}function ab(){var a={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};null===K?y.memoizedState=K=a:K=K.next=a;return K}function bb(){if(null===N){var a=y.alternate;a=null!==a?a.memoizedState:null}else a=N.next;var b=null===K?y.memoizedState:K.next;if(null!== 101 | b)K=b,N=a;else{if(null===a)throw Error(m(310));N=a;a={memoizedState:N.memoizedState,baseState:N.baseState,baseQueue:N.baseQueue,queue:N.queue,next:null};null===K?y.memoizedState=K=a:K=K.next=a}return K}function ma(a,b){return"function"===typeof b?b(a):b}function lc(a,b,c){b=bb();c=b.queue;if(null===c)throw Error(m(311));c.lastRenderedReducer=a;var d=N,e=d.baseQueue,f=c.pending;if(null!==f){if(null!==e){var g=e.next;e.next=f.next;f.next=g}d.baseQueue=e=f;c.pending=null}if(null!==e){e=e.next;d=d.baseState; 102 | var h=g=f=null,k=e;do{var l=k.lane;if((ic&l)===l)null!==h&&(h=h.next={lane:0,action:k.action,eagerReducer:k.eagerReducer,eagerState:k.eagerState,next:null}),d=k.eagerReducer===a?k.eagerState:a(d,k.action);else{var n={lane:l,action:k.action,eagerReducer:k.eagerReducer,eagerState:k.eagerState,next:null};null===h?(g=h=n,f=d):h=h.next=n;y.lanes|=l;La|=l}k=k.next}while(null!==k&&k!==e);null===h?f=d:h.next=g;X(d,b.memoizedState)||(fa=!0);b.memoizedState=d;b.baseState=f;b.baseQueue=h;c.lastRenderedState= 103 | d}return[b.memoizedState,c.dispatch]}function mc(a,b,c){b=bb();c=b.queue;if(null===c)throw Error(m(311));c.lastRenderedReducer=a;var d=c.dispatch,e=c.pending,f=b.memoizedState;if(null!==e){c.pending=null;var g=e=e.next;do f=a(f,g.action),g=g.next;while(g!==e);X(f,b.memoizedState)||(fa=!0);b.memoizedState=f;null===b.baseQueue&&(b.baseState=f);c.lastRenderedState=f}return[f,d]}function nh(a,b,c){var d=b._getVersion;d=d(b._source);var e=b._workInProgressVersionPrimary;if(null!==e)a=e===d;else if(a=a.mutableReadLanes, 104 | a=(ic&a)===a)b._workInProgressVersionPrimary=d,Bb.push(b);if(a)return c(b._source);Bb.push(b);throw Error(m(350));}function oh(a,b,c,d){var e=R;if(null===e)throw Error(m(349));var f=b._getVersion,g=f(b._source),h=jc.current,k=h.useState(function(){return nh(e,b,c)}),l=k[1],n=k[0];k=K;var t=a.memoizedState,r=t.refs,w=r.getSnapshot,z=t.source;t=t.subscribe;var B=y;a.memoizedState={refs:r,source:b,subscribe:d};h.useEffect(function(){r.getSnapshot=c;r.setSnapshot=l;var a=f(b._source);if(!X(g,a)){a=c(b._source); 105 | X(n,a)||(l(a),a=Oa(B),e.mutableReadLanes|=a&e.pendingLanes);a=e.mutableReadLanes;e.entangledLanes|=a;for(var d=e.entanglements,h=a;0c?98:c,function(){a(!0)});Za(97\x3c/script>",a=a.removeChild(a.firstChild)):"string"===typeof d.is?a=g.createElement(c,{is:d.is}):(a=g.createElement(c),"select"===c&&(g=a,d.multiple? 132 | g.multiple=!0:d.size&&(g.size=d.size))):a=g.createElementNS(a,c);a[Fa]=b;a[Wc]=d;xj(a,b,!1,!1);b.stateNode=a;g=Td(c,d);switch(c){case "dialog":z("cancel",a);z("close",a);e=d;break;case "iframe":case "object":case "embed":z("load",a);e=d;break;case "video":case "audio":for(e=0;eWe&&(b.flags|=64,f=!0,oc(d,!1),b.lanes=33554432)}else{if(!f)if(a=hd(g),null!==a){if(b.flags|=64,f=!0,c=a.updateQueue,null!==c&&(b.updateQueue=c,b.flags|=4),oc(d,!0),null===d.tail&&"hidden"===d.tailMode&& 139 | !g.alternate&&!la)return b=b.lastEffect=d.lastEffect,null!==b&&(b.nextEffect=null),null}else 2*P()-d.renderingStartTime>We&&1073741824!==c&&(b.flags|=64,f=!0,oc(d,!1),b.lanes=33554432);d.isBackwards?(g.sibling=b.child,b.child=g):(c=d.last,null!==c?c.sibling=g:b.child=g,d.last=g)}return null!==d.tail?(c=d.tail,d.rendering=c,d.tail=c.sibling,d.lastEffect=b.lastEffect,d.renderingStartTime=P(),c.sibling=null,b=E.current,A(E,f?b&1|2:b&1),c):null;case 23:case 24:return ta=cb.current,t(cb),null!==a&&null!== 140 | a.memoizedState!==(null!==b.memoizedState)&&"unstable-defer-without-hiding"!==d.mode&&(b.flags|=4),null}throw Error(m(156,b.tag));}function zj(a,b){switch(a.tag){case 1:return S(a.type)&&(t(J),t(D)),b=a.flags,b&4096?(a.flags=b&-4097|64,a):null;case 3:Ab();t(J);t(D);Je();b=a.flags;if(0!==(b&64))throw Error(m(285));a.flags=b&-4097|64;return a;case 5:return Ge(a),null;case 13:return t(E),b=a.flags,b&4096?(a.flags=b&-4097|64,a):null;case 19:return t(E),null;case 4:return Ab(),null;case 10:return Ae(a), 141 | null;case 23:case 24:return ta=cb.current,t(cb),null;default:return null}}function Xe(a,b){try{var c="",d=b;do c+=pi(d),d=d.return;while(d);var e=c}catch(f){e="\nError generating stack: "+f.message+"\n"+f.stack}return{value:a,source:b,stack:e}}function Ye(a,b){try{console.error(b.value)}catch(c){setTimeout(function(){throw c;})}}function Mh(a,b,c){c=Ia(-1,c);c.tag=3;c.payload={element:null};var d=b.value;c.callback=function(){rd||(rd=!0,Ze=d);Ye(a,b)};return c}function Nh(a,b,c){c=Ia(-1,c);c.tag= 142 | 3;var d=a.type.getDerivedStateFromError;if("function"===typeof d){var e=b.value;c.payload=function(){Ye(a,b);return d(e)}}var f=a.stateNode;null!==f&&"function"===typeof f.componentDidCatch&&(c.callback=function(){"function"!==typeof d&&(null===na?na=new Set([this]):na.add(this),Ye(a,b));var c=b.stack;this.componentDidCatch(b.value,{componentStack:null!==c?c:""})});return c}function Oh(a){var b=a.ref;if(null!==b)if("function"===typeof b)try{b(null)}catch(c){Qa(a,c)}else b.current=null}function Aj(a, 143 | b){switch(b.tag){case 0:case 11:case 15:case 22:return;case 1:if(b.flags&256&&null!==a){var c=a.memoizedProps,d=a.memoizedState;a=b.stateNode;b=a.getSnapshotBeforeUpdate(b.elementType===b.type?c:ea(b.type,c),d);a.__reactInternalSnapshotBeforeUpdate=b}return;case 3:b.flags&256&&te(b.stateNode.containerInfo);return;case 5:case 6:case 4:case 17:return}throw Error(m(163));}function Bj(a,b,c,d){switch(c.tag){case 0:case 11:case 15:case 22:b=c.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){a=b=b.next; 144 | do 3===(a.tag&3)&&(d=a.create,a.destroy=d()),a=a.next;while(a!==b)}b=c.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){a=b=b.next;do{var e=a;d=e.next;e=e.tag;0!==(e&4)&&0!==(e&1)&&(Ph(c,a),Cj(c,a));a=d}while(a!==b)}return;case 1:a=c.stateNode;c.flags&4&&(null===b?a.componentDidMount():(d=c.elementType===c.type?b.memoizedProps:ea(c.type,b.memoizedProps),a.componentDidUpdate(d,b.memoizedState,a.__reactInternalSnapshotBeforeUpdate)));b=c.updateQueue;null!==b&&dh(c,b,a);return;case 3:b=c.updateQueue; 145 | if(null!==b){a=null;if(null!==c.child)switch(c.child.tag){case 5:a=c.child.stateNode;break;case 1:a=c.child.stateNode}dh(c,b,a)}return;case 5:a=c.stateNode;null===b&&c.flags&4&&Pg(c.type,c.memoizedProps)&&a.focus();return;case 6:return;case 4:return;case 12:return;case 13:null===c.memoizedState&&(c=c.alternate,null!==c&&(c=c.memoizedState,null!==c&&(c=c.dehydrated,null!==c&&bg(c))));return;case 19:case 17:case 20:case 21:case 23:case 24:return}throw Error(m(163));}function Qh(a,b){for(var c=a;;){if(5=== 146 | c.tag){var d=c.stateNode;if(b)d=d.style,"function"===typeof d.setProperty?d.setProperty("display","none","important"):d.display="none";else{d=c.stateNode;var e=c.memoizedProps.style;e=void 0!==e&&null!==e&&e.hasOwnProperty("display")?e.display:null;d.style.display=Nf("display",e)}}else if(6===c.tag)c.stateNode.nodeValue=b?"":c.memoizedProps;else if((23!==c.tag&&24!==c.tag||null===c.memoizedState||c===a)&&null!==c.child){c.child.return=c;c=c.child;continue}if(c===a)break;for(;null===c.sibling;){if(null=== 147 | c.return||c.return===a)return;c=c.return}c.sibling.return=c.return;c=c.sibling}}function Rh(a,b,c){if(db&&"function"===typeof db.onCommitFiberUnmount)try{db.onCommitFiberUnmount($e,b)}catch(f){}switch(b.tag){case 0:case 11:case 14:case 15:case 22:a=b.updateQueue;if(null!==a&&(a=a.lastEffect,null!==a)){c=a=a.next;do{var d=c,e=d.destroy;d=d.tag;if(void 0!==e)if(0!==(d&4))Ph(b,c);else{d=b;try{e()}catch(f){Qa(d,f)}}c=c.next}while(c!==a)}break;case 1:Oh(b);a=b.stateNode;if("function"===typeof a.componentWillUnmount)try{a.props= 148 | b.memoizedProps,a.state=b.memoizedState,a.componentWillUnmount()}catch(f){Qa(b,f)}break;case 5:Oh(b);break;case 4:Sh(a,b)}}function Th(a){a.alternate=null;a.child=null;a.dependencies=null;a.firstEffect=null;a.lastEffect=null;a.memoizedProps=null;a.memoizedState=null;a.pendingProps=null;a.return=null;a.updateQueue=null}function Uh(a){return 5===a.tag||3===a.tag||4===a.tag}function Vh(a){a:{for(var b=a.return;null!==b;){if(Uh(b))break a;b=b.return}throw Error(m(160));}var c=b;b=c.stateNode;switch(c.tag){case 5:var d= 149 | !1;break;case 3:b=b.containerInfo;d=!0;break;case 4:b=b.containerInfo;d=!0;break;default:throw Error(m(161));}c.flags&16&&(qc(b,""),c.flags&=-17);a:b:for(c=a;;){for(;null===c.sibling;){if(null===c.return||Uh(c.return)){c=null;break a}c=c.return}c.sibling.return=c.return;for(c=c.sibling;5!==c.tag&&6!==c.tag&&18!==c.tag;){if(c.flags&2)continue b;if(null===c.child||4===c.tag)continue b;else c.child.return=c,c=c.child}if(!(c.flags&2)){c=c.stateNode;break a}}d?af(a,c,b):bf(a,c,b)}function af(a,b,c){var d= 150 | a.tag,e=5===d||6===d;if(e)a=e?a.stateNode:a.stateNode.instance,b?8===c.nodeType?c.parentNode.insertBefore(a,b):c.insertBefore(a,b):(8===c.nodeType?(b=c.parentNode,b.insertBefore(a,c)):(b=c,b.appendChild(a)),c=c._reactRootContainer,null!==c&&void 0!==c||null!==b.onclick||(b.onclick=Vc));else if(4!==d&&(a=a.child,null!==a))for(af(a,b,c),a=a.sibling;null!==a;)af(a,b,c),a=a.sibling}function bf(a,b,c){var d=a.tag,e=5===d||6===d;if(e)a=e?a.stateNode:a.stateNode.instance,b?c.insertBefore(a,b):c.appendChild(a); 151 | else if(4!==d&&(a=a.child,null!==a))for(bf(a,b,c),a=a.sibling;null!==a;)bf(a,b,c),a=a.sibling}function Sh(a,b,c){c=b;for(var d=!1,e,f;;){if(!d){e=c.return;a:for(;;){if(null===e)throw Error(m(160));f=e.stateNode;switch(e.tag){case 5:e=f;f=!1;break a;case 3:e=f.containerInfo;f=!0;break a;case 4:e=f.containerInfo;f=!0;break a}e=e.return}d=!0}if(5===c.tag||6===c.tag){a:for(var g=a,h=c,k=h;;)if(Rh(g,k),null!==k.child&&4!==k.tag)k.child.return=k,k=k.child;else{if(k===h)break a;for(;null===k.sibling;){if(null=== 152 | k.return||k.return===h)break a;k=k.return}k.sibling.return=k.return;k=k.sibling}f?(g=e,h=c.stateNode,8===g.nodeType?g.parentNode.removeChild(h):g.removeChild(h)):e.removeChild(c.stateNode)}else if(4===c.tag){if(null!==c.child){e=c.stateNode.containerInfo;f=!0;c.child.return=c;c=c.child;continue}}else if(Rh(a,c),null!==c.child){c.child.return=c;c=c.child;continue}if(c===b)break;for(;null===c.sibling;){if(null===c.return||c.return===b)return;c=c.return;4===c.tag&&(d=!1)}c.sibling.return=c.return;c= 153 | c.sibling}}function cf(a,b){switch(b.tag){case 0:case 11:case 14:case 15:case 22:var c=b.updateQueue;c=null!==c?c.lastEffect:null;if(null!==c){var d=c=c.next;do 3===(d.tag&3)&&(a=d.destroy,d.destroy=void 0,void 0!==a&&a()),d=d.next;while(d!==c)}return;case 1:return;case 5:c=b.stateNode;if(null!=c){d=b.memoizedProps;var e=null!==a?a.memoizedProps:d;a=b.type;var f=b.updateQueue;b.updateQueue=null;if(null!==f){c[Wc]=d;"input"===a&&"radio"===d.type&&null!=d.name&&Hf(c,d);Td(a,e);b=Td(a,d);for(e=0;ee&&(e=g);c&=~f}c=e;c=P()-c;c=(120>c?120:480>c?480:1080>c?1080:1920>c?1920:3E3>c?3E3:4320>c?4320:1960*Ij(c/1960))-c;if(10 component higher in the tree to provide a loading indicator or placeholder to display.")}5!== 167 | L&&(L=2);k=Xe(k,h);r=g;do{switch(r.tag){case 3:f=k;r.flags|=4096;b&=-b;r.lanes|=b;var B=Mh(r,f,b);ch(r,B);break a;case 1:f=k;var A=r.type,D=r.stateNode;if(0===(r.flags&64)&&("function"===typeof A.getDerivedStateFromError||null!==D&&"function"===typeof D.componentDidCatch&&(null===na||!na.has(D)))){r.flags|=4096;b&=-b;r.lanes|=b;var F=Nh(r,f,b);ch(r,F);break a}}r=r.return}while(null!==r)}ci(c)}catch(qa){b=qa;G===c&&null!==c&&(G=c=c.return);continue}break}while(1)}function Yh(){var a=vd.current;vd.current= 168 | jd;return null===a?jd:a}function sc(a,b){var c=n;n|=16;var d=Yh();R===a&&O===b||Gb(a,b);do try{Nj();break}catch(e){Zh(a,e)}while(1);ze();n=c;vd.current=d;if(null!==G)throw Error(m(261));R=null;O=0;return L}function Nj(){for(;null!==G;)di(G)}function Hj(){for(;null!==G&&!Oj();)di(G)}function di(a){var b=Pj(a.alternate,a,ta);a.memoizedProps=a.pendingProps;null===b?ci(a):G=b;kf.current=null}function ci(a){var b=a;do{var c=b.alternate;a=b.return;if(0===(b.flags&2048)){c=vj(c,b,ta);if(null!==c){G=c;return}c= 169 | b;if(24!==c.tag&&23!==c.tag||null===c.memoizedState||0!==(ta&1073741824)||0===(c.mode&4)){for(var d=0,e=c.child;null!==e;)d|=e.lanes|e.childLanes,e=e.sibling;c.childLanes=d}null!==a&&0===(a.flags&2048)&&(null===a.firstEffect&&(a.firstEffect=b.firstEffect),null!==b.lastEffect&&(null!==a.lastEffect&&(a.lastEffect.nextEffect=b.firstEffect),a.lastEffect=b.lastEffect),1g&&(h=g,g=A,A=h),h=vg(p,A),f=vg(p,g),h&&f&&(1!==u.rangeCount||u.anchorNode!==h.node||u.anchorOffset!==h.offset||u.focusNode!==f.node||u.focusOffset!==f.offset)&&(q=q.createRange(),q.setStart(h.node,h.offset),u.removeAllRanges(),A>g?(u.addRange(q),u.extend(f.node, 176 | f.offset)):(q.setEnd(f.node,f.offset),u.addRange(q))))));q=[];for(u=p;u=u.parentNode;)1===u.nodeType&&q.push({element:u,left:u.scrollLeft,top:u.scrollTop});"function"===typeof p.focus&&p.focus();for(p=0;pP()-df?Gb(a,0):jf|=c);ba(a,b)}function Ej(a,b){var c=a.stateNode;null!==c&&c.delete(b);b=0;0===b&&(b=a.mode,0===(b&2)?b=1:0===(b&4)?b=99===wb()?1:2:(0===ua&&(ua=Fb),b=nb(62914560&~ua),0===b&&(b=4194304))); 182 | c=W();a=ud(a,b);null!==a&&(Oc(a,b,c),ba(a,c))}function Uj(a,b,c,d){this.tag=a;this.key=c;this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null;this.index=0;this.ref=null;this.pendingProps=b;this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.flags=0;this.lastEffect=this.firstEffect=this.nextEffect=null;this.childLanes=this.lanes=0;this.alternate=null}function Qe(a){a=a.prototype;return!(!a||!a.isReactComponent)}function Vj(a){if("function"=== 183 | typeof a)return Qe(a)?1:0;if(void 0!==a&&null!==a){a=a.$$typeof;if(a===Dc)return 11;if(a===Ec)return 14}return 2}function Ma(a,b){var c=a.alternate;null===c?(c=Z(a.tag,b,a.key,a.mode),c.elementType=a.elementType,c.type=a.type,c.stateNode=a.stateNode,c.alternate=a,a.alternate=c):(c.pendingProps=b,c.type=a.type,c.flags=0,c.nextEffect=null,c.firstEffect=null,c.lastEffect=null);c.childLanes=a.childLanes;c.lanes=a.lanes;c.child=a.child;c.memoizedProps=a.memoizedProps;c.memoizedState=a.memoizedState;c.updateQueue= 184 | a.updateQueue;b=a.dependencies;c.dependencies=null===b?null:{lanes:b.lanes,firstContext:b.firstContext};c.sibling=a.sibling;c.index=a.index;c.ref=a.ref;return c}function fd(a,b,c,d,e,f){var g=2;d=a;if("function"===typeof a)Qe(a)&&(g=1);else if("string"===typeof a)g=5;else a:switch(a){case wa:return zb(c.children,e,f,b);case fi:g=8;e|=16;break;case Hd:g=8;e|=1;break;case Lb:return a=Z(12,c,b,e|8),a.elementType=Lb,a.type=Lb,a.lanes=f,a;case Mb:return a=Z(13,c,b,e),a.type=Mb,a.elementType=Mb,a.lanes= 185 | f,a;case Cc:return a=Z(19,c,b,e),a.elementType=Cc,a.lanes=f,a;case pf:return Ue(c,e,f,b);case qf:return a=Z(24,c,b,e),a.elementType=qf,a.lanes=f,a;default:if("object"===typeof a&&null!==a)switch(a.$$typeof){case Jd:g=10;break a;case Id:g=9;break a;case Dc:g=11;break a;case Ec:g=14;break a;case Ld:g=16;d=null;break a;case Kd:g=22;break a}throw Error(m(130,null==a?a:typeof a,""));}b=Z(g,c,b,e);b.elementType=a;b.type=d;b.lanes=f;return b}function zb(a,b,c,d){a=Z(7,a,d,b);a.lanes=c;return a}function Ue(a, 186 | b,c,d){a=Z(23,a,d,b);a.elementType=pf;a.lanes=c;return a}function De(a,b,c){a=Z(6,a,null,b);a.lanes=c;return a}function Ee(a,b,c){b=Z(4,null!==a.children?a.children:[],a.key,b);b.lanes=c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b}function Wj(a,b,c){this.tag=b;this.containerInfo=a;this.finishedWork=this.pingCache=this.current=this.pendingChildren=null;this.timeoutHandle=-1;this.pendingContext=this.context=null;this.hydrate=c;this.callbackNode= 187 | null;this.callbackPriority=0;this.eventTimes=ge(0);this.expirationTimes=ge(-1);this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0;this.entanglements=ge(0);this.mutableSourceEagerHydrationData=null}function Xj(a,b,c){var d=3