diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 8eb21cc1..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -name: Bug report -about: Report a bug to help us improve -title: '' -labels: 'bug' -assignees: '' ---- - -## Description - -<!-- Provide a clear and concise description of the bug. --> - -## How To Reproduce - -<!-- Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error --> - -## Expected behavior - -<!-- Describe what you expected to happen. --> - -## Screenshots - -<!-- If applicable, add screenshots to help explain the issue --> - -## Environment - -### Desktop - -- **Operating System:** [e.g., Windows, macOS, Linux] -- **Browser:** [e.g., Chrome, Safari, Firefox] -- **Version:** [e.g., v1.0.0] - -### Smartphone - -- **Device:** [e.g., iPhone 6] -- **OS:** [e.g., iOS 8.1] -- **Browser:** [e.g., stock browser, Safari] -- **Version:** [e.g., v1.0.0] - -## Console Errors - -<!-- Attach screenshots of console errors if available to provide more context. --> - -## Additional context (if any) - -<!-- Add any other context about the problem here. --> - -## Checklist - -- [ ] I have read and followed the project's Code of Conduct. -- [ ] I have searched for similar issues before creating this one. -- [ ] I have provided sufficient details to understand and reproduce the issue. I have provided all the necessary information to understand and reproduce the issue. -- [ ] I am willing to help resolve this issue. - ---- - -Thank you for reporting this issue! Your contributions help us improve the project. - -📚 **See:** [Contributing Guide](https://github.com/sugarlabs/www-v2/blob/main/docs/CONTRIBUTING.md). - -🙋🏾🙋🏼 Need help? Join our [Community Matrix Server](https://matrix.to/#/#sugarlabs-web:matrix.org). diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md deleted file mode 100644 index 48d5f81f..00000000 --- a/.github/ISSUE_TEMPLATE/custom.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Custom issue template -about: Describe this issue template's purpose here. -title: '' -labels: '' -assignees: '' - ---- - - diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bbcbbe7d..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 770f7dfd..00000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -name: Pull Request -about: Submit changes to the project for review and inclusion ---- - -## Description - -<!--- Describe the changes introduced by this pull request. --> -<!--- Explain what problem it solves or what feature/fix it adds. --> - -## Related Issue - -<!--- If this pull request is related to a specific issue, reference it here using #issue_number. --> -<!--- For example, "Fixes #123" or "Addresses #456". --> - -This PR fixes # - -## Changes Made - -<!--- Provide a summary of the changes made in this pull request. --> -<!--- Include any relevant technical details or architecture changes. --> - -- Change 1 -- Change 2 -- ... - -## Testing Performed - -<!--- Describe the testing that you have performed to validate these changes. --> -<!--- Include information about test cases, testing environments, and results. --> - -- Tested feature X in scenario Y. -- Ran unit tests for component Z. -- Tested on browsers A, B, and C. -- ... - -## Checklist - -<!--- Please check the boxes that apply to this pull request. --> -<!--- You can add or remove items as needed. --> - -- [ ] I have tested these changes locally and they work as expected. -- [ ] I have added/updated tests that prove the effectiveness of these changes. -- [ ] I have updated the documentation to reflect these changes, if applicable. -- [ ] I have followed the project's coding style guidelines. -- [ ] I have addressed the code review feedback from the previous submission, if applicable. - -## Additional Notes for Reviewers - -<!--- Provide any additional context or notes for the reviewers. --> -<!--- This might include details about design decisions, potential concerns, or anything else relevant. --> - ---- - -Thank you for contributing to our project! We appreciate your help in improving it. - -📚 See [contributing instructions](https://github.com/sugarlabs/musicblocks/blob/master/README.md). - -🙋🏾🙋🏼 Questions: [Community Matrix Server](https://matrix.to/#/#sugar:matrix.org). diff --git a/.github/workflows/bot.yml b/.github/workflows/bot.yml deleted file mode 100644 index ee92f30d..00000000 --- a/.github/workflows/bot.yml +++ /dev/null @@ -1,169 +0,0 @@ -name: Status Bot - -on: - pull_request_target: - types: - - opened - - synchronize - -jobs: - check-pr-status: - name: Workflow Status Check - runs-on: ubuntu-latest - permissions: - pull-requests: write - contents: read - issues: write - actions: read - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '22' - - - name: Install Dependencies - run: npm install - - - name: Run Build Test (CI Check) - id: ci-check - run: | - if npm run build; then - echo "CI_PASSED=true" >> $GITHUB_ENV - echo "CI_ERROR=" >> $GITHUB_ENV - else - echo "CI_PASSED=false" >> $GITHUB_ENV - echo "CI_ERROR=Build failed" >> $GITHUB_ENV - fi - - - name: Run Linting Checks - id: lint-check - run: | - LINT_ERRORS="" - LINT_PASSED=true - - # Run TypeScript linting - if ! npm run lint:ts; then - LINT_PASSED=false - LINT_ERRORS="${LINT_ERRORS}• TypeScript linting failed\n" - fi - - # Run Markdown linting - if ! npm run lint:md; then - LINT_PASSED=false - LINT_ERRORS="${LINT_ERRORS}• Markdown linting failed\n" - fi - - # Check code formatting with Prettier - if ! npm run format:check; then - LINT_PASSED=false - LINT_ERRORS="${LINT_ERRORS}• Code formatting issues detected\n" - fi - - echo "LINT_PASSED=$LINT_PASSED" >> $GITHUB_ENV - echo "LINT_ERRORS<<EOF" >> $GITHUB_ENV - echo -e "$LINT_ERRORS" >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV - - - name: Generate PR Comment - id: generate-comment - run: | - # Extract PR number - PR_NUMBER=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH") - - # Generate a temporary file for the comment - COMMENT_FILE=$(mktemp) - - # Save variables to GITHUB_OUTPUT - echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT - echo "COMMENT_FILE=$COMMENT_FILE" >> $GITHUB_OUTPUT - - # Generate content for the comment file - { - if [ "$CI_PASSED" = "true" ] && [ "$LINT_PASSED" = "true" ]; then - echo "## 🎉 All Checks Passed!" - echo "" - echo "> **Status:** ✅ Ready to merge" - echo "" - echo "### ✅ Completed Workflows" - echo "" - echo "| Workflow | Status | Details |" - echo "|----------|--------|---------|" - echo "| 🔨 **Continuous Integration** | ✅ Passed | Build completed successfully |" - echo "| 📝 **Code Linting** | ✅ Passed | All formatting and style checks passed |" - echo "" - echo "---" - echo "" - echo "🚀 **This PR is ready for review and can be safely merged to \`main\` branch!**" - echo "" - echo "*Great work! Your code meets all quality standards.* 👏" - else - echo "## ❌ Checks Failed" - echo "" - echo "> **Status:** 🚫 Not ready to merge" - echo "" - echo "Please fix the following issues before merging:" - echo "" - - if [ "$CI_PASSED" = "false" ]; then - echo "### 🔨 Continuous Integration Failed" - echo "" - echo "**Issue:** The build process failed to complete." - echo "" - echo "**How to fix:**" - echo "1. Run \`npm run build\` locally to identify the issue" - echo "2. Fix any TypeScript compilation errors" - echo "3. Ensure all dependencies are properly installed" - echo "4. Test your changes before pushing" - echo "" - echo "---" - echo "" - fi - - if [ "$LINT_PASSED" = "false" ]; then - echo "### 📝 Code Linting Failed" - echo "" - echo "**Issue:** Code formatting or style violations detected." - echo "" - if [ -n "$LINT_ERRORS" ]; then - echo "**Specific problems:**" - echo "" - echo -e "$LINT_ERRORS" - echo "" - fi - echo "**How to fix:**" - echo "" - echo "| Platform | Command | Description |" - echo "|----------|---------|-------------|" - echo "| 🐧 **Unix/macOS/Linux** | \`npm run format\` | Auto-fix all formatting issues |" - echo "| 🪟 **Windows** | \`npm run format:file <filename>\` | Fix specific files |" - echo "| 🔍 **Check Only** | \`npm run format:check\` | Check formatting without fixing |" - echo "" - echo "**Need help with linting?** Check out the [Linting Guide for Windows Users](https://github.com/sugarlabs/www-v2/pull/12) for detailed instructions." - echo "" - echo "---" - echo "" - fi - - echo "### 🛠️ Next Steps" - echo "" - echo "1. **Fix the issues** mentioned above" - echo "2. **Test locally** to ensure everything works" - echo "3. **Push your fixes** to this branch" - echo "4. **Wait for re-check** - This bot will automatically run again" - echo "" - echo "> 🤖 *This comment will be updated automatically when you push new commits*" - fi - } > "$COMMENT_FILE" - - - name: Comment on PR - uses: thollander/actions-comment-pull-request@v3 - with: - file-path: ${{ steps.generate-comment.outputs.COMMENT_FILE }} - pr-number: ${{ steps.generate-comment.outputs.PR_NUMBER }} - github-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 532a66f2..9615412e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,15 +5,19 @@ name: Continuous Deployment on: push: - branches: - - main + branches: [main] + pull_request: + types: [closed] + branches: [main] jobs: deploy: - name: Build and Deploy to GH-Pages + name: Build and Deploy app to GitHub Pages runs-on: ubuntu-latest + if: github.event.pull_request.merged == true || github.ref == 'refs/heads/main' + steps: - name: Checkout the code base uses: actions/checkout@v3 @@ -32,6 +36,6 @@ jobs: - name: Deploy with gh-pages run: | git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git - npx gh-pages -d dist --cname www.sugarlabs.org -u "github-actions-bot <support+actions@github.com>" + npm run deploy -- -u "github-actions-bot <support+actions@github.com>" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml deleted file mode 100644 index cb0aeb40..00000000 --- a/.github/workflows/integration.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Continuous Integration - -on: - push: - branches: - - main - pull_request: - branches: - - main - -jobs: - test: - name: Test Build - - runs-on: ubuntu-latest - - steps: - - name: Checkout the code base - uses: actions/checkout@v3 - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: '22' - - - name: Install dependencies - run: npm install - - - name: Build the project - run: npm run build \ No newline at end of file diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml deleted file mode 100644 index 953304a4..00000000 --- a/.github/workflows/linting.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Documentation: https://help.github.com/en/articles/workflow-syntax-for-github-actions - -name: Linting - -on: - pull_request: - branches: [main] - push: - branches: [main] - -jobs: - lint: - name: Lint Code Base - - runs-on: ubuntu-latest - - steps: - - name: Checkout the code base - uses: actions/checkout@v3 - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: '22' - - - name: Install dependencies - run: npm install - - - name: Run TypeScript linting - run: npm run lint:ts - - - name: Run Markdown linting - run: npm run lint:md - - - name: Check code formatting with Prettier - run: npm run format:check \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 2d2ba55e..c555e65b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,3 @@ node_modules/ build/ -public/ -src/constants/MarkdownFiles/ \ No newline at end of file +public/ \ No newline at end of file diff --git a/public/404.html b/404.html similarity index 100% rename from public/404.html rename to 404.html diff --git a/CNAME b/CNAME index 47881a95..9cb2c041 100644 --- a/CNAME +++ b/CNAME @@ -1 +1 @@ -v2.sugarlabs.org \ No newline at end of file +www.sugarlabs.org \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index e72bfdda..00000000 --- a/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -<https://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -<https://www.gnu.org/licenses/why-not-lgpl.html>. \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 5a08a1de..00000000 --- a/README.md +++ /dev/null @@ -1,46 +0,0 @@ -<div align="center"> - -# [Sugar Labs](https://www.sugarlabs.org/) - -## Sugar Labs Web Site - -</div> - -## Aims - -- Announce our vision and mission. -- Invite potential users of Sugar Labs software. -- Advertise our free software and licensing approach. -- Provide links to software downloads. -- Invite potential developers to the source code we hold in trust. - -## Contributing - -Content about Sugar, Sugarizer, or Music Blocks is **far more important** than the site's style or appearance. - -Please prioritize updating the site's content over its design. - -To have your pull requests or issues considered seriously, you must be a user or developer of one of our software products: **Sugar, Sugarizer, or Music Blocks**. - -For detailed guidelines, refer to the [Contribution Guide](docs/CONTRIBUTING.md). - -## Tech Stack - -SugarWeb is a client-side web application written in TypeScript. It utilizes React for UI components and is designed to work with any JavaScript UI library/framework or the JS DOM API directly. The project is bundled using Vite. - -### Application - -- TypeScript 5 -- React 19 -- Tailwind CSS - -### Tooling - -- Node.js -- Vite -- ESLint -- Prettier - -## Development - -To get started with development, refer to the [Developer Guide](docs/dev_guide.md). diff --git a/public/Randomfavicon.js b/Randomfavicon.js similarity index 100% rename from public/Randomfavicon.js rename to Randomfavicon.js diff --git a/public/assets/990s/2019-Form-990EZ.pdf b/assets/990s/2019-Form-990EZ.pdf similarity index 100% rename from public/assets/990s/2019-Form-990EZ.pdf rename to assets/990s/2019-Form-990EZ.pdf diff --git a/public/assets/990s/2020-Form-990EZ.pdf b/assets/990s/2020-Form-990EZ.pdf similarity index 100% rename from public/assets/990s/2020-Form-990EZ.pdf rename to assets/990s/2020-Form-990EZ.pdf diff --git a/public/assets/990s/2021-Form-990EZ.pdf b/assets/990s/2021-Form-990EZ.pdf similarity index 100% rename from public/assets/990s/2021-Form-990EZ.pdf rename to assets/990s/2021-Form-990EZ.pdf diff --git a/public/assets/990s/2022-Form-990EZ.pdf b/assets/990s/2022-Form-990EZ.pdf similarity index 100% rename from public/assets/990s/2022-Form-990EZ.pdf rename to assets/990s/2022-Form-990EZ.pdf diff --git a/public/assets/990s/2023-Form-990EZ.pdf b/assets/990s/2023-Form-990EZ.pdf similarity index 100% rename from public/assets/990s/2023-Form-990EZ.pdf rename to assets/990s/2023-Form-990EZ.pdf diff --git a/public/assets/Activities/Abacus.svg b/assets/Activities/Abacus.svg similarity index 100% rename from public/assets/Activities/Abacus.svg rename to assets/Activities/Abacus.svg diff --git a/public/assets/Activities/BlockPartyActivity.svg b/assets/Activities/BlockPartyActivity.svg similarity index 100% rename from public/assets/Activities/BlockPartyActivity.svg rename to assets/Activities/BlockPartyActivity.svg diff --git a/public/assets/Activities/CellManagement.svg b/assets/Activities/CellManagement.svg similarity index 100% rename from public/assets/Activities/CellManagement.svg rename to assets/Activities/CellManagement.svg diff --git a/public/assets/Activities/JAMath.svg b/assets/Activities/JAMath.svg similarity index 100% rename from public/assets/Activities/JAMath.svg rename to assets/Activities/JAMath.svg diff --git a/public/assets/Activities/Jumble.svg b/assets/Activities/Jumble.svg similarity index 100% rename from public/assets/Activities/Jumble.svg rename to assets/Activities/Jumble.svg diff --git a/public/assets/Activities/JupyterLabs.svg b/assets/Activities/JupyterLabs.svg similarity index 100% rename from public/assets/Activities/JupyterLabs.svg rename to assets/Activities/JupyterLabs.svg diff --git a/public/assets/Activities/Memorize.svg b/assets/Activities/Memorize.svg similarity index 100% rename from public/assets/Activities/Memorize.svg rename to assets/Activities/Memorize.svg diff --git a/public/assets/Activities/ReadEtextsActivity.svg b/assets/Activities/ReadEtextsActivity.svg similarity index 100% rename from public/assets/Activities/ReadEtextsActivity.svg rename to assets/Activities/ReadEtextsActivity.svg diff --git a/public/assets/Activities/RecallActivity.svg b/assets/Activities/RecallActivity.svg similarity index 100% rename from public/assets/Activities/RecallActivity.svg rename to assets/Activities/RecallActivity.svg diff --git a/public/assets/Activities/Speak.svg b/assets/Activities/Speak.svg similarity index 100% rename from public/assets/Activities/Speak.svg rename to assets/Activities/Speak.svg diff --git a/public/assets/Activities/TicTacToe.svg b/assets/Activities/TicTacToe.svg similarity index 100% rename from public/assets/Activities/TicTacToe.svg rename to assets/Activities/TicTacToe.svg diff --git a/public/assets/Activities/flappy.svg b/assets/Activities/flappy.svg similarity index 100% rename from public/assets/Activities/flappy.svg rename to assets/Activities/flappy.svg diff --git a/public/assets/Activities/math-hurdler.svg b/assets/Activities/math-hurdler.svg similarity index 100% rename from public/assets/Activities/math-hurdler.svg rename to assets/Activities/math-hurdler.svg diff --git a/public/assets/Cards/BootableDrive.png b/assets/Cards/BootableDrive.png similarity index 100% rename from public/assets/Cards/BootableDrive.png rename to assets/Cards/BootableDrive.png diff --git a/public/assets/Cards/DesktopInitialization.png b/assets/Cards/DesktopInitialization.png similarity index 100% rename from public/assets/Cards/DesktopInitialization.png rename to assets/Cards/DesktopInitialization.png diff --git a/public/assets/Cards/Flathub.png b/assets/Cards/Flathub.png similarity index 100% rename from public/assets/Cards/Flathub.png rename to assets/Cards/Flathub.png diff --git a/public/assets/Cards/MusicBlocks.png b/assets/Cards/MusicBlocks.png similarity index 100% rename from public/assets/Cards/MusicBlocks.png rename to assets/Cards/MusicBlocks.png diff --git a/public/assets/Cards/RaspberryPi.png b/assets/Cards/RaspberryPi.png similarity index 100% rename from public/assets/Cards/RaspberryPi.png rename to assets/Cards/RaspberryPi.png diff --git a/public/assets/Cards/Sugarizer.png b/assets/Cards/Sugarizer.png similarity index 100% rename from public/assets/Cards/Sugarizer.png rename to assets/Cards/Sugarizer.png diff --git a/public/assets/Cards/Trisquel.svg b/assets/Cards/Trisquel.svg similarity index 100% rename from public/assets/Cards/Trisquel.svg rename to assets/Cards/Trisquel.svg diff --git a/public/assets/Cards/TurtleBlocks.png b/assets/Cards/TurtleBlocks.png similarity index 100% rename from public/assets/Cards/TurtleBlocks.png rename to assets/Cards/TurtleBlocks.png diff --git a/public/assets/Cards/activity-finance.svg b/assets/Cards/activity-finance.svg similarity index 100% rename from public/assets/Cards/activity-finance.svg rename to assets/Cards/activity-finance.svg diff --git a/public/assets/Cards/activity-maze.svg b/assets/Cards/activity-maze.svg similarity index 100% rename from public/assets/Cards/activity-maze.svg rename to assets/Cards/activity-maze.svg diff --git a/public/assets/Cards/activity-measure.svg b/assets/Cards/activity-measure.svg similarity index 100% rename from public/assets/Cards/activity-measure.svg rename to assets/Cards/activity-measure.svg diff --git a/public/assets/Cards/activity-physics.svg b/assets/Cards/activity-physics.svg similarity index 100% rename from public/assets/Cards/activity-physics.svg rename to assets/Cards/activity-physics.svg diff --git a/public/assets/Cards/activity-recall.svg b/assets/Cards/activity-recall.svg similarity index 100% rename from public/assets/Cards/activity-recall.svg rename to assets/Cards/activity-recall.svg diff --git a/public/assets/Cards/activity-ruler.svg b/assets/Cards/activity-ruler.svg similarity index 100% rename from public/assets/Cards/activity-ruler.svg rename to assets/Cards/activity-ruler.svg diff --git a/public/assets/Cards/activity-star-chart.svg b/assets/Cards/activity-star-chart.svg similarity index 100% rename from public/assets/Cards/activity-star-chart.svg rename to assets/Cards/activity-star-chart.svg diff --git a/public/assets/Cards/activity-turtle3d.svg b/assets/Cards/activity-turtle3d.svg similarity index 100% rename from public/assets/Cards/activity-turtle3d.svg rename to assets/Cards/activity-turtle3d.svg diff --git a/public/assets/Cards/activity-words.svg b/assets/Cards/activity-words.svg similarity index 100% rename from public/assets/Cards/activity-words.svg rename to assets/Cards/activity-words.svg diff --git a/public/assets/Developers/Muhammad Haroon/muhammadharoon.jpg b/assets/Developers/Muhammad Haroon/muhammadharoon.jpg similarity index 100% rename from public/assets/Developers/Muhammad Haroon/muhammadharoon.jpg rename to assets/Developers/Muhammad Haroon/muhammadharoon.jpg diff --git a/public/assets/Developers/Nikhil/project-dashboard.png b/assets/Developers/Nikhil/project-dashboard.png similarity index 100% rename from public/assets/Developers/Nikhil/project-dashboard.png rename to assets/Developers/Nikhil/project-dashboard.png diff --git a/public/assets/Developers/Nikhil/project-flow.png b/assets/Developers/Nikhil/project-flow.png similarity index 100% rename from public/assets/Developers/Nikhil/project-flow.png rename to assets/Developers/Nikhil/project-flow.png diff --git a/public/assets/Developers/Safwan/AST.png b/assets/Developers/Safwan/AST.png similarity index 100% rename from public/assets/Developers/Safwan/AST.png rename to assets/Developers/Safwan/AST.png diff --git a/public/assets/Developers/Safwan/context-stack-test.png b/assets/Developers/Safwan/context-stack-test.png similarity index 100% rename from public/assets/Developers/Safwan/context-stack-test.png rename to assets/Developers/Safwan/context-stack-test.png diff --git a/public/assets/Developers/Safwan/symbol-table-test.png b/assets/Developers/Safwan/symbol-table-test.png similarity index 100% rename from public/assets/Developers/Safwan/symbol-table-test.png rename to assets/Developers/Safwan/symbol-table-test.png diff --git a/public/assets/FloatingSVGs/flathub-1.svg b/assets/FloatingSVGs/flathub-1.svg similarity index 100% rename from public/assets/FloatingSVGs/flathub-1.svg rename to assets/FloatingSVGs/flathub-1.svg diff --git a/public/assets/FloatingSVGs/flathub-2.svg b/assets/FloatingSVGs/flathub-2.svg similarity index 100% rename from public/assets/FloatingSVGs/flathub-2.svg rename to assets/FloatingSVGs/flathub-2.svg diff --git a/public/assets/FloatingSVGs/music-block-1.svg b/assets/FloatingSVGs/music-block-1.svg similarity index 100% rename from public/assets/FloatingSVGs/music-block-1.svg rename to assets/FloatingSVGs/music-block-1.svg diff --git a/public/assets/FloatingSVGs/music-block-2.svg b/assets/FloatingSVGs/music-block-2.svg similarity index 100% rename from public/assets/FloatingSVGs/music-block-2.svg rename to assets/FloatingSVGs/music-block-2.svg diff --git a/public/assets/FloatingSVGs/music-block-3.svg b/assets/FloatingSVGs/music-block-3.svg similarity index 100% rename from public/assets/FloatingSVGs/music-block-3.svg rename to assets/FloatingSVGs/music-block-3.svg diff --git a/public/assets/FloatingSVGs/sugarizer-1.svg b/assets/FloatingSVGs/sugarizer-1.svg similarity index 100% rename from public/assets/FloatingSVGs/sugarizer-1.svg rename to assets/FloatingSVGs/sugarizer-1.svg diff --git a/public/assets/FloatingSVGs/turtle-blocks-1.svg b/assets/FloatingSVGs/turtle-blocks-1.svg similarity index 100% rename from public/assets/FloatingSVGs/turtle-blocks-1.svg rename to assets/FloatingSVGs/turtle-blocks-1.svg diff --git a/public/assets/FloatingSVGs/turtle-blocks-2.svg b/assets/FloatingSVGs/turtle-blocks-2.svg similarity index 100% rename from public/assets/FloatingSVGs/turtle-blocks-2.svg rename to assets/FloatingSVGs/turtle-blocks-2.svg diff --git a/public/assets/Icons/arrow.svg b/assets/Icons/arrow.svg similarity index 100% rename from public/assets/Icons/arrow.svg rename to assets/Icons/arrow.svg diff --git a/public/assets/Icons/chat.svg b/assets/Icons/chat.svg similarity index 100% rename from public/assets/Icons/chat.svg rename to assets/Icons/chat.svg diff --git a/public/assets/Icons/email.svg b/assets/Icons/email.svg similarity index 100% rename from public/assets/Icons/email.svg rename to assets/Icons/email.svg diff --git a/public/assets/Icons/logo.svg b/assets/Icons/logo.svg old mode 100755 new mode 100644 similarity index 100% rename from public/assets/Icons/logo.svg rename to assets/Icons/logo.svg diff --git a/public/assets/Icons/mail.svg b/assets/Icons/mail.svg similarity index 100% rename from public/assets/Icons/mail.svg rename to assets/Icons/mail.svg diff --git a/public/assets/Icons/pdf-icon.svg b/assets/Icons/pdf-icon.svg similarity index 100% rename from public/assets/Icons/pdf-icon.svg rename to assets/Icons/pdf-icon.svg diff --git a/public/assets/Icons/phone.svg b/assets/Icons/phone.svg similarity index 100% rename from public/assets/Icons/phone.svg rename to assets/Icons/phone.svg diff --git a/public/assets/ImageScreenshots/Demonstration_of_Sugar_on_RaspberryPi.png b/assets/ImageScreenshots/Demonstration_of_Sugar_on_RaspberryPi.png similarity index 100% rename from public/assets/ImageScreenshots/Demonstration_of_Sugar_on_RaspberryPi.png rename to assets/ImageScreenshots/Demonstration_of_Sugar_on_RaspberryPi.png diff --git a/public/assets/ImageScreenshots/Devin_Ulibarri_with_Sugar_Learning_Desktop.png b/assets/ImageScreenshots/Devin_Ulibarri_with_Sugar_Learning_Desktop.png similarity index 100% rename from public/assets/ImageScreenshots/Devin_Ulibarri_with_Sugar_Learning_Desktop.png rename to assets/ImageScreenshots/Devin_Ulibarri_with_Sugar_Learning_Desktop.png diff --git a/public/assets/ImageScreenshots/Generative_AI_development_Demos_by_Sugar_labs.png b/assets/ImageScreenshots/Generative_AI_development_Demos_by_Sugar_labs.png similarity index 100% rename from public/assets/ImageScreenshots/Generative_AI_development_Demos_by_Sugar_labs.png rename to assets/ImageScreenshots/Generative_AI_development_Demos_by_Sugar_labs.png diff --git a/public/assets/ImageScreenshots/Kenya_Student_using_Sugarizer.png b/assets/ImageScreenshots/Kenya_Student_using_Sugarizer.png similarity index 100% rename from public/assets/ImageScreenshots/Kenya_Student_using_Sugarizer.png rename to assets/ImageScreenshots/Kenya_Student_using_Sugarizer.png diff --git a/public/assets/ImageScreenshots/LLM_Mock_Chatbot_in_Speak_Activity.png b/assets/ImageScreenshots/LLM_Mock_Chatbot_in_Speak_Activity.png similarity index 100% rename from public/assets/ImageScreenshots/LLM_Mock_Chatbot_in_Speak_Activity.png rename to assets/ImageScreenshots/LLM_Mock_Chatbot_in_Speak_Activity.png diff --git a/public/assets/ImageScreenshots/Sugar_OS.png b/assets/ImageScreenshots/Sugar_OS.png similarity index 100% rename from public/assets/ImageScreenshots/Sugar_OS.png rename to assets/ImageScreenshots/Sugar_OS.png diff --git a/public/assets/ImageScreenshots/Sugar_OS_on_R_pi.png b/assets/ImageScreenshots/Sugar_OS_on_R_pi.png similarity index 100% rename from public/assets/ImageScreenshots/Sugar_OS_on_R_pi.png rename to assets/ImageScreenshots/Sugar_OS_on_R_pi.png diff --git a/public/assets/ImageScreenshots/Sugar_on_a_Stick_from_USB_Memory_Direct.png b/assets/ImageScreenshots/Sugar_on_a_Stick_from_USB_Memory_Direct.png similarity index 100% rename from public/assets/ImageScreenshots/Sugar_on_a_Stick_from_USB_Memory_Direct.png rename to assets/ImageScreenshots/Sugar_on_a_Stick_from_USB_Memory_Direct.png diff --git a/public/assets/ImageScreenshots/booting_Sugar_on_a_Stick.png b/assets/ImageScreenshots/booting_Sugar_on_a_Stick.png similarity index 100% rename from public/assets/ImageScreenshots/booting_Sugar_on_a_Stick.png rename to assets/ImageScreenshots/booting_Sugar_on_a_Stick.png diff --git a/public/assets/ImageScreenshots/demo_for_booting_Sugar_on_a_Stick.png b/assets/ImageScreenshots/demo_for_booting_Sugar_on_a_Stick.png similarity index 100% rename from public/assets/ImageScreenshots/demo_for_booting_Sugar_on_a_Stick.png rename to assets/ImageScreenshots/demo_for_booting_Sugar_on_a_Stick.png diff --git a/public/assets/Images/1.png b/assets/Images/1.png similarity index 100% rename from public/assets/Images/1.png rename to assets/Images/1.png diff --git a/public/assets/Images/2.png b/assets/Images/2.png similarity index 100% rename from public/assets/Images/2.png rename to assets/Images/2.png diff --git a/public/assets/Images/3.png b/assets/Images/3.png similarity index 100% rename from public/assets/Images/3.png rename to assets/Images/3.png diff --git a/public/assets/Images/4.png b/assets/Images/4.png similarity index 100% rename from public/assets/Images/4.png rename to assets/Images/4.png diff --git a/public/assets/Images/5.png b/assets/Images/5.png similarity index 100% rename from public/assets/Images/5.png rename to assets/Images/5.png diff --git a/public/assets/Images/6.png b/assets/Images/6.png similarity index 100% rename from public/assets/Images/6.png rename to assets/Images/6.png diff --git a/public/assets/Images/BoardMembers/Claudia.png b/assets/Images/BoardMembers/Claudia.png similarity index 100% rename from public/assets/Images/BoardMembers/Claudia.png rename to assets/Images/BoardMembers/Claudia.png diff --git a/public/assets/Images/BoardMembers/Devin.png b/assets/Images/BoardMembers/Devin.png similarity index 100% rename from public/assets/Images/BoardMembers/Devin.png rename to assets/Images/BoardMembers/Devin.png diff --git a/public/assets/Images/BoardMembers/Samson.jpeg b/assets/Images/BoardMembers/Samson.jpeg similarity index 100% rename from public/assets/Images/BoardMembers/Samson.jpeg rename to assets/Images/BoardMembers/Samson.jpeg diff --git a/public/assets/Images/BoardMembers/Silva.png b/assets/Images/BoardMembers/Silva.png similarity index 100% rename from public/assets/Images/BoardMembers/Silva.png rename to assets/Images/BoardMembers/Silva.png diff --git a/public/assets/Images/BoardMembers/Sumit.jpeg b/assets/Images/BoardMembers/Sumit.jpeg similarity index 100% rename from public/assets/Images/BoardMembers/Sumit.jpeg rename to assets/Images/BoardMembers/Sumit.jpeg diff --git a/public/assets/Images/BoardMembers/Walter.png b/assets/Images/BoardMembers/Walter.png similarity index 100% rename from public/assets/Images/BoardMembers/Walter.png rename to assets/Images/BoardMembers/Walter.png diff --git a/public/assets/Images/DonatePic.png b/assets/Images/DonatePic.png similarity index 100% rename from public/assets/Images/DonatePic.png rename to assets/Images/DonatePic.png diff --git a/public/assets/Images/DonateToSugarLabs.png b/assets/Images/DonateToSugarLabs.png similarity index 100% rename from public/assets/Images/DonateToSugarLabs.png rename to assets/Images/DonateToSugarLabs.png diff --git a/public/assets/Images/GSOC.png b/assets/Images/GSOC.png similarity index 100% rename from public/assets/Images/GSOC.png rename to assets/Images/GSOC.png diff --git a/public/assets/Images/GSOCxSpeak.png b/assets/Images/GSOCxSpeak.png similarity index 100% rename from public/assets/Images/GSOCxSpeak.png rename to assets/Images/GSOCxSpeak.png diff --git a/public/assets/Images/Mebin-test-FT-model-tesponses.png b/assets/Images/Mebin-test-FT-model-tesponses.png similarity index 100% rename from public/assets/Images/Mebin-test-FT-model-tesponses.png rename to assets/Images/Mebin-test-FT-model-tesponses.png diff --git a/public/assets/Images/SOAS.jpeg b/assets/Images/SOAS.jpeg similarity index 100% rename from public/assets/Images/SOAS.jpeg rename to assets/Images/SOAS.jpeg diff --git a/public/assets/Images/SugarNewsLogo.png b/assets/Images/SugarNewsLogo.png similarity index 100% rename from public/assets/Images/SugarNewsLogo.png rename to assets/Images/SugarNewsLogo.png diff --git a/public/assets/Images/aman-naik-week3-img1.png b/assets/Images/aman-naik-week3-img1.png similarity index 100% rename from public/assets/Images/aman-naik-week3-img1.png rename to assets/Images/aman-naik-week3-img1.png diff --git a/public/assets/Images/aman-naik-week3-img2.png b/assets/Images/aman-naik-week3-img2.png similarity index 100% rename from public/assets/Images/aman-naik-week3-img2.png rename to assets/Images/aman-naik-week3-img2.png diff --git a/public/assets/Images/aman-naik-week4-img1.png b/assets/Images/aman-naik-week4-img1.png similarity index 100% rename from public/assets/Images/aman-naik-week4-img1.png rename to assets/Images/aman-naik-week4-img1.png diff --git a/public/assets/Images/aman-naik-week4-img2.png b/assets/Images/aman-naik-week4-img2.png similarity index 100% rename from public/assets/Images/aman-naik-week4-img2.png rename to assets/Images/aman-naik-week4-img2.png diff --git a/public/assets/Images/aman-naik-week5-img1.png b/assets/Images/aman-naik-week5-img1.png similarity index 100% rename from public/assets/Images/aman-naik-week5-img1.png rename to assets/Images/aman-naik-week5-img1.png diff --git a/public/assets/Images/aman-naik-week5-img2.png b/assets/Images/aman-naik-week5-img2.png similarity index 100% rename from public/assets/Images/aman-naik-week5-img2.png rename to assets/Images/aman-naik-week5-img2.png diff --git a/public/assets/Images/aman-naik-week6-img1.png b/assets/Images/aman-naik-week6-img1.png similarity index 100% rename from public/assets/Images/aman-naik-week6-img1.png rename to assets/Images/aman-naik-week6-img1.png diff --git a/public/assets/Images/aman-naik-week6-img2.png b/assets/Images/aman-naik-week6-img2.png similarity index 100% rename from public/assets/Images/aman-naik-week6-img2.png rename to assets/Images/aman-naik-week6-img2.png diff --git a/public/assets/Images/aman_naik_week2_img1.png b/assets/Images/aman_naik_week2_img1.png similarity index 100% rename from public/assets/Images/aman_naik_week2_img1.png rename to assets/Images/aman_naik_week2_img1.png diff --git a/public/assets/Images/aman_naik_week2_img2.png b/assets/Images/aman_naik_week2_img2.png similarity index 100% rename from public/assets/Images/aman_naik_week2_img2.png rename to assets/Images/aman_naik_week2_img2.png diff --git a/public/assets/Images/c4gt_DMP.png b/assets/Images/c4gt_DMP.png similarity index 100% rename from public/assets/Images/c4gt_DMP.png rename to assets/Images/c4gt_DMP.png diff --git a/public/assets/Images/collision.png b/assets/Images/collision.png similarity index 100% rename from public/assets/Images/collision.png rename to assets/Images/collision.png diff --git a/public/assets/Images/collisionVisual.png b/assets/Images/collisionVisual.png similarity index 100% rename from public/assets/Images/collisionVisual.png rename to assets/Images/collisionVisual.png diff --git a/public/assets/Images/discuss.jpeg b/assets/Images/discuss.jpeg similarity index 100% rename from public/assets/Images/discuss.jpeg rename to assets/Images/discuss.jpeg diff --git a/public/assets/Images/dragAroundWorkspace.png b/assets/Images/dragAroundWorkspace.png similarity index 100% rename from public/assets/Images/dragAroundWorkspace.png rename to assets/Images/dragAroundWorkspace.png diff --git a/public/assets/Images/dragFromPallette.png b/assets/Images/dragFromPallette.png similarity index 100% rename from public/assets/Images/dragFromPallette.png rename to assets/Images/dragFromPallette.png diff --git a/public/assets/Images/expression-bricks.png b/assets/Images/expression-bricks.png similarity index 100% rename from public/assets/Images/expression-bricks.png rename to assets/Images/expression-bricks.png diff --git a/public/assets/Images/faq.png b/assets/Images/faq.png similarity index 100% rename from public/assets/Images/faq.png rename to assets/Images/faq.png diff --git a/public/assets/Images/gtk4drawing.png b/assets/Images/gtk4drawing.png similarity index 100% rename from public/assets/Images/gtk4drawing.png rename to assets/Images/gtk4drawing.png diff --git a/public/assets/Images/learn.jpg b/assets/Images/learn.jpg similarity index 100% rename from public/assets/Images/learn.jpg rename to assets/Images/learn.jpg diff --git a/public/assets/Images/mb4-Palette.png b/assets/Images/mb4-Palette.png similarity index 100% rename from public/assets/Images/mb4-Palette.png rename to assets/Images/mb4-Palette.png diff --git a/public/assets/Images/nested-bricks.png b/assets/Images/nested-bricks.png similarity index 100% rename from public/assets/Images/nested-bricks.png rename to assets/Images/nested-bricks.png diff --git a/public/assets/Images/pippy_debug-terminal.png b/assets/Images/pippy_debug-terminal.png similarity index 100% rename from public/assets/Images/pippy_debug-terminal.png rename to assets/Images/pippy_debug-terminal.png diff --git a/public/assets/Images/pippy_markdown-parser.png b/assets/Images/pippy_markdown-parser.png similarity index 100% rename from public/assets/Images/pippy_markdown-parser.png rename to assets/Images/pippy_markdown-parser.png diff --git a/public/assets/Images/pippy_output-terminal.png b/assets/Images/pippy_output-terminal.png similarity index 100% rename from public/assets/Images/pippy_output-terminal.png rename to assets/Images/pippy_output-terminal.png diff --git a/public/assets/Images/pippy_run&debug.png b/assets/Images/pippy_run&debug.png similarity index 100% rename from public/assets/Images/pippy_run&debug.png rename to assets/Images/pippy_run&debug.png diff --git a/public/assets/Images/simple-bricks.png b/assets/Images/simple-bricks.png similarity index 100% rename from public/assets/Images/simple-bricks.png rename to assets/Images/simple-bricks.png diff --git a/public/assets/Images/storybook_argument_bricks.png b/assets/Images/storybook_argument_bricks.png similarity index 100% rename from public/assets/Images/storybook_argument_bricks.png rename to assets/Images/storybook_argument_bricks.png diff --git a/public/assets/Images/storybook_compundBrick_multipleLevels.png b/assets/Images/storybook_compundBrick_multipleLevels.png similarity index 100% rename from public/assets/Images/storybook_compundBrick_multipleLevels.png rename to assets/Images/storybook_compundBrick_multipleLevels.png diff --git a/public/assets/Images/storybook_label_Bbox.png b/assets/Images/storybook_label_Bbox.png similarity index 100% rename from public/assets/Images/storybook_label_Bbox.png rename to assets/Images/storybook_label_Bbox.png diff --git a/public/assets/Images/storybook_nested_Bbox.png b/assets/Images/storybook_nested_Bbox.png similarity index 100% rename from public/assets/Images/storybook_nested_Bbox.png rename to assets/Images/storybook_nested_Bbox.png diff --git a/public/assets/Images/storybook_nested_bricks.png b/assets/Images/storybook_nested_bricks.png similarity index 100% rename from public/assets/Images/storybook_nested_bricks.png rename to assets/Images/storybook_nested_bricks.png diff --git a/public/assets/Images/storybook_stacked_bricks.png b/assets/Images/storybook_stacked_bricks.png similarity index 100% rename from public/assets/Images/storybook_stacked_bricks.png rename to assets/Images/storybook_stacked_bricks.png diff --git a/public/assets/Images/student.png b/assets/Images/student.png similarity index 100% rename from public/assets/Images/student.png rename to assets/Images/student.png diff --git a/public/assets/Images/student10.png b/assets/Images/student10.png similarity index 100% rename from public/assets/Images/student10.png rename to assets/Images/student10.png diff --git a/public/assets/Images/student11.png b/assets/Images/student11.png similarity index 100% rename from public/assets/Images/student11.png rename to assets/Images/student11.png diff --git a/public/assets/Images/student12.png b/assets/Images/student12.png similarity index 100% rename from public/assets/Images/student12.png rename to assets/Images/student12.png diff --git a/public/assets/Images/student13.png b/assets/Images/student13.png similarity index 100% rename from public/assets/Images/student13.png rename to assets/Images/student13.png diff --git a/public/assets/Images/student2.png b/assets/Images/student2.png similarity index 100% rename from public/assets/Images/student2.png rename to assets/Images/student2.png diff --git a/public/assets/Images/student3.png b/assets/Images/student3.png similarity index 100% rename from public/assets/Images/student3.png rename to assets/Images/student3.png diff --git a/public/assets/Images/student4.png b/assets/Images/student4.png similarity index 100% rename from public/assets/Images/student4.png rename to assets/Images/student4.png diff --git a/public/assets/Images/student5.png b/assets/Images/student5.png similarity index 100% rename from public/assets/Images/student5.png rename to assets/Images/student5.png diff --git a/public/assets/Images/student6.png b/assets/Images/student6.png similarity index 100% rename from public/assets/Images/student6.png rename to assets/Images/student6.png diff --git a/public/assets/Images/student7.png b/assets/Images/student7.png similarity index 100% rename from public/assets/Images/student7.png rename to assets/Images/student7.png diff --git a/public/assets/Images/student8.png b/assets/Images/student8.png similarity index 100% rename from public/assets/Images/student8.png rename to assets/Images/student8.png diff --git a/public/assets/Images/student9.png b/assets/Images/student9.png similarity index 100% rename from public/assets/Images/student9.png rename to assets/Images/student9.png diff --git a/public/assets/Images/sugarnews.jpeg b/assets/Images/sugarnews.jpeg similarity index 100% rename from public/assets/Images/sugarnews.jpeg rename to assets/Images/sugarnews.jpeg diff --git a/public/assets/Images/teach.jpg b/assets/Images/teach.jpg similarity index 100% rename from public/assets/Images/teach.jpg rename to assets/Images/teach.jpg diff --git a/public/assets/Images/teach1.jpg b/assets/Images/teach1.jpg similarity index 100% rename from public/assets/Images/teach1.jpg rename to assets/Images/teach1.jpg diff --git a/public/assets/Images/teach2.jpeg b/assets/Images/teach2.jpeg similarity index 100% rename from public/assets/Images/teach2.jpeg rename to assets/Images/teach2.jpeg diff --git a/public/assets/Images/teach4.png b/assets/Images/teach4.png similarity index 100% rename from public/assets/Images/teach4.png rename to assets/Images/teach4.png diff --git a/public/assets/Images/teach5.png b/assets/Images/teach5.png similarity index 100% rename from public/assets/Images/teach5.png rename to assets/Images/teach5.png diff --git a/public/assets/Images/teach6.png b/assets/Images/teach6.png similarity index 100% rename from public/assets/Images/teach6.png rename to assets/Images/teach6.png diff --git a/public/assets/Images/tuner-interface-week4.png b/assets/Images/tuner-interface-week4.png similarity index 100% rename from public/assets/Images/tuner-interface-week4.png rename to assets/Images/tuner-interface-week4.png diff --git a/public/assets/LinksLogos/conduct.svg b/assets/LinksLogos/conduct.svg similarity index 100% rename from public/assets/LinksLogos/conduct.svg rename to assets/LinksLogos/conduct.svg diff --git a/public/assets/LinksLogos/developer.svg b/assets/LinksLogos/developer.svg similarity index 100% rename from public/assets/LinksLogos/developer.svg rename to assets/LinksLogos/developer.svg diff --git a/public/assets/LinksLogos/github.svg b/assets/LinksLogos/github.svg similarity index 100% rename from public/assets/LinksLogos/github.svg rename to assets/LinksLogos/github.svg diff --git a/public/assets/LinksLogos/mailingList.svg b/assets/LinksLogos/mailingList.svg similarity index 100% rename from public/assets/LinksLogos/mailingList.svg rename to assets/LinksLogos/mailingList.svg diff --git a/public/assets/LinksLogos/matrix.svg b/assets/LinksLogos/matrix.svg similarity index 100% rename from public/assets/LinksLogos/matrix.svg rename to assets/LinksLogos/matrix.svg diff --git a/public/assets/LinksLogos/projects.svg b/assets/LinksLogos/projects.svg similarity index 100% rename from public/assets/LinksLogos/projects.svg rename to assets/LinksLogos/projects.svg diff --git a/public/assets/LinksLogos/sugarizer-1.svg b/assets/LinksLogos/sugarizer-1.svg similarity index 100% rename from public/assets/LinksLogos/sugarizer-1.svg rename to assets/LinksLogos/sugarizer-1.svg diff --git a/public/assets/LinksLogos/translation.svg b/assets/LinksLogos/translation.svg similarity index 100% rename from public/assets/LinksLogos/translation.svg rename to assets/LinksLogos/translation.svg diff --git a/public/assets/Products/sugarTshirtBlue.jpeg b/assets/Products/sugarTshirtBlue.jpeg similarity index 100% rename from public/assets/Products/sugarTshirtBlue.jpeg rename to assets/Products/sugarTshirtBlue.jpeg diff --git a/public/assets/Products/sugarTshirtGreen.jpeg b/assets/Products/sugarTshirtGreen.jpeg similarity index 100% rename from public/assets/Products/sugarTshirtGreen.jpeg rename to assets/Products/sugarTshirtGreen.jpeg diff --git a/public/assets/Products/sugarTshirtPurple.jpeg b/assets/Products/sugarTshirtPurple.jpeg similarity index 100% rename from public/assets/Products/sugarTshirtPurple.jpeg rename to assets/Products/sugarTshirtPurple.jpeg diff --git a/public/assets/Products/sugarTshirtWhite.jpeg b/assets/Products/sugarTshirtWhite.jpeg similarity index 100% rename from public/assets/Products/sugarTshirtWhite.jpeg rename to assets/Products/sugarTshirtWhite.jpeg diff --git a/public/assets/Products/sugarlabsUsb.jpeg b/assets/Products/sugarlabsUsb.jpeg similarity index 100% rename from public/assets/Products/sugarlabsUsb.jpeg rename to assets/Products/sugarlabsUsb.jpeg diff --git a/public/assets/QuickAnswers/Headset.svg b/assets/QuickAnswers/Headset.svg similarity index 100% rename from public/assets/QuickAnswers/Headset.svg rename to assets/QuickAnswers/Headset.svg diff --git a/public/assets/QuickAnswers/card-slash.svg b/assets/QuickAnswers/card-slash.svg similarity index 100% rename from public/assets/QuickAnswers/card-slash.svg rename to assets/QuickAnswers/card-slash.svg diff --git a/public/assets/QuickAnswers/cards.svg b/assets/QuickAnswers/cards.svg similarity index 100% rename from public/assets/QuickAnswers/cards.svg rename to assets/QuickAnswers/cards.svg diff --git a/public/assets/QuickAnswers/monitor-mobbile.svg b/assets/QuickAnswers/monitor-mobbile.svg similarity index 100% rename from public/assets/QuickAnswers/monitor-mobbile.svg rename to assets/QuickAnswers/monitor-mobbile.svg diff --git a/public/assets/QuickAnswers/people.svg b/assets/QuickAnswers/people.svg similarity index 100% rename from public/assets/QuickAnswers/people.svg rename to assets/QuickAnswers/people.svg diff --git a/public/assets/QuickAnswers/task.svg b/assets/QuickAnswers/task.svg similarity index 100% rename from public/assets/QuickAnswers/task.svg rename to assets/QuickAnswers/task.svg diff --git a/public/assets/Stats/ActivitiesDownloaded.svg b/assets/Stats/ActivitiesDownloaded.svg similarity index 100% rename from public/assets/Stats/ActivitiesDownloaded.svg rename to assets/Stats/ActivitiesDownloaded.svg diff --git a/public/assets/Stats/HeartLeft.svg b/assets/Stats/HeartLeft.svg similarity index 100% rename from public/assets/Stats/HeartLeft.svg rename to assets/Stats/HeartLeft.svg diff --git a/public/assets/Stats/HeartRight.svg b/assets/Stats/HeartRight.svg similarity index 100% rename from public/assets/Stats/HeartRight.svg rename to assets/Stats/HeartRight.svg diff --git a/public/assets/Stats/KidsWhoseLife.svg b/assets/Stats/KidsWhoseLife.svg similarity index 100% rename from public/assets/Stats/KidsWhoseLife.svg rename to assets/Stats/KidsWhoseLife.svg diff --git a/public/assets/Stats/Languages.svg b/assets/Stats/Languages.svg similarity index 100% rename from public/assets/Stats/Languages.svg rename to assets/Stats/Languages.svg diff --git a/public/assets/Stats/MentorsHelping.svg b/assets/Stats/MentorsHelping.svg similarity index 100% rename from public/assets/Stats/MentorsHelping.svg rename to assets/Stats/MentorsHelping.svg diff --git a/public/assets/Stats/ProblemSolvingTasks.svg b/assets/Stats/ProblemSolvingTasks.svg similarity index 100% rename from public/assets/Stats/ProblemSolvingTasks.svg rename to assets/Stats/ProblemSolvingTasks.svg diff --git a/public/assets/Stats/ProjectsForTeaching.svg b/assets/Stats/ProjectsForTeaching.svg similarity index 100% rename from public/assets/Stats/ProjectsForTeaching.svg rename to assets/Stats/ProjectsForTeaching.svg diff --git a/public/assets/Stats/quote-icon.svg b/assets/Stats/quote-icon.svg similarity index 100% rename from public/assets/Stats/quote-icon.svg rename to assets/Stats/quote-icon.svg diff --git a/public/assets/TryMoreSvgs/android.svg b/assets/TryMoreSvgs/android.svg similarity index 100% rename from public/assets/TryMoreSvgs/android.svg rename to assets/TryMoreSvgs/android.svg diff --git a/public/assets/TryMoreSvgs/debian.svg b/assets/TryMoreSvgs/debian.svg similarity index 100% rename from public/assets/TryMoreSvgs/debian.svg rename to assets/TryMoreSvgs/debian.svg diff --git a/public/assets/TryMoreSvgs/deploy.svg b/assets/TryMoreSvgs/deploy.svg similarity index 100% rename from public/assets/TryMoreSvgs/deploy.svg rename to assets/TryMoreSvgs/deploy.svg diff --git a/public/assets/TryMoreSvgs/fedora.svg b/assets/TryMoreSvgs/fedora.svg similarity index 100% rename from public/assets/TryMoreSvgs/fedora.svg rename to assets/TryMoreSvgs/fedora.svg diff --git a/public/assets/TryMoreSvgs/ios.svg b/assets/TryMoreSvgs/ios.svg similarity index 100% rename from public/assets/TryMoreSvgs/ios.svg rename to assets/TryMoreSvgs/ios.svg diff --git a/public/assets/TryMoreSvgs/linux.svg b/assets/TryMoreSvgs/linux.svg similarity index 100% rename from public/assets/TryMoreSvgs/linux.svg rename to assets/TryMoreSvgs/linux.svg diff --git a/public/assets/TryMoreSvgs/mac.svg b/assets/TryMoreSvgs/mac.svg similarity index 100% rename from public/assets/TryMoreSvgs/mac.svg rename to assets/TryMoreSvgs/mac.svg diff --git a/public/assets/TryMoreSvgs/trisquel-community.svg b/assets/TryMoreSvgs/trisquel-community.svg similarity index 100% rename from public/assets/TryMoreSvgs/trisquel-community.svg rename to assets/TryMoreSvgs/trisquel-community.svg diff --git a/public/assets/TryMoreSvgs/trisquel-desktop.svg b/assets/TryMoreSvgs/trisquel-desktop.svg similarity index 100% rename from public/assets/TryMoreSvgs/trisquel-desktop.svg rename to assets/TryMoreSvgs/trisquel-desktop.svg diff --git a/public/assets/TryMoreSvgs/trisquel-documentation.svg b/assets/TryMoreSvgs/trisquel-documentation.svg similarity index 100% rename from public/assets/TryMoreSvgs/trisquel-documentation.svg rename to assets/TryMoreSvgs/trisquel-documentation.svg diff --git a/public/assets/TryMoreSvgs/ubuntu.svg b/assets/TryMoreSvgs/ubuntu.svg similarity index 100% rename from public/assets/TryMoreSvgs/ubuntu.svg rename to assets/TryMoreSvgs/ubuntu.svg diff --git a/public/assets/TryMoreSvgs/web.svg b/assets/TryMoreSvgs/web.svg similarity index 100% rename from public/assets/TryMoreSvgs/web.svg rename to assets/TryMoreSvgs/web.svg diff --git a/public/assets/TryMoreSvgs/windows.svg b/assets/TryMoreSvgs/windows.svg similarity index 100% rename from public/assets/TryMoreSvgs/windows.svg rename to assets/TryMoreSvgs/windows.svg diff --git a/public/assets/TryNowImages/boatsoasMockup.png b/assets/TryNowImages/boatsoasMockup.png similarity index 100% rename from public/assets/TryNowImages/boatsoasMockup.png rename to assets/TryNowImages/boatsoasMockup.png diff --git a/public/assets/TryNowImages/devin.png b/assets/TryNowImages/devin.png similarity index 100% rename from public/assets/TryNowImages/devin.png rename to assets/TryNowImages/devin.png diff --git a/public/assets/TryNowImages/flathub1.png b/assets/TryNowImages/flathub1.png similarity index 100% rename from public/assets/TryNowImages/flathub1.png rename to assets/TryNowImages/flathub1.png diff --git a/public/assets/TryNowImages/fpLogoCard2.png b/assets/TryNowImages/fpLogoCard2.png similarity index 100% rename from public/assets/TryNowImages/fpLogoCard2.png rename to assets/TryNowImages/fpLogoCard2.png diff --git a/public/assets/TryNowImages/fpLogoCard3.png b/assets/TryNowImages/fpLogoCard3.png similarity index 100% rename from public/assets/TryNowImages/fpLogoCard3.png rename to assets/TryNowImages/fpLogoCard3.png diff --git a/public/assets/TryNowImages/mbLogoCard1.png b/assets/TryNowImages/mbLogoCard1.png similarity index 100% rename from public/assets/TryNowImages/mbLogoCard1.png rename to assets/TryNowImages/mbLogoCard1.png diff --git a/public/assets/TryNowImages/mbLogoCard2.png b/assets/TryNowImages/mbLogoCard2.png similarity index 100% rename from public/assets/TryNowImages/mbLogoCard2.png rename to assets/TryNowImages/mbLogoCard2.png diff --git a/public/assets/TryNowImages/mbLogoCard3.png b/assets/TryNowImages/mbLogoCard3.png similarity index 100% rename from public/assets/TryNowImages/mbLogoCard3.png rename to assets/TryNowImages/mbLogoCard3.png diff --git a/public/assets/TryNowImages/mbLogoCard4.png b/assets/TryNowImages/mbLogoCard4.png similarity index 100% rename from public/assets/TryNowImages/mbLogoCard4.png rename to assets/TryNowImages/mbLogoCard4.png diff --git a/public/assets/TryNowImages/mbNumberedCard1.png b/assets/TryNowImages/mbNumberedCard1.png similarity index 100% rename from public/assets/TryNowImages/mbNumberedCard1.png rename to assets/TryNowImages/mbNumberedCard1.png diff --git a/public/assets/TryNowImages/mbNumberedCard2.png b/assets/TryNowImages/mbNumberedCard2.png similarity index 100% rename from public/assets/TryNowImages/mbNumberedCard2.png rename to assets/TryNowImages/mbNumberedCard2.png diff --git a/public/assets/TryNowImages/mbNumberedCard3.png b/assets/TryNowImages/mbNumberedCard3.png similarity index 100% rename from public/assets/TryNowImages/mbNumberedCard3.png rename to assets/TryNowImages/mbNumberedCard3.png diff --git a/public/assets/TryNowImages/mbText.png b/assets/TryNowImages/mbText.png similarity index 100% rename from public/assets/TryNowImages/mbText.png rename to assets/TryNowImages/mbText.png diff --git a/public/assets/TryNowImages/musicBlocks1.png b/assets/TryNowImages/musicBlocks1.png similarity index 100% rename from public/assets/TryNowImages/musicBlocks1.png rename to assets/TryNowImages/musicBlocks1.png diff --git a/public/assets/TryNowImages/musicBlocks2.png b/assets/TryNowImages/musicBlocks2.png similarity index 100% rename from public/assets/TryNowImages/musicBlocks2.png rename to assets/TryNowImages/musicBlocks2.png diff --git a/public/assets/TryNowImages/musicBlocks3.png b/assets/TryNowImages/musicBlocks3.png similarity index 100% rename from public/assets/TryNowImages/musicBlocks3.png rename to assets/TryNowImages/musicBlocks3.png diff --git a/public/assets/TryNowImages/musicBlocks4.png b/assets/TryNowImages/musicBlocks4.png similarity index 100% rename from public/assets/TryNowImages/musicBlocks4.png rename to assets/TryNowImages/musicBlocks4.png diff --git a/public/assets/TryNowImages/musicBlocksMockup.png b/assets/TryNowImages/musicBlocksMockup.png similarity index 100% rename from public/assets/TryNowImages/musicBlocksMockup.png rename to assets/TryNowImages/musicBlocksMockup.png diff --git a/public/assets/TryNowImages/musicMockup.png b/assets/TryNowImages/musicMockup.png similarity index 100% rename from public/assets/TryNowImages/musicMockup.png rename to assets/TryNowImages/musicMockup.png diff --git a/public/assets/TryNowImages/raspberry.jpg b/assets/TryNowImages/raspberry.jpg similarity index 100% rename from public/assets/TryNowImages/raspberry.jpg rename to assets/TryNowImages/raspberry.jpg diff --git a/public/assets/TryNowImages/sachiko.png b/assets/TryNowImages/sachiko.png similarity index 100% rename from public/assets/TryNowImages/sachiko.png rename to assets/TryNowImages/sachiko.png diff --git a/public/assets/TryNowImages/step1.jpg b/assets/TryNowImages/step1.jpg similarity index 100% rename from public/assets/TryNowImages/step1.jpg rename to assets/TryNowImages/step1.jpg diff --git a/public/assets/TryNowImages/step2.jpg b/assets/TryNowImages/step2.jpg similarity index 100% rename from public/assets/TryNowImages/step2.jpg rename to assets/TryNowImages/step2.jpg diff --git a/public/assets/TryNowImages/step3.jpg b/assets/TryNowImages/step3.jpg similarity index 100% rename from public/assets/TryNowImages/step3.jpg rename to assets/TryNowImages/step3.jpg diff --git a/public/assets/TryNowImages/step4.jpg b/assets/TryNowImages/step4.jpg similarity index 100% rename from public/assets/TryNowImages/step4.jpg rename to assets/TryNowImages/step4.jpg diff --git a/public/assets/TryNowImages/step5.jpg b/assets/TryNowImages/step5.jpg similarity index 100% rename from public/assets/TryNowImages/step5.jpg rename to assets/TryNowImages/step5.jpg diff --git a/public/assets/TryNowImages/step6.jpg b/assets/TryNowImages/step6.jpg similarity index 100% rename from public/assets/TryNowImages/step6.jpg rename to assets/TryNowImages/step6.jpg diff --git a/public/assets/TryNowImages/step7.png b/assets/TryNowImages/step7.png similarity index 100% rename from public/assets/TryNowImages/step7.png rename to assets/TryNowImages/step7.png diff --git a/public/assets/TryNowImages/sugarizer.png b/assets/TryNowImages/sugarizer.png similarity index 100% rename from public/assets/TryNowImages/sugarizer.png rename to assets/TryNowImages/sugarizer.png diff --git a/public/assets/TryNowImages/sugarizerMockup.png b/assets/TryNowImages/sugarizerMockup.png similarity index 100% rename from public/assets/TryNowImages/sugarizerMockup.png rename to assets/TryNowImages/sugarizerMockup.png diff --git a/public/assets/TryNowImages/trisquel.png b/assets/TryNowImages/trisquel.png similarity index 100% rename from public/assets/TryNowImages/trisquel.png rename to assets/TryNowImages/trisquel.png diff --git a/public/assets/TryNowImages/trisquel2.png b/assets/TryNowImages/trisquel2.png similarity index 100% rename from public/assets/TryNowImages/trisquel2.png rename to assets/TryNowImages/trisquel2.png diff --git a/public/assets/TryNowImages/turtleBlocks.png b/assets/TryNowImages/turtleBlocks.png similarity index 100% rename from public/assets/TryNowImages/turtleBlocks.png rename to assets/TryNowImages/turtleBlocks.png diff --git a/public/assets/TryNowImages/turtleMockup.png b/assets/TryNowImages/turtleMockup.png similarity index 100% rename from public/assets/TryNowImages/turtleMockup.png rename to assets/TryNowImages/turtleMockup.png diff --git a/public/assets/TryNowImages/turtleblocks1.png b/assets/TryNowImages/turtleblocks1.png similarity index 100% rename from public/assets/TryNowImages/turtleblocks1.png rename to assets/TryNowImages/turtleblocks1.png diff --git a/public/assets/TryNowImages/turtleblocks2.png b/assets/TryNowImages/turtleblocks2.png similarity index 100% rename from public/assets/TryNowImages/turtleblocks2.png rename to assets/TryNowImages/turtleblocks2.png diff --git a/public/assets/TryNowImages/walter.png b/assets/TryNowImages/walter.png similarity index 100% rename from public/assets/TryNowImages/walter.png rename to assets/TryNowImages/walter.png diff --git a/public/assets/TryNowImages/yuUkai.png b/assets/TryNowImages/yuUkai.png similarity index 100% rename from public/assets/TryNowImages/yuUkai.png rename to assets/TryNowImages/yuUkai.png diff --git a/public/assets/Volunteer/volunteer-1.png b/assets/Volunteer/volunteer-1.png similarity index 100% rename from public/assets/Volunteer/volunteer-1.png rename to assets/Volunteer/volunteer-1.png diff --git a/public/assets/Volunteer/volunteer-2.png b/assets/Volunteer/volunteer-2.png similarity index 100% rename from public/assets/Volunteer/volunteer-2.png rename to assets/Volunteer/volunteer-2.png diff --git a/public/assets/Volunteer/volunteer-3.png b/assets/Volunteer/volunteer-3.png similarity index 100% rename from public/assets/Volunteer/volunteer-3.png rename to assets/Volunteer/volunteer-3.png diff --git a/public/assets/Volunteer/volunteer-group.png b/assets/Volunteer/volunteer-group.png similarity index 100% rename from public/assets/Volunteer/volunteer-group.png rename to assets/Volunteer/volunteer-group.png diff --git a/assets/index-M22Aoh9H.js b/assets/index-M22Aoh9H.js new file mode 100644 index 00000000..ba19e4b8 --- /dev/null +++ b/assets/index-M22Aoh9H.js @@ -0,0 +1,127 @@ +import{j as e,N as as,A as Y,m as a,L as F,r as c,a as De,t as rs,c as is,u as os,b as ge,d as ye,S as wt,T as Ht,e as Fe,G as dt,f as mt,g as st,I as ns,h as Ut,C as ls,i as vt,k as xe,M as cs,l as ds,n as ms,o as us,p as hs,q as ze,s as gs,v as xs,w as ps,x as ut,U as Gt,B as Ee,y as at,z as ht,D as Wt,F as bs,E as rt,H as gt,J as yt,K as jt,O as it,P as He,Q as fs,R as Nt,V as kt,W as ws,X as vs,Y as Ue,Z as ys,_ as js,$ as Ns,a0 as ks}from"./vendor-19NJoZqN.js";(function(){const i=document.createElement("link").relList;if(i&&i.supports&&i.supports("modulepreload"))return;for(const t of document.querySelectorAll('link[rel="modulepreload"]'))o(t);new MutationObserver(t=>{for(const l of t)if(l.type==="childList")for(const d of l.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&o(d)}).observe(document,{childList:!0,subtree:!0});function r(t){const l={};return t.integrity&&(l.integrity=t.integrity),t.referrerPolicy&&(l.referrerPolicy=t.referrerPolicy),t.crossOrigin==="use-credentials"?l.credentials="include":t.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function o(t){if(t.ep)return;t.ep=!0;const l=r(t);fetch(t.href,l)}})();const _s={"/go/Sugar_Labs/Donate":"/donate","/booting-soas":"/bootablesoas"},Ss=Object.entries(_s).map(([s,i])=>({path:s,element:e.jsx(as,{to:i,replace:!0})})),Ls=""+new URL("Icons/logo.svg",import.meta.url).href,Cs=({id:s,label:i,items:r,isActive:o,setActive:t,onNavigate:l})=>e.jsxs("div",{className:"relative",onMouseEnter:()=>t(s),onMouseLeave:()=>t(null),children:[e.jsxs("button",{className:`px-2 lg:px-3 py-2 text-gray-700 hover:text-blue-600 font-medium rounded-md + transition-all duration-200 hover:bg-gray-50 flex items-center space-x-1 + ${o?"text-blue-600":""}`,"aria-expanded":o,children:[e.jsx("span",{children:i}),e.jsx("svg",{className:`w-4 h-4 transition-transform duration-200 ${o?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),e.jsx(Y,{children:o&&e.jsx(a.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},exit:{opacity:0,y:10},transition:{duration:.2},className:"absolute left-0 mt-2 w-56 rounded-xl bg-white shadow-xl ring-1 ring-black ring-opacity-5 overflow-hidden",children:e.jsx("div",{className:"py-2",children:r.map(d=>e.jsxs(F,{to:d.path,onClick:l,className:`group flex items-center px-4 py-3 text-sm text-gray-700 hover:bg-gray-50 + transition-all duration-200 hover:text-blue-600`,children:[e.jsx("span",{className:`w-2 h-2 rounded-full bg-blue-600 opacity-0 group-hover:opacity-100 + transition-all duration-200 mr-2 transform scale-0 group-hover:scale-100`}),d.label]},d.path))})})})]}),Ae={dropdowns:{about:{label:"About",items:[{label:"About Us",path:"/about-us"},{label:"Leadership",path:"/leadership"},{label:"Contact Us",path:"/contact-us"},{label:"FAQs",path:"/faqs"}]}},links:[{label:"News",path:"/news"},{label:"Merchandise",path:"/products"},{label:"Donate",path:"/donate"},{label:"Join Development",path:"/join-development"},{label:"Volunteer",path:"/volunteer"}]},A=()=>{const[s,i]=c.useState(!1),[r,o]=c.useState(!1),[t,l]=c.useState(null);c.useEffect(()=>{const h=()=>i(window.scrollY>20);return window.addEventListener("scroll",h),()=>window.removeEventListener("scroll",h)},[]),c.useEffect(()=>(r?document.body.style.overflow="hidden":document.body.style.overflow="",()=>{document.body.style.overflow=""}),[r]),c.useEffect(()=>{const h=w=>{w.key==="Escape"&&(l(null),o(!1))};return window.addEventListener("keydown",h),()=>window.removeEventListener("keydown",h)},[]);const d=()=>{o(!1),l(null)};return e.jsxs(e.Fragment,{children:[e.jsx("header",{className:`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${s?"backdrop-blur-md bg-white/90 shadow-lg":"bg-white"}`,children:e.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:e.jsxs("div",{className:"flex justify-between items-center h-16 md:h-20",children:[e.jsx(F,{to:"/",className:"flex-shrink-0 flex items-center",onClick:d,children:e.jsx("img",{src:Ls,alt:"Sugar Labs",className:"h-8 md:h-12 w-auto transition-transform hover:scale-105"})}),e.jsx("button",{className:"md:hidden relative w-10 h-10 focus:outline-none z-50",onClick:()=>o(!r),"aria-label":"Toggle menu","aria-expanded":r,children:e.jsxs("div",{className:"absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2",children:[e.jsx("span",{className:`block w-6 h-0.5 bg-gray-600 transition-all duration-300 ${r?"rotate-45 translate-y-1.5":"translate-y-[-4px]"}`}),e.jsx("span",{className:`block w-6 h-0.5 bg-gray-600 transition-all duration-300 mt-1 ${r?"opacity-0":""}`}),e.jsx("span",{className:`block w-6 h-0.5 bg-gray-600 transition-all duration-300 mt-1 ${r?"-rotate-45 -translate-y-1.5":"translate-y-[4px]"}`})]})}),e.jsxs("nav",{className:"hidden md:flex md:items-center md:space-x-4 lg:space-x-8",children:[Object.entries(Ae.dropdowns).map(([h,w])=>e.jsx(Cs,{id:h,label:w.label,items:w.items,isActive:t===h,setActive:l,onNavigate:d},h)),Ae.links.map(h=>e.jsx(F,{to:h.path,className:`px-2 lg:px-3 py-2 text-gray-700 hover:text-blue-600 font-medium rounded-md + transition-all duration-200 hover:bg-gray-50 text-sm lg:text-base`,onClick:d,children:h.label},h.label)),e.jsx(F,{to:"/try-sugar",className:`inline-flex items-center px-4 lg:px-6 py-2 lg:py-2.5 rounded-full font-semibold text-white + bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 hover:to-blue-800 + transition-all duration-300 transform hover:scale-105 hover:shadow-lg + focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 text-sm lg:text-base`,onClick:d,children:"TRY NOW"})]})]})})}),e.jsx(Y,{children:r&&e.jsx(a.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.2},className:"fixed inset-0 bg-black/30 md:hidden z-40",onClick:()=>o(!1)})}),e.jsx(Ts,{isOpen:r,activeDropdown:t,setActiveDropdown:l,onClose:d}),e.jsx("div",{className:"h-16 md:h-20"})]})},Ts=({isOpen:s,activeDropdown:i,setActiveDropdown:r,onClose:o})=>e.jsx(Y,{children:s&&e.jsx(a.div,{initial:{opacity:0,x:"100%"},animate:{opacity:1,x:0},exit:{opacity:0,x:"100%"},transition:{type:"tween",duration:.3},className:`fixed md:hidden top-0 right-0 bottom-0 w-[80%] max-w-sm bg-white shadow-xl z-40 + flex flex-col h-full`,children:e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("div",{className:"h-16"}),e.jsx("div",{className:"flex-1 overflow-y-auto py-2",children:e.jsxs("div",{className:"space-y-4",children:[Object.entries(Ae.dropdowns).map(([t,l])=>e.jsxs("div",{className:"space-y-1 px-2",children:[e.jsxs("button",{onClick:()=>r(i===t?null:t),className:`flex items-center justify-between w-full text-left px-2 py-2 + text-gray-700 font-medium rounded-lg hover:bg-gray-50`,"aria-expanded":i===t,children:[e.jsx("span",{children:l.label}),e.jsx("svg",{className:`w-5 h-5 transition-transform duration-200 ${i===t?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),e.jsx(Y,{children:i===t&&e.jsx(a.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:{duration:.2},className:"overflow-hidden",children:e.jsx("div",{className:"pl-4 space-y-1 pb-2",children:l.items.map(d=>e.jsx(F,{to:d.path,onClick:o,className:`flex items-center px-4 py-2 text-sm text-gray-600 + rounded-lg hover:bg-gray-50 hover:text-blue-600`,children:d.label},d.path))})})})]},t)),Ae.links.map(t=>e.jsx(F,{to:t.path,onClick:o,className:`block px-4 py-2 text-gray-700 font-medium rounded-lg + hover:bg-gray-50 hover:text-blue-600`,children:t.label},t.label))]})}),e.jsx("div",{className:"p-4 border-t border-gray-200 sticky bottom-0 bg-white",children:e.jsx(F,{to:"/try-sugar",onClick:o,className:`flex items-center justify-center px-6 py-3 rounded-xl font-semibold + text-white bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 + hover:to-blue-800 transition-all duration-300 w-full`,children:"TRY NOW"})})]})})}),$t=""+new URL("social/github.svg",import.meta.url).href,Is=""+new URL("social/x.svg",import.meta.url).href,Es=""+new URL("social/instagram.svg",import.meta.url).href,As=""+new URL("social/linkedin.svg",import.meta.url).href,Ms=""+new URL("social/facebook.svg",import.meta.url).href,Ps=""+new URL("social/youtube.svg",import.meta.url).href,Rs=""+new URL("social/mastodon.svg",import.meta.url).href,Ds=""+new URL("social/medium.svg",import.meta.url).href,qt=[{name:"GitHub",href:"https://github.com/sugarlabs",icon:$t},{name:"X",href:"https://x.com/sugar_labs",icon:Is},{name:"Instagram",href:"https://www.instagram.com/sugarlabsforall/",icon:Es},{name:"LinkedIn",href:"https://www.linkedin.com/company/sugar-labs",icon:As},{name:"Facebook",href:"https://www.facebook.com/SugarLabsforall/timeline/",icon:Ms},{name:"YouTube",href:"https://www.youtube.com/channel/UCfsR9AEb7HuPRAc14jfiI6g/featured",icon:Ps},{name:"Mastodon",href:"https://mastodon.social/@sugar_labs",icon:Rs},{name:"Medium",href:"https://medium.com/@sugarlabs",icon:Ds}],Fs=[{to:"/more/culture",text:"Culture and pedagogy"},{to:"/more/students",text:"For Students"},{to:"/more/school-admin",text:"For School Administrators"},{to:"/more/parents",text:"For Parents"},{to:"/join-development",text:"For Developers"},{to:"/news/sugar-stories",text:"Sugar Stories"},{to:"/musicblocks",text:"Music Blocks"},{to:"/turtleblocks",text:"Turtle Blocks JS"}],Bs=[{to:"/join-development",text:"Read about development"},{href:"https://buttondown.com/sugarlabs",text:"Join mailing list"},{href:"https://help.sugarlabs.org/en/",text:"Documentation"},{href:"https://matrix.to/#/#sugar:matrix.org",text:"Chat with us on Matrix"},{href:"https://wiki.sugarlabs.org/go/Development_Team/Source_Code",text:"Development code"},{href:"https://translate.sugarlabs.org/",text:"Translation Platform"},{href:"https://wiki.sugarlabs.org/go/Welcome_to_the_Sugar_Labs_wiki",text:"Sugar Labs Wiki"}],Os=[{to:"/about-us",text:"About Us"},{to:"/volunteer",text:"Get Involved"},{to:"/donate",text:"Donate to Sugar Labs"},{to:"/leadership",text:"Leadership and Governance"},{to:"/contact-us",text:"Contact Us"}],M=()=>e.jsx(e.Fragment,{children:e.jsxs("footer",{className:"bg-gradient-to-b from-gray-900 to-gray-950 text-gray-300 py-10 sm:py-16 px-4 sm:px-6 relative",children:[e.jsx("div",{className:"absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500"}),e.jsxs("div",{className:"max-w-7xl mx-auto",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-12 gap-8 sm:gap-10 mb-8 sm:mb-12",children:[e.jsxs("div",{className:"lg:col-span-3",children:[e.jsxs("h2",{className:"text-lg sm:text-xl font-bold mb-4 sm:mb-6 text-white relative inline-block",children:["Resources",e.jsx("span",{className:"absolute -bottom-2 left-0 w-8 sm:w-12 h-1 bg-blue-500"})]}),e.jsx("ul",{className:"space-y-2 sm:space-y-3",children:Fs.map(s=>e.jsx("li",{children:e.jsxs(F,{to:`${s.to}`,className:"hover:text-white transition-all duration-300 flex items-center group",children:[e.jsx("span",{className:"w-0 group-hover:w-2 h-2 bg-blue-500 rounded-full mr-0 group-hover:mr-2 transition-all duration-300"}),s.text]})},s.to))})]}),e.jsxs("div",{className:"lg:col-span-3",children:[e.jsxs("h2",{className:"text-lg sm:text-xl font-bold mb-4 sm:mb-6 text-white relative inline-block",children:["Development",e.jsx("span",{className:"absolute -bottom-2 left-0 w-8 sm:w-12 h-1 bg-purple-500"})]}),e.jsx("ul",{className:"space-y-2 sm:space-y-3",children:Bs.map(s=>e.jsx("li",{children:s.href?e.jsxs("a",{href:s.href,target:"_blank",rel:"noopener noreferrer",className:"hover:text-white transition-all duration-300 flex items-center group",children:[e.jsx("span",{className:"w-0 group-hover:w-2 h-2 bg-purple-500 rounded-full mr-0 group-hover:mr-2 transition-all duration-300"}),s.text]}):e.jsxs(F,{to:`${s.to}`,className:"hover:text-white transition-all duration-300 flex items-center group",children:[e.jsx("span",{className:"w-0 group-hover:w-2 h-2 bg-purple-500 rounded-full mr-0 group-hover:mr-2 transition-all duration-300"}),s.text]})},s.to||s.href))})]}),e.jsxs("div",{className:"sm:col-span-2 lg:col-span-6",children:[e.jsxs("h2",{className:"text-lg sm:text-xl font-bold mb-4 sm:mb-6 text-white relative inline-block",children:["Connect With Us",e.jsx("span",{className:"absolute -bottom-2 left-0 w-8 sm:w-12 h-1 bg-pink-500"})]}),e.jsx("div",{className:"flex flex-wrap items-center gap-3 sm:gap-4 md:gap-6 mb-6 sm:mb-8",children:qt.map(s=>e.jsxs("a",{href:s.href,target:"_blank",rel:"noopener noreferrer","aria-label":`Visit our ${s.name} page`,className:`group relative flex items-center justify-center w-10 h-10 sm:w-12 sm:h-12 + bg-gray-800/30 hover:bg-gray-700 rounded-xl + transition-all duration-300 ease-in-out + hover:scale-110 + before:absolute before:inset-0 before:rounded-xl + before:bg-gradient-to-r before:from-blue-500/20 before:to-purple-500/20 + before:opacity-0 before:transition-opacity before:duration-300 + hover:before:opacity-100 hover:shadow-lg hover:shadow-blue-500/10`,children:[e.jsx("img",{src:s.icon,alt:s.name,width:18,height:18,className:`relative z-10 transition-transform duration-300 + filter brightness-0 invert opacity-90 + group-hover:opacity-100 group-hover:scale-110 + sm:w-5 sm:h-5`}),e.jsx("span",{className:`absolute -bottom-6 left-1/2 -translate-x-1/2 + whitespace-nowrap text-xs sm:text-sm opacity-0 group-hover:opacity-100 + transition-opacity duration-300 pointer-events-none`,children:s.name})]},s.href))}),e.jsxs("a",{href:"https://github.com/sugarlabs/www-v2",target:"_blank",rel:"noopener noreferrer",className:`inline-flex items-center gap-2 sm:gap-3 px-4 sm:px-6 py-2.5 sm:py-3 bg-gray-800/50 hover:bg-gray-700 + rounded-lg transition-all duration-300 transform hover:-translate-y-1 + hover:shadow-lg hover:shadow-gray-800/30 mb-6 sm:mb-8 text-sm sm:text-base`,children:[e.jsx("img",{src:$t,alt:"GitHub",width:18,className:"filter brightness-0 invert"}),e.jsx("span",{className:"text-white",children:"Contribute to this website"})]}),e.jsx("div",{className:"p-4 sm:p-6 bg-gray-800/30 rounded-lg backdrop-blur-sm",children:e.jsx("p",{className:"text-xs sm:text-sm leading-relaxed",children:"Sugar Labs is a registered USA 501(c)(3) tax-exempt, not-for-profit organization, supported by our generous contributors and sponsors."})})]})]}),e.jsx("div",{className:"grid grid-cols-1 xs:grid-cols-2 sm:grid-cols-3 md:grid-cols-5 gap-3 sm:gap-4 py-6 sm:py-8 border-t border-gray-800",children:Os.map(s=>e.jsx(F,{to:`${s.to}`,className:"hover:text-white transition-all duration-300 text-xs sm:text-sm",children:s.text},s.to))}),e.jsxs("div",{className:"text-xs sm:text-sm text-gray-500 pt-4 sm:pt-6 border-t border-gray-800 flex flex-col sm:flex-row justify-between items-center gap-3 sm:gap-4",children:[e.jsxs("p",{children:["Copyright © ",new Date().getFullYear()," Sugar Labs (R)"]}),e.jsxs("p",{className:"text-center sm:text-right",children:["Available under the"," ",e.jsx("a",{href:"https://creativecommons.org/licenses/by-sa/4.0/",target:"_blank",rel:"noopener noreferrer",className:"text-gray-400 hover:text-white transition-colors duration-300 underline decoration-dotted",children:"Creative Commons Attribution-ShareAlike 4.0 International License (CC BY-SA)"})]})]})]})]})}),Vs=""+new URL("Stats/KidsWhoseLife.svg",import.meta.url).href,zs=""+new URL("Stats/ProjectsForTeaching.svg",import.meta.url).href,Hs=""+new URL("Stats/ProblemSolvingTasks.svg",import.meta.url).href,Us=""+new URL("Stats/ActivitiesDownloaded.svg",import.meta.url).href,Gs=""+new URL("Stats/Languages.svg",import.meta.url).href,Ws=""+new URL("Stats/MentorsHelping.svg",import.meta.url).href,$s=""+new URL("Stats/quote-icon.svg",import.meta.url).href,qs=""+new URL("Stats/HeartLeft.svg",import.meta.url).href,Ys=""+new URL("Stats/HeartRight.svg",import.meta.url).href,Js=""+new URL("Images/faq.png",import.meta.url).href,O={kidlaptop:Vs,studentsCollaborating:zs,studentMobile:Hs,activity:Us,language:Gs,mentorsTeaching:Ws,apostrophie:$s,leftHeart:qs,rightHeart:Ys,faq:Js},_t=[{title:"Kids whose lives have been enriched by using the Sugar Learning Platform.",value:"3,000,000+",imageSrc:O.kidlaptop,imageAlt:"Student with laptop",gradient:"from-green-600 to-green-700",bgColor:"bg-green-50",borderColor:"border-green-200"},{title:"Projects for teaching and learning created by Sugar Labs students and teachers.",value:"344+",imageSrc:O.studentsCollaborating,imageAlt:"Students collaborating",gradient:"from-red-600 to-red-700",bgColor:"bg-red-50",borderColor:"border-red-200"},{title:"Problem-solving tasks completed by students ages 13-17.",value:"1,450+",imageSrc:O.studentMobile,imageAlt:"Student with mobile device",gradient:"from-green-600 to-green-700",bgColor:"bg-green-100",borderColor:"border-green-300"},{title:"Activities Downloaded",value:"11,531,321+",imageSrc:O.activity,imageAlt:"Activity icon",gradient:"from-yellow-600 to-yellow-700",bgColor:"bg-yellow-50",borderColor:"border-yellow-200"},{title:"Languages our educational software has been translated into",value:"170",imageSrc:O.language,imageAlt:"Language icon",gradient:"from-blue-600 to-blue-700",bgColor:"bg-blue-50",borderColor:"border-blue-200"},{title:"Mentors helping youth learn in programs like Google Code-In (GCI) and Google Summer of Code",value:"55+",imageSrc:O.mentorsTeaching,imageAlt:"Mentors teaching",gradient:"from-red-600 to-red-700",bgColor:"bg-red-100",borderColor:"border-red-300"}],E=[.22,1,.36,1],Yt=[.4,0,.2,1],P={hidden:{opacity:0},visible:{opacity:1,transition:{duration:.6,ease:E}}},$={hidden:{x:-100,opacity:0},visible:{x:0,opacity:1,transition:{duration:.6,ease:E}}},K={hidden:{x:100,opacity:0},visible:{x:0,opacity:1,transition:{duration:.6,ease:E}}},V={hidden:{y:100,opacity:0},visible:{y:0,opacity:1,transition:{duration:.6,ease:E}}},ne={hidden:{scale:.9,opacity:0},visible:{scale:1,opacity:1,transition:{type:"spring",stiffness:400,damping:10}},hover:{scale:1.05,transition:{type:"spring",stiffness:400,damping:10}},tap:{scale:.95}},H={hidden:{opacity:0},visible:{opacity:1,transition:{staggerChildren:.1,delayChildren:.2}}},ve={hidden:{opacity:0},visible:{opacity:1,transition:{duration:.8,ease:E}}},z={hidden:{opacity:0,y:20},visible:{opacity:1,y:0,transition:{duration:.7,ease:E}}},Ks={hidden:{opacity:0},visible:{opacity:1,transition:{staggerChildren:.15,delayChildren:.1}}},St={hidden:{opacity:0,y:20},visible:{opacity:1,y:0,transition:{duration:.6,ease:E}}},Jt={hidden:{opacity:0,y:30,scale:.95},visible:{opacity:1,y:0,scale:1,transition:{duration:.5,ease:E}},hover:{scale:1.05,y:-5,transition:{duration:.3}}},G={hidden:{opacity:0,y:20},visible:{opacity:1,y:0,transition:{duration:.7,ease:E}}},Lt={hidden:{opacity:0,scale:1.1},visible:{opacity:1,scale:1,transition:{delay:.2,duration:.5}}},Kt={hidden:{opacity:0,y:20,scale:.97},visible:{opacity:1,y:0,scale:1,transition:{duration:.5,ease:E}},hover:{y:-8,boxShadow:"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",transition:{type:"spring",stiffness:400,damping:15}}},xt={hidden:{opacity:0,scale:.95},visible:{opacity:1,scale:1,transition:{duration:.7,ease:E}}},W={hidden:{opacity:0,scale:0,rotate:-10},visible:{opacity:1,scale:1,rotate:0,transition:{type:"spring",stiffness:300,damping:15}},float:{y:[0,-7,0],transition:{duration:3,repeat:1/0,repeatType:"reverse",ease:Yt}}},Me={hidden:{opacity:0},visible:{opacity:1,transition:{delay:.2,duration:.5}}},Xt={hidden:{scale:.5,opacity:0},visible:{scale:1,opacity:1,transition:{type:"spring",stiffness:400,damping:15}}},Pe={hidden:{opacity:0},visible:{opacity:1,transition:{staggerChildren:.08,delayChildren:.1}}},ot={hidden:{opacity:0},visible:{opacity:1,transition:{staggerChildren:.2,delayChildren:.3}}},nt={hidden:{y:20,opacity:0},visible:{y:0,opacity:1,transition:{duration:.8,ease:E}},hover:{scale:1.02,boxShadow:"0 10px 30px rgba(0,0,0,0.1)",transition:{duration:.3}}},ke={letterAnimation:{hidden:{opacity:0,y:50},visible:{opacity:1,y:0,transition:{duration:.6,ease:E}}},hoverText:{initial:{},hover:{scale:1.05,transition:{type:"spring",stiffness:300}}},mouseFollow:{hidden:{opacity:0},visible:{opacity:.2,transition:{duration:.3}},hover:{scale:1.2,transition:{duration:.3}}}},Be={hidden:{width:0,opacity:0},visible:{width:"6rem",opacity:1,transition:{duration:.8,delay:.3,ease:E}}},Q={pageSection:{hidden:{opacity:0},visible:{opacity:1,transition:{duration:.6,ease:E}}},headingText:{hidden:{opacity:0,y:20},visible:{opacity:1,y:0,transition:{duration:.7,ease:E}}},paragraphText:{hidden:{opacity:0,y:20},visible:{opacity:1,y:0,transition:{duration:.7,ease:E,delay:.2}}},heroImage:{hidden:{opacity:0,x:100},visible:{opacity:1,x:0,transition:{duration:.6,ease:E}},hover:{scale:1.03,transition:{duration:.3}}},quickAnswersContainer:{hidden:{opacity:0},visible:{opacity:1,transition:{staggerChildren:.15,delayChildren:.1}}},quickAnswerCard:{hidden:{scale:.9,opacity:0},visible:{scale:1,opacity:1,transition:{type:"spring",stiffness:400,damping:10}},hover:{scale:1.05,transition:{type:"spring",stiffness:400,damping:10}},tap:{scale:.95}},quickAnswerIcon:{hidden:{rotate:-10,scale:.9},visible:s=>({rotate:0,scale:1,transition:{duration:.5,delay:s*.1}})},faqContainer:{hidden:{opacity:0},visible:{opacity:1,transition:{staggerChildren:.2,delayChildren:.3}}}},se={section:{hidden:{opacity:0,y:50},visible:{opacity:1,y:0,transition:{duration:.8,ease:E}}},heading:{hidden:{opacity:0,y:20},visible:{opacity:1,y:0,transition:{duration:.6,ease:E,delay:.2}}},memberCard:{hidden:{opacity:0,scale:.9},visible:{opacity:1,scale:1,transition:{duration:.6,ease:E}}},memberImage:{hidden:{opacity:0,scale:.8},visible:{opacity:1,scale:1,transition:{duration:.6,ease:E,delay:.3}}}},pe={section:{hidden:{opacity:0,y:50},visible:{opacity:1,y:0,transition:{duration:.6,ease:E}}},text:{hidden:{opacity:0,y:20},visible:{opacity:1,y:0,transition:{duration:.4,ease:E}}},listItem:s=>({hidden:{opacity:0,y:20},visible:{opacity:1,y:0,transition:{duration:.4,delay:s*.1}}}),button:{hover:{scale:1.05,transition:{duration:.3}}}},Ge={card:{hidden:{opacity:0,y:50},visible:{opacity:1,y:0,transition:{duration:.6,ease:E}},hover:{scale:1.05,boxShadow:"0px 10px 20px rgba(0, 0, 0, 0.2)",transition:{duration:.3}}},numberCircle:{hover:{rotate:10,transition:{duration:.3}}},image:{hover:{scale:1.02,transition:{duration:.3}}}},We={card:{hidden:{opacity:0,y:50},visible:s=>({opacity:1,y:0,transition:{duration:.6,ease:E,delay:s*.15}}),hover:{scale:1.05,boxShadow:"0px 10px 20px rgba(0, 0, 0, 0.2)",transition:{duration:.3}}},logoContainer:{hover:{rotate:10,transition:{duration:.3}}},button:{hover:{scale:1.1,transition:{duration:.2}},tap:{scale:.95}}},ce={section:{hidden:{opacity:0,y:50},visible:{opacity:1,y:0,transition:{duration:.8,ease:E}}},textContainer:{hidden:{opacity:0,x:-50},visible:{opacity:1,x:0,transition:{duration:.8,ease:E}}},imageContainer:{hidden:{opacity:0,x:50},visible:{opacity:1,x:0,transition:{duration:.8,ease:E}}},image:{hidden:{opacity:0,scale:.8},visible:{opacity:1,scale:1,transition:{duration:.5,ease:E}},hover:{scale:1.05,transition:{duration:.3}}},note:{hidden:{opacity:0},visible:{opacity:1,transition:{delay:.3,duration:.5}}}},we={whileHover:{scale:1.05,transition:{type:"spring",stiffness:400,damping:10}},whileTap:{scale:.95,transition:{type:"spring",stiffness:400,damping:10}}},J={initial:{opacity:0,y:30},animate:{opacity:1,y:0,transition:{delay:.2,duration:1.5,ease:E}}},Oe={initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1,transition:{delay:1,duration:1.5,ease:E}}},Xs={initial:{scale:.8,opacity:0},animate:{scale:1,opacity:1,transition:{duration:.8,ease:E}}},Qt={hidden:{opacity:0,y:40},visible:s=>({opacity:1,y:0,transition:{duration:.6,ease:E,delay:s*.2}})},Qs={hidden:{height:0},visible:{height:"100%",transition:{duration:1.5,ease:Yt}}},Ct={hidden:{opacity:0,y:60,scale:.8},visible:{opacity:1,y:0,scale:1,transition:{duration:1.2,ease:E,type:"spring",damping:25,stiffness:100}}},Zs=()=>e.jsxs("section",{className:"max-w-7xl mx-auto py-10 sm:py-16 md:py-20 px-4 sm:px-6 bg-white",children:[e.jsxs("div",{className:"relative mb-12 sm:mb-16 md:mb-24",children:[e.jsx("div",{className:"absolute left-0 top-1/2 w-full h-0.5 sm:h-1 bg-gradient-to-r from-red-500 via-yellow-500 to-blue-500 transform -translate-y-1/2 opacity-30"}),e.jsxs(a.div,{className:"relative z-10 text-center mx-auto max-w-2xl bg-white px-2 py-2 sm:py-4",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.3},children:[e.jsxs(a.h1,{variants:G,className:"text-center",children:[e.jsx(a.span,{className:"block text-black font-Caveat text-5xl sm:text-6xl md:text-7xl mb-1 sm:mb-2",variants:G,custom:1,children:"What"}),e.jsx(a.div,{className:`text-transparent bg-clip-text bg-gradient-to-r + from-red-500 to-orange-500 font-Pacifico text-4xl sm:text-5xl md:text-6xl mb-1 sm:mb-2`,variants:G,custom:2,children:"numbers"}),e.jsx(a.span,{className:"text-black italic font-serif text-2xl sm:text-3xl md:text-4xl",variants:G,custom:3,children:"say for us?"})]}),e.jsxs(a.p,{className:"text-gray-600 text-base sm:text-lg md:text-xl leading-relaxed font-Roboto mt-4 sm:mt-6",variants:G,custom:4,children:["Sugar Labs, founded in 2008, has had"," ",e.jsx("span",{className:"italic",children:"an impact on the lives of many"}),". Here are some of the statistics we are tracking"]})]})]}),e.jsx(a.div,{className:"mb-8 sm:mb-12 md:mb-16",variants:ot,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.1},children:e.jsxs(a.div,{className:"flex flex-col lg:flex-row items-center bg-gradient-to-r from-green-50 to-green-100 rounded-xl sm:rounded-2xl overflow-hidden shadow-lg sm:shadow-xl border border-green-200",variants:nt,whileHover:"hover",children:[e.jsxs("div",{className:"w-full lg:w-1/2 p-5 sm:p-8 lg:p-12",children:[e.jsx("h3",{className:"text-gray-700 text-xl sm:text-2xl font-medium mb-3 sm:mb-4 font-AnonymousPro",children:"Kids whose lives have been enriched by using the Sugar Learning Platform."}),e.jsx(a.div,{className:"text-5xl sm:text-6xl md:text-7xl lg:text-8xl font-bold mb-4 sm:mb-8 bg-gradient-to-r from-green-600 to-green-700 bg-clip-text text-transparent font-Caveat",variants:St,children:"3,000,000+"}),e.jsx("div",{className:"w-24 sm:w-32 h-0.5 sm:h-1 bg-gradient-to-r from-green-600 to-green-400 rounded-full"})]}),e.jsxs(a.div,{className:"w-full lg:w-1/2 h-48 sm:h-56 md:h-64 lg:h-96 relative",variants:Lt,children:[e.jsx("img",{src:O.kidlaptop,alt:"Student with laptop",className:"w-full h-full object-cover object-center"}),e.jsx("div",{className:"absolute inset-0 bg-gradient-to-r from-green-600/20 to-transparent"})]})]})}),e.jsx(a.div,{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6 md:gap-8",variants:ot,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.1},children:_t.slice(1).map((s,i)=>e.jsxs(a.div,{className:`rounded-lg sm:rounded-xl overflow-hidden shadow-md sm:shadow-lg hover:shadow-xl transition-all duration-300 ${s.bgColor} border ${s.borderColor}`,variants:nt,whileHover:{y:-5,transition:{duration:.2}},children:[e.jsxs(a.div,{className:"h-36 sm:h-40 md:h-48 relative overflow-hidden",variants:Lt,children:[e.jsx("img",{src:s.imageSrc,alt:s.imageAlt,className:"w-full h-full object-cover object-center"}),e.jsx("div",{className:`absolute inset-0 opacity-10 bg-gradient-to-br ${s.gradient}`})]}),e.jsxs("div",{className:"p-4 sm:p-5 md:p-6",children:[e.jsx("h3",{className:"text-gray-700 text-lg sm:text-xl font-medium mb-2 sm:mb-3 font-AnonymousPro line-clamp-2 h-12 sm:h-14",children:s.title}),e.jsx(a.div,{className:`text-4xl sm:text-5xl md:text-6xl font-bold mb-3 sm:mb-4 bg-gradient-to-r ${s.gradient} bg-clip-text text-transparent font-Caveat`,variants:St,children:s.value}),e.jsx("div",{className:`w-16 sm:w-20 md:w-24 h-0.5 sm:h-1 bg-gradient-to-r ${s.gradient} opacity-50 rounded-full mt-1 sm:mt-2`})]})]},i))}),e.jsxs(a.div,{className:"text-center mt-10 sm:mt-12 md:mt-16 pt-8 sm:pt-12 md:pt-16 border-t border-gray-200",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},transition:{duration:.8},viewport:{once:!0},children:[e.jsx("h2",{className:"text-2xl sm:text-3xl md:text-4xl font-bold text-gray-800 mb-4 sm:mb-6",children:"Join us and make a difference"}),e.jsx("p",{className:"text-gray-600 max-w-2xl mx-auto mb-6 sm:mb-8 md:mb-10 px-4 text-sm sm:text-base md:text-lg",children:"These numbers represent more than statistics - they represent lives changed through education and technology. Sugar Labs continues to grow and impact communities worldwide."}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-2 sm:gap-3 md:gap-4 max-w-6xl mx-auto px-2",children:_t.map((s,i)=>e.jsxs(a.div,{className:`px-2 sm:px-3 md:px-4 py-2 sm:py-3 rounded-md sm:rounded-lg ${s.bgColor} border ${s.borderColor} flex flex-col items-center justify-center`,whileHover:{scale:1.05,boxShadow:"0 4px 12px rgba(0,0,0,0.1)"},transition:{type:"spring",stiffness:400,damping:10},children:[e.jsx("span",{className:`font-bold text-transparent bg-clip-text bg-gradient-to-r ${s.gradient} text-base sm:text-xl md:text-2xl`,children:s.value}),e.jsxs("span",{className:"text-gray-700 text-2xs sm:text-xs md:text-sm text-center mt-0.5 sm:mt-1 line-clamp-1",children:[s.title.split(".")[0].substring(0,12),s.title.split(".")[0].length>12?"...":""]})]},i))})]})]}),Tt=({title:s,description:i,icon:r,buttonText:o,href:t,version:l})=>e.jsxs("div",{className:"bg-white rounded-xl sm:rounded-3xl p-4 sm:p-6 md:p-8 flex flex-col items-center text-center shadow-lg transition-transform hover:scale-105",children:[e.jsx("img",{src:r,alt:s,className:"flex-1/3 w-16 h-16 sm:w-20 sm:h-20 md:w-24 md:h-24 mb-3 sm:mb-4"}),e.jsx("h3",{className:"text-xl sm:text-2xl md:text-3xl font-bold mb-1 sm:mb-2",children:s}),l&&e.jsx("p",{className:`text-xs sm:text-sm mb-1 sm:mb-2 px-4 py-1 rounded-full inline-block ml-auto font-medium ${l==="v4"?"bg-pink-100 text-pink-700":l==="v3"?"bg-cyan-100 text-cyan-700":"bg-gray-100 text-gray-600"}`,children:l}),e.jsx("p",{className:"text-gray-600 text-sm sm:text-base mb-4 sm:mb-6",children:i}),e.jsx("a",{href:t,className:"w-full",children:e.jsx("button",{className:"w-full py-2 sm:py-3 px-4 sm:px-6 border-2 border-gray-900 rounded-full text-sm sm:text-base md:text-lg font-semibold hover:bg-gray-900 cursor-pointer hover:text-white transition-colors",children:o})})]}),It=({title:s,description:i,tryNowText:r,tryNowHref:o,learnMoreText:t,learnMoreHref:l,imagePath:d,gradientClass:h})=>e.jsx("div",{className:"bg-white rounded-xl sm:rounded-2xl md:rounded-3xl shadow-[rgba(13,_38,_76,_0.19)_0px_9px_20px] hover:shadow-[rgba(13,_38,_76,_0.25)_0px_12px_28px] transition-all duration-500 overflow-hidden mx-auto w-full group h-full",children:e.jsxs("div",{className:"p-4 sm:p-5 md:p-6 flex flex-col h-full",children:[e.jsxs("div",{className:"flex-1 flex flex-col space-y-3 sm:space-y-4",children:[e.jsxs("div",{className:"space-y-2 flex-1/4 sm:space-y-3 text-center w-full",children:[e.jsx("h2",{className:"text-lg sm:text-xl font-black text-gray-800 leading-tight bg-gradient-to-br from-gray-900 via-gray-800 to-gray-600 bg-clip-text group-hover:scale-[1.02] transition-transform duration-500",children:s}),e.jsx("p",{className:"text-gray-500 text-xs sm:text-sm leading-relaxed mx-auto font-medium tracking-wide",children:i})]}),e.jsxs("div",{className:"space-y-2 sm:space-y-2.5 flex flex-col items-center pt-1 sm:pt-3",children:[e.jsx("a",{href:o,className:`w-full text-white font-bold px-3 sm:px-4 md:px-5 py-2 sm:py-2.5 md:py-3 rounded-xl sm:rounded-2xl + transition-all duration-500 hover:scale-[1.02] hover:shadow-lg + active:scale-95 text-xs sm:text-sm backdrop-blur-sm relative overflow-hidden + ${h||"bg-gradient-to-br from-blue-600 via-blue-700 to-blue-800"} + before:absolute before:inset-0 before:bg-white/20 before:translate-x-[-150%] before:skew-x-[45deg] + hover:before:translate-x-[150%] before:transition-transform before:duration-700 + `,children:r}),e.jsx(F,{to:l,className:`w-full bg-gray-50/80 backdrop-blur-sm border-[1.5px] border-gray-100 rounded-xl sm:rounded-2xl px-3 sm:px-4 md:px-5 py-2 sm:py-2.5 md:py-3 + font-bold transition-all duration-500 hover:scale-[1.02] + hover:bg-gray-100/80 hover:border-gray-200 text-gray-700 text-xs sm:text-sm + active:scale-95 relative overflow-hidden + before:absolute before:inset-0 before:bg-gray-400/20 before:translate-x-[-150%] before:skew-x-[45deg] + hover:before:translate-x-[150%] before:transition-transform before:duration-700`,children:t})]})]}),e.jsxs("div",{className:"-mx-4 sm:-mx-5 md:-mx-6 -mb-4 sm:-mb-5 md:-mb-6 mt-4 sm:mt-5 md:mt-6 relative overflow-hidden",children:[e.jsx("div",{className:"absolute inset-0 bg-gradient-to-b from-white via-white/50 to-transparent h-8 sm:h-10 md:h-12 z-10"}),e.jsx("img",{src:d,alt:s,className:`w-full h-36 sm:h-40 md:h-48 object-cover transform transition-all duration-700 + group-hover:scale-110 group-hover:rotate-1`}),e.jsx("div",{className:"absolute inset-0 bg-gradient-to-t from-black/20 to-transparent"})]})]})}),ea=""+new URL("Cards/MusicBlocks.png",import.meta.url).href,ta=""+new URL("Cards/TurtleBlocks.png",import.meta.url).href,sa=""+new URL("Cards/Sugarizer.png",import.meta.url).href,aa=""+new URL("Cards/BootableDrive.png",import.meta.url).href,ra=""+new URL("Cards/DesktopInitialization.png",import.meta.url).href,ia=""+new URL("Cards/Trisquel.svg",import.meta.url).href,oa=""+new URL("Cards/RaspberryPi.png",import.meta.url).href,na=""+new URL("Cards/Flathub.png",import.meta.url).href,la=""+new URL("Cards/activity-finance.svg",import.meta.url).href,ca=""+new URL("Cards/activity-maze.svg",import.meta.url).href,da=""+new URL("Cards/activity-measure.svg",import.meta.url).href,ma=""+new URL("Cards/activity-turtle3d.svg",import.meta.url).href,ua=""+new URL("Cards/activity-words.svg",import.meta.url).href,ha=""+new URL("Cards/activity-ruler.svg",import.meta.url).href,ga=""+new URL("Cards/activity-star-chart.svg",import.meta.url).href,xa=""+new URL("Cards/activity-recall.svg",import.meta.url).href,pa=""+new URL("Cards/activity-physics.svg",import.meta.url).href,de=[{title:"Music Blocks",description:"Create musical code with the browser-based visual programming language Music Blocks",tryNowText:"Try Music Blocks now!",tryNowHref:"https://musicblocks.sugarlabs.org/",learnMoreText:"Learn more about Music Blocks",learnMoreHref:"/musicblocks",imagePath:ea,gradientClass:"bg-gradient-to-r from-blue-700 to-blue-500"},{title:"Turtle Blocks",description:"Explore math and computation through beautiful, artful and creative geometry.",tryNowText:"Try Turtle Blocks now!",tryNowHref:"https://turtle.sugarlabs.org/",learnMoreText:"Learn more about Turtle Blocks",learnMoreHref:"/turtleblocks",imagePath:ta,gradientClass:"bg-gradient-to-r from-pink-600 to-blue-500"},{title:"Try now on any device with Sugarizer.",description:"Get a taste of Sugar with Sugarizer, which opens in your browser with no installation.",tryNowText:"Try Sugarizer now!",tryNowHref:"https://try.sugarizer.org/",learnMoreText:"Learn more about Sugarizer",learnMoreHref:"/sugarizer",imagePath:sa,gradientClass:"bg-gradient-to-r from-yellow-400 to-green-500"},{title:"Desktop/laptop bootable drive",description:"With Sugar a Stick (SOAS), you can experience the full Sugar Learning Platform on any computer at any time from a bootable thumb drive",tryNowText:"Try Bootable drive now!",tryNowHref:"https://fedoraproject.org/spins/soas/download/",learnMoreText:"Learn more about Bootable Drive",learnMoreHref:"/bootablesoas",imagePath:aa,gradientClass:"bg-gradient-to-r from-gray-900 to-gray-400"},{title:"Desktop/laptop installation",description:"Sugar Learning platform can be installed as a full operating system on ost desktop and laptop computers.",tryNowText:"Try Desktop Installation now!",tryNowHref:"https://fedoraproject.org/spins/soas/download/",learnMoreText:"Learn more about Installation",learnMoreHref:"/bootablesoas",imagePath:ra,gradientClass:"bg-gradient-to-r from-blue-700 to-blue-500"},{title:"Try Trisquel for full freedom",description:"Get all the benefits of a bootable/installation frive on the fully free and well maintained Trisquel distro.",tryNowText:"Try Trisquel now!",tryNowHref:"https://trisquel.info/en/download",learnMoreText:"Learn more about Trisquel",learnMoreHref:"/trisquel",imagePath:ia,gradientClass:"bg-gradient-to-r from-blue-700 to-blue-900"},{title:"Try Sugar on Raspberry Pi",description:"The full Sugar environment on a Raspberry P.(RPk)",tryNowText:"Try Raspberry Pi now!",tryNowHref:"https://wiki.sugarlabs.org/go/Raspbian",learnMoreText:"Learn more about Raspberry Pi",learnMoreHref:"/raspberry",imagePath:oa,gradientClass:"bg-gradient-to-r from-red-600 to-green-500"},{title:"Convenient installation via Flatpak",description:"Create musical code with the browser based visual programming language Music Blocks",tryNowText:"Try Flatpak now!",tryNowHref:"https://flathub.org/apps/search?q=sugar%20labs",learnMoreText:"Learn more about Flatpak",learnMoreHref:"/flathub",imagePath:na,gradientClass:"bg-gradient-to-r from-gray-400 to-gray-900"}],me=[{title:"Finance",description:"Roleplay with money",icon:la,buttonText:"Get Finance",href:"https://activities.sugarlabs.org/en-US/sugar/addon/4040",version:"v3"},{title:"Maze",description:"Have fun with progressive challenges",icon:ca,buttonText:"Get Maze",href:"https://activities.sugarlabs.org/en-US/sugar/addon/4727",version:"v3"},{title:"Measure",description:"Use your computer to measure things in the physical world",icon:da,buttonText:"Get Measure",href:"https://activities.sugarlabs.org/en-US/sugar/addon/4197",version:"v3"},{title:"TurtleBlocks3D",description:"Turtle Blocks? But in three dimensions!",icon:ma,buttonText:"Get TurtleBlocks3D",href:"https://activities.sugarlabs.org/en-US/sugar/addon/4757",version:"v3"},{title:"Words",description:"Compose and share your ideas",icon:ua,buttonText:"Get Words",href:"https://activities.sugarlabs.org/en-US/sugar/addon/4315",version:"v3"},{title:"Ruler",description:"Measure and explore math",icon:ha,buttonText:"Get Ruler",href:"https://activities.sugarlabs.org/en-US/sugar/addon/4192",version:"v3"},{title:"StarChart",description:"Explore numbers and information in charts",icon:ga,buttonText:"Get StarChart",href:"https://activities.sugarlabs.org/en-US/sugar/addon/4300",version:"v3"},{title:"Recall",description:"Test your memory with this fun game",icon:xa,buttonText:"Get Recall",href:"https://v4.activities.sugarlabs.org/app/org.sugarlabs.RecallActivity.html",version:"v4"},{title:"Physics",description:"Physical world simulator and playground",icon:pa,buttonText:"Get Physics",href:"https://activities.sugarlabs.org/en-US/sugar/addon/4193",version:"v3"}],Zt=()=>{const[s,i]=c.useState(0),[r,o]=c.useState(0),[t,l]=c.useState(0),[d,h]=c.useState(!1),[w,k]=c.useState(0),m=c.useRef(null),u=c.useRef(null),x=(g,j,I)=>{j(g==="next"?S=>(S+1)%I:S=>(S-1+I)%I)},f=g=>{o(g.targetTouches[0].clientX),h(!0)},v=g=>{l(g.targetTouches[0].clientX)},L=(g,j)=>{h(!1);const I=50,S=r-t;Math.abs(S)>I&&(S>0?x("next",g,j):x("prev",g,j))};return e.jsx(a.div,{className:"min-h-screen flex flex-col",initial:"hidden",animate:"visible",variants:P,children:e.jsxs(a.main,{className:"flex-grow bg-[#F6DEC9] px-3 sm:px-4 md:px-8 lg:px-16 py-6 sm:py-8 md:py-12 lg:py-16",children:[e.jsxs("div",{className:"max-w-6xl mx-auto space-y-6 sm:space-y-8",children:[e.jsxs(a.header,{className:"space-y-3 sm:space-y-4 md:space-y-6",variants:H,children:[e.jsxs(a.h1,{className:"text-3xl sm:text-4xl md:text-5xl lg:text-7xl font-bold flex flex-col sm:flex-row items-start sm:items-center",variants:G,children:[e.jsx(a.span,{className:"text-white bg-[#975555] px-2 py-1 rounded-lg inline-block",variants:$,children:"EXPERIENCE"}),e.jsx(a.span,{className:"text-black sm:ml-2 mt-1 sm:mt-0",variants:K,children:"SUGAR"})]}),e.jsxs(a.div,{className:"space-y-2 sm:space-y-3 md:space-y-4",variants:z,children:[e.jsx(a.p,{className:"text-[#975555] text-xl sm:text-2xl md:text-3xl lg:text-4xl font-bold leading-tight",variants:P,children:'"Our educational tools can be experienced in a number of ways. Try the ones that are best for you!"'}),e.jsx(a.i,{className:"text-xs md:text-sm text-gray-700 block",variants:P,children:"Whether you enjoy hands-on activities, visual learning, or interactive coding, there's something for everyone. Explore creative tools, enhance your problem-solving skills, and make learning more engaging."})]})]}),e.jsx("div",{className:"hidden md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 lg:gap-8",children:de.map((g,j)=>e.jsx(It,{...g},j))}),e.jsxs("div",{className:"md:hidden -mx-3 sm:-mx-2",children:[e.jsxs("div",{className:"relative px-3 sm:px-4",children:[e.jsx("div",{ref:m,className:"overflow-hidden touch-pan-x",onTouchStart:f,onTouchMove:v,onTouchEnd:()=>L(i,de.length),children:e.jsx("div",{className:"flex transition-transform duration-300 ease-out",style:{transform:`translateX(-${s*100}%)`,willChange:"transform"},children:de.map((g,j)=>e.jsx("div",{className:"w-full flex-shrink-0 px-2",style:{scrollSnapAlign:"start"},children:e.jsx("div",{className:` + transform transition-all duration-300 + ${d?"scale-98":"hover:scale-102"} + `,children:e.jsx(It,{...g})})},j))})}),e.jsxs("div",{className:"absolute top-1/2 -translate-y-1/2 left-1 right-1 flex justify-between pointer-events-none",children:[e.jsx("button",{onClick:()=>x("prev",i,de.length),className:"pointer-events-auto p-2 sm:p-3 bg-white/80 text-[#975555] rounded-full shadow-lg hover:bg-white transition-all","aria-label":"Previous",children:e.jsx("svg",{className:"w-4 h-4 sm:w-5 sm:h-5 md:w-6 md:h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})}),e.jsx("button",{onClick:()=>x("next",i,de.length),className:"pointer-events-auto p-2 sm:p-3 bg-white/80 text-[#975555] rounded-full shadow-lg hover:bg-white transition-all","aria-label":"Next",children:e.jsx("svg",{className:"w-4 h-4 sm:w-5 sm:h-5 md:w-6 md:h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})})]})]}),e.jsx("div",{className:"flex justify-center space-x-1 sm:space-x-2 mt-4 sm:mt-6",children:de.map((g,j)=>e.jsx("button",{onClick:()=>i(j),className:`w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full transition-all duration-300 ${s===j?"bg-[#975555] w-4 sm:w-6":"bg-[#975555]/30"}`,"aria-label":`Go to slide ${j+1}`},j))})]})]}),e.jsxs(a.div,{className:"max-w-6xl mx-auto space-y-6 sm:space-y-8 mt-12 sm:mt-14 md:mt-16",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.1},variants:V,children:[e.jsxs(a.header,{className:"space-y-3 sm:space-y-4 md:space-y-6",variants:H,children:[e.jsxs(a.h1,{className:"text-3xl sm:text-4xl md:text-5xl lg:text-7xl font-bold flex flex-col sm:flex-row items-start sm:items-center",variants:G,children:[e.jsx(a.span,{className:"text-white bg-[#975555] px-2 py-1 rounded-lg inline-block",variants:$,children:"ALREADY USING"}),e.jsx(a.span,{className:"text-black sm:ml-2 mt-1 sm:mt-0",variants:K,children:"SUGAR?"})]}),e.jsxs(a.div,{className:"space-y-2 sm:space-y-3 md:space-y-4",variants:z,children:[e.jsx(a.p,{className:"text-[#975555] text-xl sm:text-2xl md:text-3xl lg:text-4xl font-bold leading-tight",variants:P,children:'"We have many activities for you!"'}),e.jsx(a.i,{className:"text-xs md:text-sm text-gray-700 block",variants:P,children:"The Sugar Learning platform is a complete environment for teaching and learning, which includes individual activities. If you're already using the Sugar Desktop Environment, then you can install from the activities below, which has links to some of our most popular activities."})]})]}),e.jsx("div",{className:"hidden md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 lg:gap-8",children:me.map((g,j)=>e.jsx(Tt,{title:g.title,description:g.description,icon:g.icon,buttonText:g.buttonText,href:g.href,version:g.version},j))}),e.jsxs("div",{className:"md:hidden -mx-3 sm:-mx-2",children:[e.jsxs("div",{className:"relative px-3 sm:px-4",children:[e.jsx("div",{ref:u,className:"overflow-hidden touch-pan-x",onTouchStart:f,onTouchMove:v,onTouchEnd:()=>L(k,me.length),children:e.jsx("div",{className:"flex transition-transform duration-300 ease-out",style:{transform:`translateX(-${w*100}%)`,willChange:"transform"},children:me.map((g,j)=>e.jsx("div",{className:"w-full flex-shrink-0 px-2",style:{scrollSnapAlign:"start"},children:e.jsx("div",{className:` + transform transition-all duration-300 + ${d?"scale-98":"hover:scale-102"} + `,children:e.jsx(Tt,{title:g.title,description:g.description,icon:g.icon,buttonText:g.buttonText,href:g.href,version:g.version})})},j))})}),e.jsxs("div",{className:"absolute top-1/2 -translate-y-1/2 left-1 right-1 flex justify-between pointer-events-none",children:[e.jsx("button",{onClick:()=>x("prev",k,me.length),className:"pointer-events-auto p-2 sm:p-3 bg-white/80 text-[#975555] rounded-full shadow-lg hover:bg-white transition-all","aria-label":"Previous",children:e.jsx("svg",{className:"w-4 h-4 sm:w-5 sm:h-5 md:w-6 md:h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})}),e.jsx("button",{onClick:()=>x("next",k,me.length),className:"pointer-events-auto p-2 sm:p-3 bg-white/80 text-[#975555] rounded-full shadow-lg hover:bg-white transition-all","aria-label":"Next",children:e.jsx("svg",{className:"w-4 h-4 sm:w-5 sm:h-5 md:w-6 md:h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})})]})]}),e.jsx("div",{className:"flex justify-center space-x-1 sm:space-x-2 mt-4 sm:mt-6",children:me.map((g,j)=>e.jsx("button",{onClick:()=>k(j),className:`w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full transition-all duration-300 ${w===j?"bg-[#975555] w-4 sm:w-6":"bg-[#975555]/30"}`,"aria-label":`Go to slide ${j+1}`},j))})]})]})]})})},ba=""+new URL("Images/teach.jpg",import.meta.url).href,fa=""+new URL("Images/teach1.jpg",import.meta.url).href,wa=""+new URL("Images/discuss.jpeg",import.meta.url).href,va=""+new URL("Images/teach2.jpeg",import.meta.url).href,ya=""+new URL("Images/learn.jpg",import.meta.url).href,Et={title:"SUGAR LABS",description:`Whether you're a young learner, teacher, or a budding developer, + we believe Sugar Labs has something for you. Read on to learn more + about our award-winning Sugar Learning Platform and how to join our + diverse community of teachers and learners.`},_e={main:{src:ba,alt:"Sugar Labs Learning Environment"},bottom1:{src:va,alt:"Sugar Labs Collaboration",caption:"Collaborative Learning Environment"},bottom2:{src:fa,alt:"Sugar Labs Teaching",caption:"Interactive Teaching Tools"},bottom3:{src:wa,alt:"Sugar Labs Learning",caption:"Global Learning Community"}},ja={learnImage:ya},Na=()=>{const[s,i]=c.useState(0);c.useEffect(()=>{const o=()=>{i(window.innerWidth)};return o(),window.addEventListener("resize",o),()=>window.removeEventListener("resize",o)},[]);const r=(o,t)=>e.jsxs("div",{className:"relative",children:[e.jsx("img",{src:t.src,alt:t.alt,className:"w-full h-48 sm:h-64 object-cover",loading:"lazy"}),t.caption&&e.jsx("div",{className:`absolute bottom-0 inset-x-0 bg-gradient-to-t from-black/90 + to-transparent p-3 sm:p-4`,children:e.jsx("p",{className:"text-white font-normal text-sm sm:text-base",children:t.caption})})]},o);return e.jsx(e.Fragment,{children:e.jsx("div",{className:"min-h-screen bg-gradient-to-b from-slate-50 to-white font-Inter",children:e.jsxs("main",{className:"max-w-7xl mx-auto px-3 sm:px-4 md:px-6 py-8 sm:py-10 md:py-12 space-y-12 sm:space-y-16 md:space-y-20",children:[e.jsxs("section",{className:"container mx-auto px-2 sm:px-4 py-6 sm:py-8 max-w-7xl",children:[e.jsxs(a.div,{className:`relative mb-6 sm:mb-8 rounded-2xl sm:rounded-3xl overflow-hidden shadow-xl sm:shadow-2xl + transform hover:scale-[1.01] transition-all duration-500 + ease-out bg-white`,initial:"hidden",whileInView:"visible",viewport:{once:!0},variants:ve,children:[e.jsx("img",{src:_e.main.src,alt:_e.main.alt,className:"w-full h-[350px] sm:h-[400px] md:h-[500px] lg:h-[600px] xl:h-[700px] object-cover"}),e.jsx("div",{className:`absolute inset-0 bg-gradient-to-r from-black/70 + via-black/50 to-transparent`}),e.jsxs(a.div,{className:`absolute top-1/2 left-2 sm:left-6 md:left-12 transform -translate-y-1/2 + text-white max-w-xs sm:max-w-sm md:max-w-lg lg:max-w-2xl p-2 sm:p-0`,initial:"hidden",whileInView:"visible",viewport:{once:!0},variants:z,children:[e.jsx("h1",{className:`text-3xl sm:text-4xl md:text-5xl lg:text-6xl xl:text-7xl font-black mb-3 sm:mb-4 md:mb-6 lg:mb-8 + leading-tight tracking-tight animate-fade-in font-display`,children:Et.title}),e.jsx("p",{className:`text-base sm:text-lg md:text-xl lg:text-2xl leading-relaxed opacity-90 + animate-fade-in-delayed font-light`,children:Et.description})]})]}),e.jsx(a.div,{className:"hidden md:grid grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4",variants:Ks,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.1},children:Object.entries(_e).filter(([o])=>o.startsWith("bottom")).map(([o,t])=>e.jsxs(a.div,{className:`group relative rounded-3xl overflow-hidden shadow-lg hover:shadow-2xl + transition-all duration-500 bg-white`,variants:z,whileHover:"hover",children:[e.jsx("img",{src:t.src,alt:t.alt||o,className:`w-full h-auto object-cover transform group-hover:scale-105 + transition-all duration-700 ease-out`,loading:"lazy"}),t.caption&&e.jsx("div",{className:`absolute bottom-0 inset-x-0 bg-gradient-to-t from-black/90 + to-transparent p-3 sm:p-4 md:p-6 lg:p-8`,children:e.jsx("p",{className:"text-white font-medium text-sm sm:text-base md:text-lg lg:text-xl",children:t.caption})})]},o))}),e.jsx(a.div,{className:"md:hidden",variants:P,initial:"hidden",whileInView:"visible",viewport:{once:!0},children:e.jsx(De.Carousel,{showThumbs:!1,showStatus:!1,infiniteLoop:!0,autoPlay:!0,interval:5e3,transitionTime:500,className:"rounded-xl sm:rounded-2xl overflow-hidden",stopOnHover:!0,swipeable:!0,emulateTouch:!0,children:Object.entries(_e).filter(([o])=>o.startsWith("bottom")).map(([o,t])=>r(o,t))})})]}),e.jsxs(a.section,{className:"grid sm:grid-cols-1 md:grid-cols-2 gap-8 sm:gap-10 md:gap-16 lg:gap-20 items-center px-2 sm:px-4",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},variants:ve,children:[e.jsxs("div",{className:"space-y-6 sm:space-y-8 md:space-y-10",children:[e.jsx("div",{className:`inline-block px-3 sm:px-4 md:px-6 py-1.5 sm:py-2 md:py-3 bg-gradient-to-r + from-red-500/10 to-orange-500/10 rounded-full`,children:e.jsx("span",{className:`text-xs sm:text-sm font-bold text-red-600 tracking-wider + uppercase`,children:"Empowering Young Learners"})}),e.jsxs(a.h2,{className:`text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-black space-y-1 sm:space-y-2 + font-display tracking-tight`,variants:z,children:[e.jsx("span",{className:"font-bold tracking-wider font-Caveat text-5xl sm:text-6xl md:text-7xl lg:text-8xl",children:"Our Mission?"}),e.jsxs("div",{children:[e.jsx("div",{className:`text-transparent bg-clip-text bg-gradient-to-r + from-red-500 to-orange-500 font-Caveat text-5xl sm:text-6xl md:text-7xl lg:text-8xl`,children:"Authentic"}),e.jsx("span",{className:"font-semibold",children:"Problem"}),e.jsx("br",{}),e.jsx("span",{className:"font-semibold",children:"Solving"})]})]}),e.jsx(a.h4,{className:"text-base sm:text-lg md:text-xl font-bold text-gray-800",variants:z,children:"Igniting Curiosity through Project Based Learning"}),e.jsx("p",{className:"text-gray-600 text-sm sm:text-base md:text-lg font-Roboto",children:"Empowering Young Minds with Hands-on Learning, Transforming Curiosity into Discovery and Innovation."})]}),e.jsx(a.div,{className:"relative",variants:z,children:e.jsxs("div",{className:"bg-auto rounded-xl sm:rounded-2xl overflow-hidden shadow-lg sm:shadow-xl",children:[e.jsx(a.img,{src:ja.learnImage,alt:"Students learning",className:`w-full rounded-xl sm:rounded-2xl transform hover:scale-105 + transition-all duration-500 ease-out`,loading:"lazy",whileHover:{scale:1.05}}),s>=270&&e.jsxs(a.div,{className:`absolute top-2 left-2 bg-black/60 + backdrop-blur-sm rounded-lg sm:rounded-xl p-2.5 sm:p-4 md:p-6 shadow-lg + max-w-[180px] sm:max-w-[220px] md:max-w-xs transform hover:scale-105 + transition-all duration-300 ease-out z-10 border border-white/50`,whileHover:{scale:1.05},children:[s>=355&&e.jsxs(e.Fragment,{children:[e.jsx("h3",{className:"text-base sm:text-lg md:text-xl font-bold mb-1 md:mb-2 text-gray-100 font-AnonymousPro",children:"Project Based Learning"}),e.jsx("p",{className:"text-white text-xs sm:text-sm leading-tight sm:leading-snug",children:"Empowering learners and educators with hands-on project-based tools that enable creation and real-world problem-solving."})]}),s<355&&s>=250&&e.jsx("h3",{className:"text-base sm:text-lg md:text-xl font-bold text-gray-100 font-AnonymousPro",children:"Project Based Learning"})]}),s>=270&&e.jsxs(a.div,{className:`absolute bottom-2 right-2 bg-black/60 + backdrop-blur-sm rounded-lg sm:rounded-xl p-2.5 sm:p-4 md:p-6 shadow-lg + max-w-[180px] sm:max-w-[220px] md:max-w-xs transform hover:scale-105 + transition-all duration-300 ease-out z-10 border border-white/50`,whileHover:{scale:1.05},children:[s>=355&&e.jsxs(e.Fragment,{children:[e.jsx("h3",{className:"text-base sm:text-lg font-bold mb-1 text-amber-100 font-AnonymousPro",children:"Challenge and Fun: It's hard fun."}),e.jsx("p",{className:"text-white text-xs sm:text-sm leading-tight sm:leading-snug",children:"Bringing interactive, meaningful experiences that make education exciting and impactful."})]}),s<355&&s>=270&&e.jsx("h3",{className:"text-base sm:text-lg font-bold text-amber-100 font-AnonymousPro",children:"Challenge and Fun: It's hard fun."})]})]})})]})]})})})};function At(...s){return rs(is(s))}function oe({className:s,reverse:i=!1,pauseOnHover:r=!1,children:o,vertical:t=!1,repeat:l=4,...d}){return e.jsx("div",{...d,className:At("group flex overflow-hidden p-2 [--duration:40s] [--gap:1rem] [gap:var(--gap)]",{"flex-row":!t,"flex-col":t},s),children:Array(l).fill(0).map((h,w)=>e.jsx("div",{className:At("flex shrink-0 justify-around [gap:var(--gap)]",{"animate-marquee flex-row":!t,"animate-marquee-vertical flex-col":t,"group-hover:[animation-play-state:paused]":r,"[animation-direction:reverse]":i}),children:o},w))})}const Se=[{name:"Student at Soham Shubham Science",username:"Soham Shubham Science",body:"Music Blocks is a programming environment for children interested in music and graphics. It expands upon Turtle Blocks by adding a collection of features relating to pitch and rhythm.",img:"https://subhamgroupofinstitutions.com/wp-content/uploads/2022/08/Subham_logo-1-removebg-preview.png"},{name:"Richard Hermann",username:"Richard Hermann, PhD, Prof. of Music Theory and Composition, University of New Mexico",body:"I think Music Blocks will inspire many young folks to become programmers, mathematicians, composers, and music theorists. It will also provide important experiences to other young folk who pursue other fields. You are to be congratulated on your efforts.",img:"https://www.richardhermann.net/_Media/rhmh-tentrock_med.jpeg"},{name:"Riya Lohia",username:"Riya Lohia GSoc 2018 Student",body:"I would like to thank my mentors Walter Bender and Devin Ulibarri for their constant guidance and motivation...",img:"https://avatar.vercel.sh/james"},{name:"Sourabha G.",username:"Sourabha G. GSoC 2021 Student",body:"This summer was super fun and filled with learning! I enjoyed testing over 60+ activities with kids to get first-hand feedback which had a positive impact in the way they approach problems...",img:"https://avatar.vercel.sh/james"},{name:"LinuxInsider",username:"LinuxInsider",body:"Fedora-Based Sugar on a Stick Is One Sweet Desktop.",img:"https://avatar.vercel.sh/james"},{name:"Harshit Verma",username:"Harshit Verma",body:"Contribution to Sugar Labs has been an incredible rewarding experience. It has not only helped me grow as a developer but also given me confidence to work on real world projects. I’m excited about what’s next in my open source journey, and I can’t wait to continue learning and contributing!",img:"https://miro.medium.com/v2/resize:fill:44:44/1*devzHlZAKt4fVu5Cg0eN6w.png"},{name:"Om Santosh Suneri",username:"Om Santosh Suneri",body:"My first open source contribution was challenging but incredibly rewarding. If you’re hesitant about contributing, just dive in. Find a project you love, pick an issue, and start exploring.Who knows? Your first PR might be just around the corner.",img:"https://miro.medium.com/v2/da:true/resize:fill:44:44/0*975x0N6-dYtP01Y7"},{name:"Vipul Gupta",username:"Vipul Gupta",body:"Sugar Labs excelled all my expectations of how an open-source community would be like. The work I did during the course of the program would sure benefit the community. But more importantly, from day one, I felt to be working for something much bigger than myself.",img:"https://miro.medium.com/v2/resize:fill:44:44/1*QK0Aauitgk6kBBB6XpX98A.jpeg"},{name:"Sam Parkinson",username:"Sam Parkinson, Google Code-in grand prize winner",body:"GCI was truly something that changed my life. I went from being an open source newbie to being able to contribute to really cool projects, thanks to the amazing GCI and Sugar Labs communities. It's something that I would recommend any young programmer consider doing. Participating in GCI is something that can make dreams come true.",img:"https://avatar.vercel.sh/james"},{name:"Riya J",username:"Riya J. GSoC 2023 Student",body:"I learned a lot during the whole summer especially about backward compatibility when I worked on Sugar, which is a free/libre open-source software learning platform for children. I would like to thank my mentors, Chihurumnaya Ibiam and Sourabha Ganesh who provided constant support whenever I faced any issue. Looking forward to contributing more to Open Source!",img:"https://media.licdn.com/dms/image/v2/D5603AQGfK0K2z8gjMg/profile-displayphoto-shrink_100_100/B56ZR54oTdHwAY-/0/1737211676388?e=1749686400&v=beta&t=Kk7H2ex_3Vzmuw69QRiR55ZuXftrd4n60xRUFTbeDGo"}],Mt=({img:s,name:i,username:r,body:o,delay:t=0})=>e.jsxs(a.div,{className:"bg-white dark:bg-gray-900 rounded-xl p-6 flex flex-col items-center text-center min-h-[250px] h-auto w-[350px] shadow-lg border border-gray-200 dark:border-gray-700 mx-2 justify-between",variants:Kt,initial:"hidden",whileInView:"visible",whileHover:"hover",viewport:{once:!0,amount:.1},transition:{delay:t},children:[e.jsx(a.img,{src:O.apostrophie,alt:"double-quotes",className:"w-10 h-10 self-start opacity-70",variants:W}),e.jsx(a.p,{className:"text-gray-700 dark:text-gray-300 mt-2",variants:Me,children:o}),e.jsxs("div",{className:"flex items-center mt-4 space-x-3 text-left",children:[e.jsx(a.img,{src:s,alt:i,className:"w-12 h-12 rounded-full border border-gray-300",variants:Xt}),e.jsxs(a.div,{variants:Me,children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:i}),e.jsxs("p",{className:"text-sm text-gray-500 dark:text-gray-400",children:["@",r]})]})]})]});function ka(){const s=Se.slice(0,Math.ceil(Se.length/2)),i=Se.slice(Math.ceil(Se.length/2));return e.jsxs("div",{className:"w-full bg-gradient-to-b from-white-800 to-[#F5DDC8]",children:[e.jsxs(a.div,{className:"flex items-center justify-center gap-4 md:gap-6 mb-12",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.6},variants:Pe,children:[e.jsx(a.img,{src:O.leftHeart,alt:"Heart Left",className:"w-8 md:w-12 lg:w-16 fill-current text-red-500 border-none shadow-none",variants:W,animate:"float",custom:1}),e.jsxs("div",{className:"relative flex items-center justify-center gap-4 md:gap-6 lg:gap-8",children:[e.jsx(a.img,{src:O.apostrophie,alt:"Apostrophe Left",className:"w-8 md:w-12 lg:w-16 -translate-y-2 block max-[400px]:hidden",variants:W,custom:2}),e.jsx(a.h2,{className:"font-bold tracking-wider font-Caveat text-3xl md:text-5xl lg:text-6xl text-gray-800 text-center",variants:xt,children:e.jsxs("span",{className:"text-black",children:["Words of appreciation and",e.jsx("br",{})," admiration from others."]})}),e.jsx(a.img,{src:O.apostrophie,alt:"Apostrophe Right",className:"w-8 md:w-12 lg:w-16 -translate-y-2 scale-x-[-1] block max-[400px]:hidden",variants:W,custom:3})]}),e.jsx(a.img,{src:O.rightHeart,alt:"Heart Right",className:"w-8 md:w-12 lg:w-16 fill-current text-red-500 border-none shadow-none",variants:W,animate:"float",custom:4})]}),e.jsxs(a.div,{className:"relative flex flex-col items-center justify-center w-full overflow-hidden mt-6",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.1},variants:Pe,children:[e.jsx(oe,{pauseOnHover:!0,className:"w-full",children:s.map((r,o)=>e.jsx(Mt,{...r,delay:o*.05},r.username))}),e.jsx(oe,{reverse:!0,pauseOnHover:!0,className:"w-full mt-4",children:i.map((r,o)=>e.jsx(Mt,{...r,delay:o*.05},r.username))}),e.jsx("div",{className:"pointer-events-none absolute inset-y-0 left-0 w-6 md:w-10 bg-gradient-to-r from-background"}),e.jsx("div",{className:"pointer-events-none absolute inset-y-0 right-0 w-6 md:w-10 bg-gradient-to-l from-background"})]})]})}const te=[{title:"Abacus",description:"A tool for simple arithmetic calculations",buttonText:"Get Abacus",img:"assets/Activities/Abacus.svg"},{title:"BlockParty",description:"Blocks arrangement game",buttonText:"Get BlockParty",img:"assets/Activities/BlockPartyActivity.svg"},{title:"Cells",description:"This game is based on the mechanisms present in gene regulatory networks",buttonText:"Get Cells",img:"assets/Activities/CellManagement.svg"},{title:"Flappy",description:"The popular Flappy bird game",buttonText:"Get Flappy",img:"assets/Activities/flappy.svg"},{title:"JAMath",description:"A fun and interactive math game",buttonText:"Get JAMath",img:"assets/Activities/JAMath.svg"},{title:"Jumble",description:"Rearrange and uncover the hidden pattern",buttonText:"Get Jumble",img:"assets/Activities/Jumble.svg"},{title:"JupyterLabs",description:"Coding, data science, and visualization",buttonText:"Get JupyterLabs",img:"assets/Activities/JupyterLabs.svg"},{title:"Math Hurdler",description:"Solve equations to keep moving forward",buttonText:"Get Math Hurdler",img:"assets/Activities/math-hurdler.svg"},{title:"Memorize",description:"Here you can play games that challenge your memory!",buttonText:"Get Memorize",img:"assets/Activities/Memorize.svg"},{title:"Read ETexts",description:"Download and read thousands of free e-books in plain text format from Project Gutenberg!",buttonText:"Get Read ETexts",img:"assets/Activities/ReadEtextsActivity.svg"},{title:"Recall",description:"Memory exercise game",buttonText:"Get Recall",img:"assets/Activities/RecallActivity.svg"},{title:"Speak",description:"An animated face that speaks whatever you type",buttonText:"Get Speak",img:"assets/Activities/Speak.svg"},{title:"Tic-Tac-Toe",description:"A classic strategy game of Xs and Os",buttonText:"Get Tic-Tac-Toe",img:"assets/Activities/TicTacToe.svg"}],_a=te.slice(0,te.length/2),Sa=te.slice(te.length/2),La=te.slice(0,te.length/2),Ca=te.slice(te.length/2),Le=({img:s,title:i,description:r,buttonText:o})=>e.jsxs("figure",{className:"relative h-full w-36 cursor-pointer overflow-hidden rounded-xl border p-4 border-gray-950/[.1] bg-gray-950/[.01] hover:bg-gray-950/[.05] dark:border-gray-50/[.1] dark:bg-gray-50/[.10] dark:hover:bg-gray-50/[.15] flex flex-col items-center text-center",children:[e.jsx("img",{className:"w-12 h-12 mb-2",alt:i,src:s}),e.jsx("figcaption",{className:"text-lg font-semibold dark:text-white",children:i}),e.jsx("p",{className:"text-xs font-medium dark:text-white/40",children:r}),e.jsx("button",{className:"mt-4 px-3 py-1 border rounded-lg border-gray-950 dark:border-gray-50 text-sm font-medium dark:text-white",children:o})]});function Ta(){return e.jsxs("div",{className:"relative flex flex-col lg:flex-row h-auto lg:h-96 w-full items-center justify-center gap-6 lg:gap-4 overflow-hidden [perspective:300px] px-4 sm:px-6 md:px-10 lg:pl-20 bg-gradient-to-b from-[#F5DDC8] to-white-800",children:[e.jsx("div",{className:"height- 30px"}),e.jsxs(a.div,{className:"w-full lg:w-1/2 text-center lg:text-left",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.3},variants:H,children:[e.jsxs(a.h2,{className:"text-3xl sm:text-4xl font-extrabold text-[#975555] dark:text-[#975555]",variants:G,children:[e.jsxs(a.span,{variants:$,custom:0,children:["Check out the ",e.jsx("br",{className:"hidden lg:block"})]}),e.jsxs(a.span,{variants:$,custom:1,children:["remaining hundreds ",e.jsx("br",{className:"hidden lg:block"})]}),e.jsx(a.span,{variants:$,custom:2,children:"of activities!"})]}),e.jsx(a.p,{className:"mt-4 text-base sm:text-lg text-gray-700 dark:text-gray-300",variants:P,custom:3,children:"Important: Please know that in order to install and try them, you need to be running the Sugar Desktop Environment. If you don't have that already, please reconsider your other options to explore Sugar. Try Sugar!"}),e.jsx(a.a,{href:"https://v4.activities.sugarlabs.org/",target:"_blank",rel:"noopener noreferrer",children:e.jsx(a.button,{className:"mt-6 px-6 py-3 bg-indigo-600 text-white font-medium rounded-lg hover:bg-indigo-700 transition",variants:ne,custom:4,whileHover:{scale:1.05,backgroundColor:"#4338ca",boxShadow:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"},whileTap:{scale:.95},children:"Go to Sugar Activity page"})})]}),e.jsxs("div",{className:"flex flex-col lg:flex-row items-center gap-4 max-[1040px]:hidden",style:{transform:"translateX(0px) translateY(0px) translateZ(0px) rotateX(10deg) rotateY(-5deg) rotateZ(10deg)"},children:[e.jsx(oe,{pauseOnHover:!0,vertical:!0,className:"[--duration:20s] w-full lg:w-auto",children:_a.map(s=>e.jsx(Le,{...s},s.title))}),e.jsx(oe,{reverse:!0,pauseOnHover:!0,vertical:!0,className:"[--duration:20s] w-full lg:w-auto",children:Sa.map(s=>e.jsx(Le,{...s},s.title))}),e.jsx(oe,{reverse:!0,pauseOnHover:!0,vertical:!0,className:"[--duration:20s] w-full lg:w-auto",children:La.map(s=>e.jsx(Le,{...s},s.title))}),e.jsx(oe,{pauseOnHover:!0,vertical:!0,className:"[--duration:20s] w-full lg:w-auto",children:Ca.map(s=>e.jsx(Le,{...s},s.title))})]}),e.jsx("div",{className:"height- 20px"})]})}const Ia=""+new URL("Images/DonatePic.png",import.meta.url).href,Ea=""+new URL("Icons/arrow.svg",import.meta.url).href,Aa=""+new URL("Icons/pdf-icon.svg",import.meta.url).href,$e=[Ia,Ea,Aa],fe={url:"https://www.every.org/sugar-labs?suggestedAmounts=17,37,57&frequency=ONCE#donate",urlMonth:"https://www.every.org/sugar-labs?suggestedAmounts=17,37,57&frequency=MONTHLY#donate"},Ma=[{value:"300+",title:"Educational Tools",description:"We've created over three-hundred tools for learning that are used around the globe, helping students develop critical thinking and technical skills."},{value:"1000s",title:"Mentorship Hours",description:"We've mentored students for thousands of hours, guiding young developers at critical points in their development and helping them become leaders."},{value:"Global",title:"Educational Impact",description:"We've assisted schools in bringing project-based learning activities into their classrooms, empowering youth with technology skills worldwide."}],qe=[{year:"2023",link:"assets/tax-filings/2023-Form-990EZ.pdf"},{year:"2022",link:"assets/tax-filings/2022-Form-990EZ.pdf"},{year:"2021",link:"assets/tax-filings/2021-Form-990EZ.pdf"},{year:"2020",link:"assets/tax-filings/2020-Form-990EZ.pdf"},{year:"2019",link:"assets/tax-filings/2019-Form-990EZ.pdf"}],Pa=""+new URL("Volunteer/volunteer-1.png",import.meta.url).href,Ra=""+new URL("Volunteer/volunteer-2.png",import.meta.url).href,Da=""+new URL("Volunteer/volunteer-3.png",import.meta.url).href,Fa=[{id:1,alt:"Volunteer 1",src:Pa},{id:2,alt:"Volunteer 2",src:Ra},{id:3,alt:"Volunteer 3",src:Da}],Ba=()=>{const[s,i]=c.useState(""),r=()=>{window.open(fe.url,"_blank")};return e.jsxs("section",{className:"relative overflow-hidden bg-white text-black py-16 px-4",children:[e.jsxs("div",{className:"max-w-[90%] mx-auto flex flex-col lg:flex-row items-center justify-center lg:gap-12",children:[e.jsxs(a.div,{className:"lg:w-1/2 text-center lg:text-left",variants:$,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:[e.jsxs("p",{className:"italic text-gray-600 text-lg md:text-xl",children:["Donate to Sugar Labs to make a"," ",e.jsx("span",{className:"font-bold",children:"Positive"})," Impact"]}),e.jsxs("h1",{className:"text-4xl md:text-5xl font-bold mt-2 leading-tight",children:[e.jsx("span",{className:"text-red-500",children:"Support"})," and Empower ",e.jsx("br",{})," ","Learners Everywhere"]}),e.jsx("p",{className:"text-gray-600 text-lg mt-4",children:"Support Sugar Labs and make a difference in children's education. Sugar Labs has brought educational software and authentic problem solving to millions in the US and across the globe."}),e.jsx(a.button,{onClick:r,className:"mt-6 px-6 py-3 bg-[#fbd04d] text-black text-2xl font-bold rounded-full shadow-md hover:bg-yellow-500 cursor-pointer transition duration-300 uppercase",variants:ne,whileHover:"hover",whileTap:"tap",children:"Donate Now"})]}),e.jsx(a.img,{src:"assets/Images/DonateToSugarLabs.png",alt:"Children with laptops and Donate to Sugarlabs",className:"w-[400px] lg:w-[500px] transition-none hover:transform-none object-contain",variants:K,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},whileHover:{scale:1.01}})]}),e.jsxs("div",{className:"relative z-10 w-full mt-12 text-center",children:[e.jsx(a.div,{className:"flex justify-center items-center",variants:V,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.6},children:e.jsxs("div",{className:"relative",children:[e.jsx(a.div,{className:"absolute -top-8 -right-8",animate:{x:[0,10,0],transition:{repeat:1/0,duration:1.5}},children:e.jsx("i",{className:"fas fa-arrow-right text-2xl"})}),e.jsx(F,{to:"/volunteer",children:e.jsxs(a.div,{className:"bg-white border border-gray-300 rounded-full px-4 py-2 flex items-center shadow-lg",whileHover:{scale:1.05},transition:{type:"spring",stiffness:400,damping:10},children:[Fa.map((o,t)=>e.jsx(a.img,{alt:o.alt,className:"w-8 h-8 rounded-full border-2 border-white -ml-2",src:o.src,initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.05*t}},o.id)),e.jsx("span",{className:"ml-4 text-sm",children:"Join the volunteer"}),e.jsx(a.span,{className:"ml-2 bg-blue-500 text-white text-xs rounded-full px-2 py-1",initial:{scale:0},animate:{scale:1,transition:{type:"spring",stiffness:400,damping:10,delay:.3}},children:"+1000"})]})})]})}),e.jsxs(a.div,{className:"mt-16",variants:H,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},children:[e.jsx(a.p,{className:"text-lg",variants:P,children:"Join us to empower young learners across the globe. The simplest way to get involved is to join our newsletter."}),e.jsx(a.div,{className:"mt-4 flex justify-center items-center",variants:K,children:e.jsxs(a.form,{action:"https://buttondown.com/api/emails/embed-subscribe/sugarlabs",method:"post",onSubmit:()=>setTimeout(()=>i(""),500),className:"flex",children:[e.jsx("input",{className:"px-4 py-2 border border-gray-300 rounded-l-full focus:outline-none",placeholder:"Enter your email",type:"email",name:"email",value:s,onChange:o=>i(o.target.value),required:!0}),e.jsx("input",{value:"1",type:"hidden",name:"embed"}),e.jsx(a.button,{className:"px-6 py-2 bg-red-500 text-white font-bold rounded-r-full shadow-lg hover:bg-red-600 cursor-pointer transition duration-300",variants:we,whileHover:"whileHover",whileTap:"whileTap",type:"submit",children:"SUBSCRIBE"})]})})]})]})]})},Oa={primary:{background:"from-blue-100 to-indigo-200",border:"border-blue-300",icon:"text-blue-700",button:"from-blue-700 to-indigo-800 hover:from-blue-800 hover:to-indigo-900",progress:"from-blue-600 to-indigo-700",text:"text-blue-950"},success:{background:"from-green-100 to-emerald-200",border:"border-green-300",icon:"text-emerald-700",button:"from-green-700 to-emerald-800 hover:from-green-800 hover:to-emerald-900",progress:"from-green-600 to-emerald-700",text:"text-green-950"},warning:{background:"from-amber-100 to-orange-200",border:"border-amber-300",icon:"text-amber-700",button:"from-amber-600 to-orange-700 hover:from-amber-700 hover:to-orange-800",progress:"from-amber-600 to-orange-700",text:"text-amber-950"},sale:{background:"from-purple-100 to-fuchsia-200",border:"border-purple-300",icon:"text-purple-700",button:"from-purple-700 to-fuchsia-800 hover:from-purple-800 hover:to-fuchsia-900",progress:"from-purple-600 to-fuchsia-700",text:"text-purple-950"},info:{background:"from-cyan-100 to-sky-200",border:"border-cyan-300",icon:"text-cyan-700",button:"from-cyan-700 to-sky-800 hover:from-cyan-800 hover:to-sky-900",progress:"from-cyan-600 to-sky-700",text:"text-cyan-950"}},Va=({theme:s})=>{switch(s){case"primary":return e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("rect",{x:"2",y:"6",width:"20",height:"12",rx:"2"}),e.jsx("circle",{cx:"12",cy:"12",r:"3.5"}),e.jsx("line",{x1:"2",y1:"10",x2:"22",y2:"10"}),e.jsx("line",{x1:"2",y1:"14",x2:"22",y2:"14"}),e.jsx("path",{d:"M12 8.5v7"}),e.jsx("path",{d:"M10.5 10.5c.83-.35 2.17-.35 3 0"}),e.jsx("path",{d:"M10.5 13.5c.83.35 2.17.35 3 0"})]});case"success":return e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M22 11.08V12a10 10 0 1 1-5.93-9.14"}),e.jsx("polyline",{points:"22 4 12 14.01 9 11.01"})]});case"warning":return e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"}),e.jsx("line",{x1:"12",y1:"9",x2:"12",y2:"13"}),e.jsx("line",{x1:"12",y1:"17",x2:"12.01",y2:"17"})]});case"sale":return e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"}),e.jsx("line",{x1:"3",y1:"6",x2:"21",y2:"6"}),e.jsx("path",{d:"M16 10a4 4 0 0 1-8 0"}),e.jsx("line",{x1:"9",y1:"15",x2:"15",y2:"15"})]});case"info":default:return e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("circle",{cx:"12",cy:"12",r:"10"}),e.jsx("path",{d:"M12 16v-4"}),e.jsx("path",{d:"M12 8h.01"})]})}},za=({bannerConfigs:s,autoRotateInterval:i=4e3})=>{const[r,o]=c.useState(!0),t=Object.values(s),[l,d]=c.useState(0),[h,w]=c.useState(!1),[k,m]=c.useState(0),u=t[l],x=Oa[u.theme||"primary"],f=t.length,v=f>1,L=c.useCallback(()=>{v&&(m(-1),d(y=>y===0?f-1:y-1))},[v,f]),g=c.useCallback(()=>{v&&(m(1),d(y=>(y+1)%f))},[v,f]);c.useEffect(()=>{if(!v||h)return;const y=setInterval(()=>{g()},i);return()=>clearInterval(y)},[g,i,h,v]);const j=()=>{o(!1)},I=`inline-flex items-center justify-center px-3.5 py-1.5 sm:px-5 sm:py-2 border border-transparent rounded-full shadow-sm sm:text-l font-medium text-white bg-gradient-to-r ${x.button} transition-all duration-200 whitespace-nowrap`,S={whileHover:{scale:1.03},whileTap:{scale:.97}},N={enter:y=>({x:y>0?"100%":"-100%",opacity:0}),center:{x:0,opacity:1},exit:y=>({x:y<0?"100%":"-100%",opacity:0})},C=()=>!u.buttonText||!u.buttonLink?null:u.isExternalLink?e.jsx(a.a,{...S,href:u.buttonLink,target:"_blank",rel:"noopener noreferrer",className:I,children:u.buttonText}):e.jsx(a.div,{...S,children:e.jsx(F,{to:u.buttonLink,className:I,children:u.buttonText})});return e.jsx(Y,{children:r&&e.jsx("div",{className:`w-full bg-gradient-to-r ${x.background} border-b ${x.border} shadow-sm overflow-hidden`,children:e.jsx("div",{className:"max-w-7xl mx-auto px-3 py-6 sm:px-6 md:px-8 relative",children:e.jsx(Y,{initial:!1,custom:k,mode:"wait",children:e.jsx(a.div,{custom:k,variants:N,initial:"enter",animate:"center",exit:"exit",transition:{type:"tween",duration:.5,ease:"easeInOut"},className:"w-full",onMouseEnter:()=>w(!0),onMouseLeave:()=>w(!1),children:e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-y-3 sm:gap-y-0",children:[e.jsxs("div",{className:"flex items-center w-full sm:w-auto",children:[v&&e.jsx(a.button,{whileHover:{scale:1.1,backgroundColor:"rgba(255, 255, 255, 0.4)",cursor:"pointer"},whileTap:{scale:.95},onClick:L,className:`hidden sm:flex p-1.5 rounded-full hover:bg-white/30 focus:outline-none focus:ring-2 focus:ring-white/50 transition-all ${x.text} touch-manipulation mr-2`,"aria-label":"Previous banner",children:e.jsx("svg",{className:"h-5 w-5",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})}),e.jsx("div",{className:`flex p-2 sm:p-2.5 rounded-full bg-white/40 backdrop-blur-sm ${x.border} shadow-sm shrink-0`,children:e.jsx("span",{className:x.icon,children:e.jsx(Va,{theme:u.theme||"primary"})})}),e.jsxs("div",{className:"ml-3 sm:ml-3.5 pr-2 flex-1",children:[e.jsx("p",{className:`font-medium ${x.text} text-sm sm:text-base leading-tight`,children:u.title}),u.description&&e.jsx("p",{className:`text-xs sm:text-sm ${x.text} opacity-80 mt-0.5 line-clamp-2 sm:line-clamp-none`,children:u.description})]}),v&&e.jsx(a.button,{whileHover:{scale:1.1,backgroundColor:"rgba(255, 255, 255, 0.4)",cursor:"pointer"},whileTap:{scale:.95},onClick:g,className:`hidden sm:flex p-1.5 rounded-full hover:bg-white/30 focus:outline-none focus:ring-2 focus:ring-white/50 transition-all ${x.text} touch-manipulation ml-2`,"aria-label":"Next banner",children:e.jsx("svg",{className:"h-5 w-5",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})})]}),e.jsxs("div",{className:"flex items-center space-x-3 mt-2 sm:mt-0 self-end sm:self-auto",children:[C(),e.jsx(a.button,{whileHover:{scale:1.1,backgroundColor:"rgba(255, 255, 255, 0.4)"},whileTap:{scale:.95},onClick:j,className:`flex p-1.5 rounded-full hover:bg-white/30 focus:outline-none focus:ring-2 focus:ring-white/50 transition-all ${x.text} touch-manipulation`,"aria-label":"Dismiss",children:e.jsx("svg",{className:"h-4 w-4 sm:h-5 sm:w-5",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})]})},l)})})})})},Ha={donation:{title:"Help us reach our next fundraising milestone.",description:"Through every.org, we accept donations via credit card, ACH, PayPal, crypto, stocks, DAF, and Venmo.",buttonText:"Donate Now",buttonLink:"/donate",theme:"primary"},sale:{title:"Have you seen our merchandise?",description:"Check out t-shirts, hoodies, and bootable USB sticks, all with the official Sugar Labs logo.",buttonText:"Shop Now",buttonLink:"/products",theme:"info"},limitedOffer:{title:"Interested in joining the community?",description:"Learn more about the first steps to volunteering for Sugar Labs.",buttonText:"Learn more",buttonLink:"/volunteer",theme:"info"},announcement:{title:"This is our new website!",description:"We've launched our new website. If you found something missing, please let us know in a GitHub issue.",buttonText:"Report an issue",buttonLink:"https://github.com/sugarlabs/www-v2",theme:"info",isExternalLink:!0},successStory:{title:"Learn more about Sugar Labs through a Sugar Story, told by members of our community.",description:'"Sugar Stories" are stories told by members of the Sugar Labs community.',buttonText:"Read Story",buttonLink:"/news/sugar-stories",theme:"success"},webinar:{title:"Live online events",description:"Join us Fridays, starting 4/25/25 at 17:00 UTC (1:00pm EDT) to celebrate our website launch and learn more about Sugar Labs.",buttonText:"Subscribe for reminders",buttonLink:"https://www.youtube.com/@SugarlabsOrg-EN",theme:"info",isExternalLink:!0},feedback:{title:"We value your feedback",description:"Take our short survey and help us improve your experience.",buttonText:"Give Feedback",buttonLink:"/contact-us",theme:"info"}},Ua=()=>e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsx(za,{bannerConfigs:Ha}),e.jsx(Na,{}),e.jsx(Zs,{}),e.jsx(ka,{}),e.jsx(Zt,{}),e.jsx(Ta,{}),e.jsx(Ba,{}),e.jsx(M,{})]}),Ye=[{id:"mission",label:"Our Mission"},{id:"principles",label:"Our Principles"},{id:"goals",label:"Our Goals"},{id:"projects",label:"Our Projects"},{id:"roadmap",label:"Our Roadmap"}],Ce={scrollOffset:20,stickyTopPosition:70,activeDetectionOffset:100,defaultActiveSection:"mission"},Z={container:"sticky bg-white/90 backdrop-blur-md shadow-md rounded-lg p-4 mb-8 z-40 mt-16",list:"flex flex-wrap justify-center gap-4 md:gap-8",button:{base:"px-4 py-2 rounded-md transition-all duration-300 text-sm md:text-base relative group hover:cursor-pointer",active:"text-red-500 font-medium",inactive:"text-gray-600 hover:text-red-500"},indicator:{base:"absolute bottom-0 left-0 w-full h-0.5 bg-red-500 transform transition-all duration-300",active:"scale-x-100",inactive:"scale-x-0 group-hover:scale-x-100"}},Ga=()=>{const[s,i]=c.useState(Ce.defaultActiveSection),[r,o]=c.useState(""),t=c.useRef({});c.useEffect(()=>{console.log("Checking for all section elements..."),Ye.forEach(d=>{const h=document.getElementById(d.id);t.current[d.id]=!!h,h?console.log(`Found section: ${d.id}`):console.warn(`Section with ID "${d.id}" not found in the document!`)})},[]),c.useEffect(()=>{const d=()=>{const h=Ye.map(u=>({id:u.id,element:document.getElementById(u.id)})),w=h.find(u=>{if(!u.element)return!1;const x=u.element.getBoundingClientRect();return x.top<=Ce.activeDetectionOffset&&x.bottom>=50}),k=h.find(u=>u.id==="roadmap"&&u.element);window.innerHeight+window.scrollY>=document.body.offsetHeight-100&&k&&k.element?i("roadmap"):w?i(w.id):r&&i(r)};return d(),window.addEventListener("scroll",d),window.addEventListener("resize",d),()=>{window.removeEventListener("scroll",d),window.removeEventListener("resize",d)}},[r]);const l=d=>{let h=document.getElementById(d);if(o(d),i(d),!h&&d==="roadmap"){const w=["road-map","road_map","Roadmap","ROADMAP"];for(const k of w)if(h=document.getElementById(k),h){console.log(`Found roadmap with alternative ID: ${k}`);break}if(!h){const k=document.querySelectorAll("h1, h2, h3, h4, h5, h6");for(const m of k)if(m.textContent?.toLowerCase().includes("roadmap")){h=m.closest("section")||m.closest("div")||m.parentElement,console.log("Found roadmap section via heading text");break}}if(!h){console.log("Roadmap section not found - scrolling to bottom of the page"),window.scrollTo({top:document.documentElement.scrollHeight,behavior:"smooth"});return}}if(h){const w=document.querySelector("header, nav:first-of-type"),k=w?w.getBoundingClientRect().height:0;window.scrollTo({top:h.offsetTop-k-Ce.scrollOffset,behavior:"smooth"})}else console.error(`Section with ID "${d}" not found in the document!`)};return e.jsx("nav",{className:Z.container,style:{top:`${Ce.stickyTopPosition}px`},children:e.jsx("ul",{className:Z.list,children:Ye.map(({id:d,label:h})=>e.jsx("li",{children:e.jsxs("button",{onClick:()=>l(d),className:` + ${Z.button.base} + ${s===d?Z.button.active:Z.button.inactive} + `,children:[h,e.jsx("span",{className:` + ${Z.indicator.base} + ${s===d?Z.indicator.active:Z.indicator.inactive} + `})]})},d))})})},Wa=()=>{const s="ABOUT US".split("");return e.jsxs(a.div,{className:"relative min-h-[50vh] flex flex-col items-center justify-center text-center px-4 py-16 sm:py-20 overflow-hidden",variants:H,initial:"hidden",animate:"visible",children:[e.jsx(a.div,{className:"absolute top-5 left-5 sm:top-10 sm:left-10 w-24 h-24 sm:w-32 sm:h-32 rounded-full bg-gradient-to-br from-indigo-400 to-blue-500 blur-xl sm:blur-2xl opacity-60 dark:opacity-40",variants:P,custom:.2,initial:"hidden",animate:"visible"}),e.jsx(a.div,{className:"absolute bottom-5 right-5 sm:bottom-10 sm:right-10 w-32 h-32 sm:w-48 sm:h-48 rounded-full bg-gradient-to-tr from-emerald-300 to-teal-400 blur-xl sm:blur-2xl opacity-50 dark:opacity-30",variants:P,custom:.4,initial:"hidden",animate:"visible"}),e.jsx(a.div,{className:"absolute top-1/2 left-1/4 w-16 h-16 sm:w-24 sm:h-24 rounded-full bg-gradient-to-r from-amber-300 to-yellow-400 blur-xl sm:blur-2xl opacity-40 dark:opacity-20",variants:P,custom:.6,initial:"hidden",animate:"visible"}),e.jsxs(a.div,{className:"relative z-10 max-w-full",variants:z,initial:"hidden",animate:"visible",children:[e.jsx(a.h1,{className:"text-4xl sm:text-6xl md:text-8xl font-bold mb-6 sm:mb-9 tracking-tight relative inline-block font-Caveat",children:e.jsxs("div",{className:"flex justify-center items-center relative",children:[s.map((i,r)=>e.jsx(a.span,{variants:ke.letterAnimation,initial:"hidden",animate:"visible",transition:{delay:r*.1,duration:.6,ease:[.22,1,.36,1]},className:r>=s.length-2?"text-blue-800 dark:text-blue-600":"text-slate-800 dark:text-slate-200",whileHover:{scale:1.2,rotate:Math.random()*10-5,transition:{duration:.2}},children:i===" "?" ":i},r)),e.jsx(a.div,{className:"absolute -z-10 h-3 sm:h-6 bottom-1 sm:bottom-2 left-0 transform -skew-x-6 bg-gradient-to-r from-emerald-300 via-teal-400 to-cyan-300 opacity-70 dark:opacity-80",variants:$,initial:"hidden",animate:"visible",transition:{delay:.8,duration:.6}})]})}),e.jsx(a.div,{className:"w-16 sm:w-24 h-1 sm:h-1.5 mx-auto mb-6 sm:mb-8 rounded-full bg-gradient-to-r from-blue-500 to-slate-500",variants:Be,initial:"hidden",animate:"visible"}),e.jsxs(a.h2,{className:"text-xl sm:text-3xl md:text-4xl mb-8 sm:mb-12 max-w-xs sm:max-w-lg md:max-w-3xl mx-auto leading-relaxed font-Caveat relative text-slate-700 dark:text-slate-200",variants:V,initial:"hidden",animate:"visible",transition:{delay:.5,duration:.8},children:[e.jsxs(a.span,{className:"relative inline-block",variants:ke.hoverText,whileHover:"hover",children:["A",e.jsxs("span",{className:"text-rose-500 dark:text-rose-400 font-semibold",children:[" ","Community"]})]})," ","of"," ",e.jsx(a.span,{className:"relative inline-block",variants:ke.hoverText,whileHover:"hover",children:e.jsx("span",{className:"text-emerald-500 dark:text-emerald-400 font-semibold",children:"Open Source"})})," ",e.jsx(a.span,{variants:ne,animate:"visible",className:"inline-block",children:"Enthusiasts"})]})]}),e.jsx(a.div,{className:"absolute w-64 h-64 sm:w-96 sm:h-96 bg-gradient-to-br from-indigo-100 via-purple-100 to-pink-100 dark:from-indigo-900/20 dark:via-purple-900/20 dark:to-pink-900/20 rounded-full blur-2xl sm:blur-3xl opacity-30 dark:opacity-20",variants:ke.mouseFollow,initial:"hidden",animate:"visible",whileHover:"hover",style:{mixBlendMode:"multiply"}})]})},$a=()=>{const[s,i]=c.useState("120");return c.useEffect(()=>{const r=()=>{const o=window.innerWidth;o<640?i("50"):o<768?i("70"):o<1024?i("90"):i("120")};return r(),window.addEventListener("resize",r),()=>window.removeEventListener("resize",r)},[]),e.jsx("div",{className:"py-16",children:e.jsx(a.div,{className:"relative rounded-lg shadow-md overflow-hidden",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},children:e.jsxs("div",{className:"relative",children:[e.jsxs("div",{className:"relative h-[280px] md:h-[400px] overflow-hidden",children:[e.jsx("div",{className:"absolute inset-0 w-full h-full",style:{backgroundImage:"url('assets/Images/teach.jpg')",backgroundSize:"cover",backgroundPosition:"center"}}),e.jsxs("div",{className:"relative h-full flex items-center justify-center",children:[e.jsxs("svg",{className:"w-full h-full absolute inset-0",viewBox:"0 0 1200 400",preserveAspectRatio:"xMidYMid slice",children:[e.jsx("defs",{children:e.jsxs("mask",{id:"textMask",children:[e.jsx("rect",{width:"100%",height:"100%",fill:"white"}),e.jsx("text",{x:"50%",y:"50%",textAnchor:"middle",dominantBaseline:"middle",fill:"black",fontSize:s,fontWeight:"bold",fontFamily:"Arial, sans-serif",letterSpacing:"0.05em",className:"select-none",children:"SUGAR LABS"}),e.jsx("line",{x1:"30%",y1:"65%",x2:"70%",y2:"65%",stroke:"black",strokeWidth:"4"}),e.jsx("line",{x1:"35%",y1:"70%",x2:"65%",y2:"70%",stroke:"black",strokeWidth:"3"})]})}),e.jsx("rect",{width:"100%",height:"100%",fill:"rgba(255, 255, 255, 0.92)",mask:"url(#textMask)"})]}),e.jsx("div",{className:"absolute inset-0 bg-gradient-to-t from-slate-900/30 via-transparent to-transparent mix-blend-overlay"})]}),e.jsx("div",{className:"absolute top-6 left-6 w-16 h-16 border-t-2 border-l-2 border-white/60"}),e.jsx("div",{className:"absolute bottom-6 right-6 w-16 h-16 border-b-2 border-r-2 border-white/60"})]}),e.jsxs("div",{className:"py-8 px-6 md:px-12 bg-white text-center",children:[e.jsx(a.h3,{className:"text-lg md:text-xl font-medium text-blue-600 mb-3",initial:{opacity:0,y:10},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{delay:.3},children:"Innovate. Educate. Transform."}),e.jsx(a.p,{className:"text-base md:text-lg text-slate-700 max-w-2xl mx-auto leading-relaxed",initial:{opacity:0,y:10},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{delay:.5},children:"Sugar Labs creates innovative educational tools that transform how children learn and explore technology. Our community-driven approach empowers young minds to become creators, not just consumers."})]})]})})})},ae={sectionId:"mission",title:{prefix:"Our",highlighted:"Mission"},paragraphs:["Sugar Labs is dedicated to creating learning tools that transform how children learn and explore technology. Our mission is to, as a community of teachers and learners, create quality software and curriculae under a free/libre/open-source (FLO) license that encourages collaborative learning and creativity.","We believe that every child deserves equal access to a robust set of learning tools regardless of their background or location. Our global network of teachers and learners work to imagine, design, and test our innovative learning tools for meaningful use in classrooms worldwide.","Our community-driven approach brings together educators, developers, and volunteers who are passionate about making a difference in education worldwide. Together, we're building tools that make learning engaging, accessible, and fun."],images:{main:{src:"assets/Images/student3.png",alt:"Children using Sugar Labs software in a classroom"},gallery:[{src:"assets/Images/student9.png",alt:"Students collaborating on a Sugar Labs project"},{src:"assets/Images/teach4.png",alt:"Teacher helping students with Sugar Labs activities"},{src:"assets/Images/student13.png",alt:"Children exploring creative software tools"}]}},qa=()=>e.jsx("section",{id:ae.sectionId,className:"w-full py-24 bg-white",children:e.jsxs("div",{className:"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8",children:[e.jsxs("div",{className:"text-center mb-16",children:[e.jsxs(a.h2,{className:"text-3xl font-semibold text-slate-800 sm:text-4xl mb-4 tracking-tight",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},children:[e.jsx("span",{className:"text-blue-900 font-medium",children:ae.title.prefix})," ",e.jsx("span",{className:"text-red-600 font-medium",children:ae.title.highlighted})]}),e.jsx(a.div,{className:"h-0.5 w-24 bg-gradient-to-r from-blue-600 to-red-600 mx-auto mb-8",initial:{width:0},whileInView:{width:96},viewport:{once:!0},transition:{duration:.8,delay:.2}})]}),e.jsxs("div",{className:"flex flex-col lg:flex-row justify-between items-center gap-16",children:[e.jsx(a.div,{className:"w-full lg:w-1/2 order-2 lg:order-1",initial:{opacity:0,x:-20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.8},children:e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"absolute inset-0 bg-gradient-to-r from-blue-600/5 to-red-600/5 rounded-lg -m-2 -z-10"}),e.jsx("div",{className:"overflow-hidden rounded-lg shadow-xl",children:e.jsx("img",{src:ae.images.main.src,alt:ae.images.main.alt,className:"w-full h-full object-cover transition-transform duration-700 hover:scale-105"})})]})}),e.jsxs(a.div,{className:"w-full lg:w-1/2 order-1 lg:order-2 text-slate-700",initial:{opacity:0,x:20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.8},children:[e.jsx("div",{className:"space-y-6",children:ae.paragraphs.map((s,i)=>e.jsx(a.p,{className:"text-base sm:text-lg leading-relaxed",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:.1*i},children:s},i))}),e.jsx(a.div,{className:"grid grid-cols-2 md:grid-cols-3 gap-4 mt-10",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.3},children:ae.images.gallery.map((s,i)=>e.jsx(a.div,{className:"aspect-video overflow-hidden rounded-md shadow-md",whileHover:{scale:1.03},transition:{duration:.3},children:e.jsx("img",{src:s.src,alt:s.alt,className:"w-full h-full object-cover"})},i))})]})]})]})}),Ya=[{id:1,title:"Learning as a verb",description:"Knowledge is a noun, learning is a verb. Instead of curating prescribed information to be instructed, we create tools for learning. Our methodology is called *Constructionism*.",image:"assets/Images/teach4.png"},{id:2,title:"Free and open",description:"We believe that learners can learn not just *with* their tools but also *from* their tools. This is why we distribute all our software and curriculae as free/libre/open (FLO)",image:"assets/Images/teach5.png"},{id:3,title:"Equitable",description:"By helping others learn and grow, we learn and grow as well. We also help make the world a better place for ourselves and others.",image:"assets/Images/teach6.png"},{id:4,title:"Community led",description:"We work with our friends, both locally and globally, to design and develop learning tools meaningful for their communities.",image:"assets/Images/student5.png"},{id:5,title:"Accessible",description:"We aim to make our learning tools accessible to as many youth as we possibly can.",image:"assets/Images/student7.png"},{id:6,title:"Hard fun",description:"Our work is challenging, but it’s also fun. We work hard to be playful and inspiring.",image:"assets/Images/student6.png"}],be={sectionId:"principles",title:{prefix:"Our",highlight:"Principles"},description:"Sugar Labs is founded on a set of fundamental principles that guide our work. We believe, for example, that learning is a verb, and we therefore create tools to learn with. We also believe in the freedom to study how one's tools work, and we therefore license all our work under a FLO license. Read on to learn more about our commitment to these principles, as well as our commitment to equity, community, accessibility, and hard fun.",featuredImage:"assets/Images/student11.png"},Ja=()=>e.jsx("section",{id:be.sectionId,className:"w-full py-24 bg-white",children:e.jsxs("div",{className:"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8",children:[e.jsxs("div",{className:"text-center mb-16",children:[e.jsxs(a.h2,{className:"text-3xl font-semibold text-slate-800 sm:text-4xl mb-4 tracking-tight",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},children:[e.jsx("span",{className:"text-blue-900 font-medium",children:be.title.prefix})," ",e.jsx("span",{className:"text-red-600 font-medium",children:be.title.highlight})]}),e.jsx(a.div,{className:"h-0.5 w-24 bg-gradient-to-r from-indigo-700 to-rose-700 mx-auto mb-8",initial:{width:0},whileInView:{width:96},viewport:{once:!0},transition:{duration:.8,delay:.2}})]}),e.jsxs("div",{className:"flex flex-col lg:flex-row justify-between items-center gap-16 mb-20",children:[e.jsx(a.div,{className:"w-full lg:w-1/2",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.8},children:e.jsx("div",{className:"bg-slate-50 p-8 rounded-lg shadow-md border-l-2 border-indigo-700",children:e.jsx("p",{className:"text-base sm:text-lg text-slate-700 leading-relaxed",children:be.description})})}),e.jsx(a.div,{className:"w-full lg:w-1/2",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.8,delay:.2},children:e.jsxs("div",{className:"rounded-lg overflow-hidden shadow-lg relative",children:[e.jsx("img",{src:be.featuredImage,alt:"Our Principles",className:"w-full h-[350px] object-cover"}),e.jsx("div",{className:"absolute inset-0 bg-gradient-to-t from-slate-900/80 via-transparent to-transparent opacity-80"}),e.jsxs("div",{className:"absolute bottom-0 left-0 right-0 p-6 text-white",children:[e.jsx("h3",{className:"text-xl font-semibold",children:"Our Guiding Principles"}),e.jsx("div",{className:"w-20 h-0.5 bg-rose-600 mt-2 mb-3"}),e.jsx("p",{className:"text-sm text-slate-100",children:"Values that drive our organization forward"})]})]})})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8",children:Ya.map((s,i)=>e.jsx(a.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.1*i},children:e.jsxs("div",{className:"bg-white rounded-lg shadow-md overflow-hidden h-full flex flex-col border border-slate-200 transition-all duration-300 hover:shadow-lg hover:translate-y-[-4px]",children:[e.jsx("div",{className:"h-48 overflow-hidden relative",children:e.jsx("img",{src:s.image,alt:s.title,className:"w-full h-full object-cover"})}),e.jsxs("div",{className:"p-6 flex flex-col flex-grow bg-gradient-to-b from-white to-slate-50",children:[e.jsx("h3",{className:"text-lg font-semibold text-slate-800 mb-3 pb-2 border-b border-slate-200",children:s.title}),e.jsx("p",{className:"text-slate-700 text-base",children:s.description})]})]})},s.id))})]})}),Ka=[{title:"Power users, involved in feedback",description:'Reach one hundred "power" users, regularly providing their feedback to the development community, by the end of 2025',category:"Community"},{title:"Leadership in education",description:"Take fifteen actions (e.g. conferences, articles, events-led) in 2025 that help us establish ourselves as leaders in education technology.",category:"Education"},{title:"New Sugar Stories",description:"Publish five new Sugar Stories from the community in 2025.",category:"Content"},{title:"Establish 150k in annual revenue",description:"In order to magnify our impact, we aim to establish 150k in annual revenue by the end of 2025. These funds will help us establish our operations, starting by hiring one full-time staff and three part time workers to serve our stakeholders.",category:"Sustainability"},{title:"200 volunteers",description:"In order to best serve our community, our goal is to have twenty active mentors, and 180 active volunteers.",category:"Community"},{title:"1,000 people on Matrix",description:"Our main mode of communication is on Matrix chat. Our goal in 2025 is to have 1,000 users on our chat, discussing ideas, designs, and development for our community-led suite of learning tools.",category:"Communication"}],Je={title:{main:"Our ",highlight:"Goals"},introduction:"At Sugar Labs, we strive to create a vibrant ecosystem where technology empowers education. Our strategic goals focus on expanding our impact while maintaining our core values."},re={goalItem:{initial:{opacity:0,x:-20}},flowContainer:{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0}}},Xa=()=>e.jsx("section",{id:"goals",className:"w-full py-24 bg-white",children:e.jsxs("div",{className:"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8",children:[e.jsxs("div",{className:"text-center mb-16",children:[e.jsxs(a.h2,{className:"text-3xl font-semibold text-slate-800 sm:text-4xl mb-4 tracking-tight",initial:re.flowContainer.initial,whileInView:re.flowContainer.whileInView,viewport:{once:!0},transition:{duration:.6},children:[e.jsx("span",{className:"text-blue-900 font-medium",children:Je.title.main})," ",e.jsx("span",{className:"text-red-600 font-medium",children:Je.title.highlight})]}),e.jsx(a.div,{className:"h-0.5 w-24 bg-gradient-to-r from-blue-600 to-rose-400 mx-auto mb-8",initial:{width:0},whileInView:{width:96},viewport:{once:!0},transition:{duration:.8,delay:.2}}),e.jsx(a.p,{className:"text-base sm:text-lg text-slate-600 max-w-3xl mx-auto",initial:re.flowContainer.initial,whileInView:re.flowContainer.whileInView,viewport:{once:!0},transition:{duration:.6,delay:.3},children:Je.introduction})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:Ka.map((s,i)=>e.jsxs(a.div,{className:`bg-white rounded-lg shadow-sm p-6 border border-slate-100 transition-all duration-300 + hover:shadow-md group relative overflow-hidden`,initial:re.goalItem.initial,whileInView:{opacity:1,x:0},whileHover:{y:-5},viewport:{once:!0},transition:{duration:.5,delay:.1*(i%6)},children:[e.jsx("div",{className:`absolute top-0 left-0 right-0 h-1 + ${i%3===0?"bg-blue-500":i%3===1?"bg-rose-400":"bg-gradient-to-r from-blue-600 to-rose-400"}`}),e.jsxs("div",{className:"flex items-center mb-4",children:[e.jsx("div",{className:"w-8 h-8 rounded-full bg-gradient-to-br from-blue-500 to-rose-400 flex items-center justify-center text-white font-semibold text-sm",children:i+1}),e.jsx("div",{className:"h-px flex-grow bg-slate-100 ml-3"})]}),e.jsx("h4",{className:"font-semibold text-slate-800 text-lg mb-3",children:s.title}),e.jsx("p",{className:"text-slate-600 leading-relaxed",children:s.description}),s.category&&e.jsx("div",{className:"mt-4 inline-block px-3 py-1 bg-slate-50 text-xs font-medium text-slate-600 rounded-full",children:s.category}),e.jsx("div",{className:"absolute bottom-0 left-0 right-0 h-0.5 bg-gradient-to-r from-blue-500 to-rose-400 transform scale-x-0 group-hover:scale-x-100 transition-transform duration-300 origin-left"})]},i))}),e.jsx(a.div,{className:"mt-16 text-center",initial:re.flowContainer.initial,whileInView:re.flowContainer.whileInView,viewport:{once:!0},transition:{duration:.6,delay:.5}})]})}),Ke=[{title:"Sugar on a Stick (SoaS)",description:"A USB version of the Sugar platform, an environment made for kids to learn and explore. It can be used to temporarily boot into SoaS or to install onto your computer.",tags:["Distribution","Portable"],imageUrl:"assets/Images/SOAS.jpeg",link:"/bootablesoas"},{title:"Google Summer of Code (GSoC)",description:"GSoC is a global program, hosted by Google, focused on bringing more student developers into free/libre/open (FLO) software development.",tags:["Community","Development"],imageUrl:"assets/Images/GSOC.png",exlink:"https://summerofcode.withgoogle.com/programs/2025/organizations/sugar-labs"},{title:"Music Blocks",description:"A visual programming language for exploring musical concepts. Based on the tried-and-true Logo programming language, you can blend art, geometry, and music to make challenging and fun creations.",tags:["Education","Creative"],progress:75,imageUrl:"assets/TryNowImages/musicBlocks1.png",link:"/musicblocks"},{title:"Sugarizer",description:"Multi-platform implementation of the Sugar Learning Platform. Versions are available for the web, as well as for iOS, Android, Windows, and GNU/Linux.",tags:["Web","Mobile"],progress:80,imageUrl:"assets/TryNowImages/sugarizer.png",link:"/sugarizer"}],ie={sectionId:"projects",title:{prefix:"Our",highlight:"Projects"},description:"Sugar Labs develops and maintains several key projects that support our educational mission. These projects range from complete kid-friendly desktop environments to specific applications, each designed to enhance learning through technology.",ctaText:"Learn more"},Qa=()=>{const[s,i]=c.useState(!1),r=3,o=s?Ke:Ke.slice(0,r);return e.jsx("section",{id:ie.sectionId,className:"w-full py-24",children:e.jsxs("div",{className:"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8",children:[e.jsxs("div",{className:"text-center mb-16",children:[e.jsxs(a.h2,{className:"text-3xl font-semibold text-slate-800 sm:text-4xl mb-4 tracking-tight",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},children:[e.jsx("span",{className:"text-blue-900 font-medium",children:ie.title.prefix})," ",e.jsx("span",{className:"text-red-600 font-medium",children:ie.title.highlight})]}),e.jsx(a.div,{className:"h-0.5 w-24 bg-gradient-to-r from-blue-600 to-red-600 mx-auto mb-8",initial:{width:0},whileInView:{width:96},viewport:{once:!0},transition:{duration:.8,delay:.2}}),e.jsx(a.p,{className:"text-base sm:text-lg text-slate-600 max-w-3xl mx-auto",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.3},children:ie.description})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8",children:o.map((t,l)=>e.jsx(a.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.1*l},className:"h-full",children:e.jsxs("div",{className:"bg-white rounded-lg shadow-md overflow-hidden h-full flex flex-col border border-slate-100 transition-all duration-300 hover:shadow-lg hover:translate-y-[-4px]",children:[e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"absolute top-0 right-0 z-10",children:e.jsxs("div",{className:"bg-blue-600 text-white text-xs py-1 px-3 font-medium",children:["Project ",l+1]})}),e.jsx("div",{className:"w-full h-48 bg-slate-50 flex items-center justify-center p-6",children:e.jsx("img",{src:t.imageUrl,alt:t.title,className:"w-full h-full object-contain"})})]}),e.jsxs("div",{className:"p-6 flex flex-col flex-grow",children:[e.jsx("h3",{className:"text-lg font-semibold text-slate-800 mb-3 pb-2 border-b border-slate-100",children:t.title}),e.jsx("p",{className:"text-slate-600 mb-6 flex-grow text-base",children:t.description}),t.tags&&t.tags.length>0&&e.jsx("div",{className:"flex flex-wrap gap-2 mb-4",children:t.tags.map((d,h)=>e.jsx("span",{className:"px-2 py-1 bg-slate-100 text-slate-700 rounded-full text-xs font-medium",children:d},h))}),t.link&&e.jsxs("a",{href:t.link,className:"text-blue-600 hover:text-red-600 font-medium text-sm flex items-center gap-1 mt-auto transition-colors duration-300 group",children:[ie.ctaText,e.jsx("svg",{className:"w-4 h-4 transition-transform duration-300 group-hover:translate-x-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M9 5l7 7-7 7"})})]}),t.exlink&&e.jsxs("a",{href:t.exlink,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-red-600 font-medium text-sm flex items-center gap-1 mt-auto transition-colors duration-300 group",children:[ie.ctaText,e.jsx("svg",{className:"w-4 h-4 transition-transform duration-300 group-hover:translate-x-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"})})]}),!t.link&&!t.exlink&&e.jsxs("button",{className:"text-blue-600 hover:text-red-600 font-medium text-sm flex items-center gap-1 mt-auto transition-colors duration-300 group",onClick:()=>window.location.href="#projects",children:[ie.ctaText,e.jsx("svg",{className:"w-4 h-4 transition-transform duration-300 group-hover:translate-x-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M9 5l7 7-7 7"})})]})]})]})},l))}),Ke.length>r&&e.jsx(a.div,{className:"flex justify-center mt-14",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:.4},children:s?e.jsxs("button",{onClick:()=>i(!1),className:"px-8 py-3 bg-blue-600 hover:bg-red-600 text-white rounded-lg shadow-sm font-medium transition-all duration-300 inline-flex items-center gap-2",children:["Show less",e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M5 15l7-7 7 7"})})]}):e.jsxs("button",{onClick:()=>i(!0),className:"px-8 py-3 bg-blue-600 hover:bg-red-600 cursor-pointer text-white rounded-lg shadow-sm font-medium transition-all duration-300 inline-flex items-center gap-2",children:["Show more",e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M19 9l-7 7-7-7"})})]})})]})})},Pt=[{title:"Mission, vision, values",description:"Establishing our foundational principles, creating founding documents and holding elections to our Board of Directors.",borderColor:"border-red-500",stepColor:"bg-red-500"},{title:"Community building",description:"Work to establish a community of teachers and learners, maintaining ways that we can community and work together to solve problems.",borderColor:"border-red-400",stepColor:"bg-purple-500"},{title:"Development of learning tools",description:"Design, develop, and deploy software tools for learning.",borderColor:"border-red-300",stepColor:"bg-blue-500"},{title:"Study impact",description:"Showcase student work, publish teacher and developer stories, and poll users to better understand our impact. Make adjustments based on results.",borderColor:"border-blue-400",stepColor:"bg-red-500"},{title:"Strategic growth",description:"Work with partners to broaden our reach and deepen our impact.",borderColor:"border-blue-500",stepColor:"bg-purple-500"}],Te={sectionId:"roadmap",title:{prefix:"Our",highlight:"Strategy"},description:"Our strategic roadmap outlines our key milestones and future directions as we continue to grow and innovate."},Za=()=>e.jsx("section",{id:Te.sectionId,className:"w-full py-24 bg-white",children:e.jsxs("div",{className:"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8",children:[e.jsxs("div",{className:"text-center mb-16",children:[e.jsxs(a.h2,{className:"text-3xl font-semibold text-slate-800 sm:text-4xl mb-4 tracking-tight",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},children:[e.jsx("span",{className:"text-blue-900 font-medium",children:Te.title.prefix})," ",e.jsx("span",{className:"text-red-600 font-medium",children:Te.title.highlight})]}),e.jsx(a.div,{className:"h-0.5 w-24 bg-gradient-to-r from-blue-600 to-red-600 mx-auto mb-8",initial:{width:0},whileInView:{width:96},viewport:{once:!0},transition:{duration:.8,delay:.2}}),e.jsx(a.p,{className:"text-base sm:text-lg text-slate-600 max-w-3xl mx-auto",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.3},children:Te.description})]}),e.jsxs("div",{className:"hidden md:block relative w-full mt-20",children:[e.jsx(a.div,{className:"absolute top-0 bottom-0 left-1/2 w-0.5 bg-slate-200 transform -translate-x-1/2",initial:{scaleY:0,transformOrigin:"top"},whileInView:{scaleY:1},viewport:{once:!0},transition:{duration:1.2}}),e.jsx("div",{className:"relative",children:Pt.map((s,i)=>e.jsxs(a.div,{className:`flex mb-10 ${i%2===0?"justify-start":"justify-end"} relative`,initial:{opacity:0,x:i%2===0?-30:30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6,delay:.2*i},children:[e.jsx("div",{className:`w-3/7 ${i%2===0?"pr-1":"pl-1"}`,children:e.jsxs("div",{className:`p-5 bg-white rounded-lg shadow-md border-t-2 ${s.borderColor||"border-blue-600"} transition-all duration-300 hover:shadow-lg`,children:[e.jsx("h3",{className:"text-base font-semibold text-slate-800 mb-2 pb-2 border-b border-slate-100",children:s.title}),e.jsx("p",{className:"text-slate-600 text-sm",children:s.description||"Milestone in our journey"})]})}),e.jsx("div",{className:"absolute top-5 left-1/2 transform -translate-x-1/2",children:e.jsx(a.div,{className:`w-10 h-10 rounded-full flex items-center justify-center text-white font-semibold shadow-sm z-10 + ${s.stepColor||"bg-blue-600"}`,initial:{scale:0},whileInView:{scale:1},viewport:{once:!0},transition:{duration:.5,delay:.3+.1*i},children:i+1})})]},i))})]}),e.jsx("div",{className:"md:hidden relative w-full mt-16",children:e.jsxs("div",{className:"flex flex-col items-start space-y-12",children:[e.jsx(a.div,{className:"absolute top-0 bottom-0 left-5 w-0.5 bg-slate-200 h-full",style:{zIndex:1},initial:{scaleY:0,transformOrigin:"top"},whileInView:{scaleY:1},viewport:{once:!0},transition:{duration:1.2}}),Pt.map((s,i)=>e.jsxs(a.div,{className:"relative w-full flex items-start space-x-4 pl-4 pr-2",style:{zIndex:2},initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:.1*i},children:[e.jsx(a.div,{className:`w-10 h-10 flex-shrink-0 rounded-full flex items-center justify-center text-white font-semibold shadow-sm + ${s.stepColor||"bg-blue-600"}`,initial:{scale:0},whileInView:{scale:1},viewport:{once:!0},transition:{duration:.4,delay:.2},children:i+1}),e.jsxs("div",{className:`flex-grow p-5 bg-white rounded-lg shadow-md border-l-2 ${s.borderColor||"border-blue-600"}`,children:[e.jsx("h3",{className:"text-base font-semibold text-slate-800 mb-2 pb-2 border-b border-slate-100",children:s.title}),e.jsx("p",{className:"text-slate-600 text-sm",children:s.description||"Milestone in our journey"})]})]},i))]})})]})}),er=()=>{const[,s]=c.useState(!1);return c.useEffect(()=>{setTimeout(()=>s(!0),100)},[]),e.jsxs("div",{className:"bg-white min-h-screen",children:[e.jsx("div",{className:"relative z-20",children:e.jsx(A,{})}),e.jsxs(a.main,{initial:{opacity:0},animate:{opacity:1},transition:{duration:.6},className:"w-full relative z-10",children:[e.jsx(Wa,{}),e.jsx("div",{className:"w-full",children:e.jsxs("div",{className:"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8",children:[e.jsx(Ga,{}),e.jsx($a,{})]})}),e.jsx(qa,{}),e.jsx("div",{className:"w-full",children:e.jsx(Ja,{})}),e.jsx(Xa,{}),e.jsx("div",{className:"w-full",children:e.jsx(Qa,{})}),e.jsx(Za,{})]}),e.jsx(M,{})]})},tr=({director:s})=>{const[i,r]=c.useState(!1),o=i||!s.imageUrl;return e.jsxs("div",{className:"flex flex-col h-full bg-white rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300",children:[e.jsxs("div",{className:"flex justify-center pt-8 pb-4 relative",children:[e.jsx("div",{className:"absolute top-0 left-0 w-1 h-full bg-red-500"}),e.jsx("div",{className:"w-32 h-32 rounded-full overflow-hidden border-4 border-white shadow-md",children:o?e.jsx("div",{className:"flex items-center justify-center w-full h-full bg-gray-100 text-gray-700 text-2xl font-bold",children:s.name.split(" ").map(t=>t[0]).join("")}):e.jsx("img",{src:s.imageUrl,alt:`${s.name}`,className:"w-full h-full object-cover",onError:()=>r(!0)})})]}),e.jsxs("div",{className:"flex flex-col flex-grow p-5 gap-3",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("h3",{className:"text-xl font-bold text-gray-900",children:s.name}),s.position&&e.jsx("p",{className:"text-sm font-medium text-red-500 mt-1",children:s.position})]}),e.jsx("div",{className:"w-16 h-0.5 bg-gray-200 mx-auto"}),e.jsx("div",{className:"flex-grow",children:e.jsx("div",{className:"text-gray-600 text-sm leading-relaxed max-h-28 overflow-y-auto pr-1 custom-scrollbar",children:s.bio||"No biography available."})}),e.jsx("div",{className:"pt-3 mt-auto border-t border-gray-100",children:e.jsxs("div",{className:"flex items-center justify-center gap-4",children:[s.socialLinks?.linkedin&&e.jsx(Xe,{href:s.socialLinks.linkedin,aria:"LinkedIn",icon:e.jsx(sr,{})}),s.socialLinks?.github&&e.jsx(Xe,{href:s.socialLinks.github,aria:"GitHub",icon:e.jsx(ar,{})}),s.socialLinks?.wiki&&e.jsx(Xe,{href:s.socialLinks.wiki,aria:"Wiki",icon:e.jsx(rr,{})}),!s.socialLinks?.linkedin&&!s.socialLinks?.github&&!s.socialLinks?.wiki&&e.jsx("span",{className:"text-xs text-gray-400",children:"No social links available"})]})})]})]})},Xe=({href:s,aria:i,icon:r})=>e.jsx("a",{href:s,target:"_blank",rel:"noopener noreferrer",className:"text-gray-500 hover:text-red-500 transition-colors","aria-label":i,children:r}),sr=()=>e.jsx("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{d:"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452z"})}),ar=()=>e.jsx("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{fillRule:"evenodd",d:"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z",clipRule:"evenodd"})}),rr=()=>e.jsx("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{d:"M4 5h2l2.5 9L12 5h2l3.5 9L20 5h2l-4 14h-2l-4-10-4 10H6L2 5z"})}),ir=[{id:1,name:"Claudia Urrea",position:"Treasurer, Sugar Labs",bio:`Claudia Urrea is the Senior Associate Director for pK-12 at the MIT Abdul Latif Jameel World Education Lab (J-WEL). Claudia was born in Colombia, where she received an undergraduate degree in Computer Science from EAFIT University. Claudia received her master's degree in Educational Media and Technology from Boston University, and her doctorate degree from the MIT Media Laboratory. Her Ph.D. thesis studied the implications of one-to-one learning in a rural setting in Costa Rica. Claudia worked for 5 years as the Director of Learning for One Laptop Per Child, collaborating with SugarLabs in that role. She has been in the board of SugarLabs since 2010. + +For the past 25 years, Claudia has helped multiple governments and non-government agencies- The New York Academy of Sciences, Schlumberger Excellence in Education Development, International Development Research Centre, among others- to empower and support schools and communities of learners to evolve from traditional teaching methods into progressive learning environments. She has also a research scientist position with the Lifelong Kindergarten group at the MIT Media Lab. She has taught several classes at the Harvard Summer Program and Early Childhood Development program at Tufts University.`,imageUrl:"assets/Images/BoardMembers/Claudia.png",socialLinks:{linkedin:"https://www.linkedin.com/in/claudia-urrea-ph-d-0335041/",wiki:"https://wiki.sugarlabs.org/go/User:Claudia_Urrea"}},{id:2,name:"Devin Ulibarri",position:"Executive Director, Sugar Labs",bio:`Devin Ulibarri has been involved in Sugar Labs for over a decade. Ulibarri has been involved in education for twenty years, and he's advocated for free/libre/open (FLO) source software, particularly in education, for the past decade. For two years from 2022 to 2024, he worked as Outreach and Communications Coordinator at the Free Software Foundation. + +At Sugar Labs, Ulibarri has worked closely with Walter Bender to create Music Blocks visual programming language. In addition to this, he's mentored for Google Summer of Code (GSoC) and Google Code-In (GCI), and he regularly teaches students as young as five years old using a rich variety of Sugar tools. Ulibarri plays classical guitar, and he is the Dungeon Master for his family on the weekends.`,imageUrl:"assets/Images/BoardMembers/Devin.png",socialLinks:{github:"https://github.com/pikurasa",linkedin:"https://www.linkedin.com/in/devin-ulibarri-76277a300/",wiki:"https://wiki.sugarlabs.org/go/User:Pikurasa"}},{id:3,name:"Samson Goddy",position:"Board Member, Sugar Labs",bio:"Samson is an open source advocate who is very passionate about Edtech. He is currently working with International Telecommunication Union (ITU) to bring more African girls into Technology. He is the co-founder of Open Source Community Africa, a movement that promotes and educate everything open source within Africa.",imageUrl:"assets/Images/BoardMembers/Samson.jpeg",socialLinks:{github:"https://github.com/samswag",linkedin:"https://www.linkedin.com/in/samsongoddy/",wiki:"https://wiki.sugarlabs.org/go/User:Samson_Goddy"}},{id:4,name:"Sebastian Silva",position:"Board Member, Sugar Labs",bio:`Sebastian Silva learned Logo as a 5-year-old child in a workshop in Lima in the 1980s. Later, he taught himself Basic, Pascal, Python, JS, etc... but most importantly, through exploring GNU/Linux, he became enamoured with the philosophy of Software Freedom. He went on to study Psychology to satisfy his curiosity. Soon, he was involved with the original Sugar deployments on OLPC laptops in Peru, Colombia, and Uruguay - organizing local groups to promote software freedom in the region. SomosAzucar initiative (a SL local lab) was responsible for the addition of Quechua, Aymara and Awajún system locales to GLIBC in order to support these deployments. Currently, Silva works as Senior Programming Coach at Laboratoria, a feminist organization. In his spare time, he has written a few programming-learning gadgets such as SUPER-8 and Jappy Creator, and he's the Software Curator for the laptop-deployment projects of Repurpose-IT.org. He misses having a viable constructivist learning environment that "free desktops" can use, so he has returned to the Sugar Labs board.`,imageUrl:"assets/Images/BoardMembers/Silva.png",socialLinks:{github:"https://github.com/icarito",wiki:"https://wiki.sugarlabs.org/go/User:Sebastian"}},{id:5,name:"Sumit Srivastava",position:"Board Member, Sugar Labs",bio:"Sumit Srivastava is a recipient of Stability AI supercomputer grant for open source AI research and is currently working on a new AI project called Cotyper. Prior to this, he started a leading medical search engine and was a part of the leading talent investor Entrepreneur First. He is a maintainer of the Music Blocks programming language. Sumit started many learning groups in Asia where people learn by doing and get iterative feedback. For fun, he plays ukulele and flute, and he builds things like livestreaming software and air purifiers.",imageUrl:"assets/Images/BoardMembers/Sumit.jpeg",socialLinks:{github:"https://github.com/sum2it",linkedin:"https://www.linkedin.com/in/sumsri/",wiki:"https://wiki.sugarlabs.org/go/User:Sum2it"}},{id:6,name:"Walter Bender",position:"Secretary, Sugar Labs",bio:"Founder of Sugar Labs and co-founder of One Laptop Per Child (OLPC), Walter Bender has more than thirty years experience as an academic advisor at MIT. He has more than forty years experience as a software developer. Author of numerous learning tools, Bender is the original author of Turtle Blocks and Music Blocks, as well as many Sugar Activities.",imageUrl:"assets/Images/BoardMembers/Walter.png",socialLinks:{github:"https://github.com/walterbender",linkedin:"https://www.linkedin.com/in/walterbender/",wiki:"https://wiki.sugarlabs.org/go/User:Walter"}}],or=()=>e.jsxs("div",{children:[e.jsx(A,{}),e.jsx("section",{className:"py-24 px-4 bg-white",children:e.jsxs("div",{className:"container mx-auto max-w-7xl",children:[e.jsxs("div",{className:"text-center mb-16",children:[e.jsxs(a.h2,{className:"text-4xl md:text-5xl font-bold text-gray-900 mb-4",initial:"hidden",whileInView:"visible",viewport:{once:!0},variants:xt,children:[e.jsxs(a.span,{className:"text-red-500 font-Pacifico",variants:W,initial:"hidden",whileInView:"visible",viewport:{once:!0},children:["Meet"," "]}),"Our Board of Directors"]}),e.jsx("div",{className:"flex justify-center",children:e.jsx(a.div,{className:"h-1 bg-red-500 mb-8",initial:"hidden",whileInView:"visible",viewport:{once:!0},variants:Be})}),e.jsx(a.p,{className:"text-lg text-gray-600 max-w-3xl mx-auto",initial:"hidden",whileInView:"visible",viewport:{once:!0},variants:ve,children:`The "Sugar Labs Board of Directors" consists of dedicated six individuals who guide our organization's mission to provide educational tools for children worldwide. They bring diverse expertise in education, technology, and nonprofit leadership.`})]}),e.jsx(a.div,{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8",variants:ot,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.1},children:ir.map(s=>e.jsx(a.div,{className:"h-full",variants:nt,whileHover:"hover",children:e.jsx(tr,{director:s})},s.id))})]})}),e.jsx(M,{})]}),nr=()=>e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsxs("div",{className:"min-h-screen bg-gray-50",children:[e.jsxs(a.section,{variants:P,initial:"hidden",animate:"visible",className:"relative w-full bg-gradient-to-r from-blue-900 via-slate-800 to-slate-900 py-32 overflow-hidden",children:[e.jsx("div",{className:"absolute inset-0 overflow-hidden",children:e.jsxs("svg",{className:"absolute w-full h-full opacity-5",viewBox:"0 0 100 100",preserveAspectRatio:"none","aria-hidden":"true",children:[e.jsx("defs",{children:e.jsx("pattern",{id:"grid",width:"8",height:"8",patternUnits:"userSpaceOnUse",children:e.jsx("path",{d:"M 8 0 L 0 0 0 8",fill:"none",stroke:"white",strokeWidth:"0.5"})})}),e.jsx("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:"url(#grid)"})]})}),e.jsx("div",{className:"container mx-auto px-4 sm:px-6 lg:px-8 relative z-10",children:e.jsxs(a.div,{className:"max-w-3xl",variants:V,initial:"hidden",animate:"visible",children:[e.jsxs(a.h1,{className:"text-4xl md:text-5xl font-bold text-white mb-4 tracking-tight",variants:V,initial:"hidden",animate:"visible",children:["Contact ",e.jsx("span",{className:"text-blue-200",children:"Sugar Labs"})]}),e.jsx(a.div,{className:"w-20 h-1 bg-blue-400 mb-6",variants:Be,initial:"hidden",animate:"visible"}),e.jsx(a.p,{className:"text-base md:text-lg text-gray-200 max-w-2xl leading-relaxed",variants:P,initial:"hidden",animate:"visible",transition:{delay:.3},children:"We'd love to hear from you. Here's how you can reach our team of educational innovators."})]})})]}),e.jsx("section",{className:"container mx-auto px-4 sm:px-6 lg:px-8 py-12 md:py-20",children:e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-12 gap-6 md:gap-8",children:[e.jsx(a.div,{className:"lg:col-span-7 bg-white rounded-xl shadow-md overflow-hidden border border-gray-200 transition-shadow duration-300 hover:shadow-lg",variants:$,initial:"hidden",animate:"visible",whileHover:{y:-5},transition:{duration:.3},children:e.jsxs("div",{className:"p-6 md:p-8 lg:p-10",children:[e.jsxs(a.h2,{className:"text-2xl font-bold text-gray-800 mb-8 flex items-center",variants:P,initial:"hidden",animate:"visible",children:[e.jsx("span",{className:"w-1.5 h-6 bg-blue-600 mr-3 rounded-sm"}),"How to Reach Us"]}),e.jsxs(a.div,{className:"grid grid-cols-1 md:grid-cols-2 gap-y-8 gap-x-6 lg:gap-x-8",variants:H,initial:"hidden",animate:"visible",children:[e.jsx(Ie,{iconSrc:"assets/Icons/mail.svg",title:"By Mail",description:e.jsxs("address",{className:"mt-2 not-italic text-gray-600 leading-relaxed text-sm",children:["Sugar Labs",e.jsx("br",{}),"2028 E Ben White Blvd ",e.jsx("b",{children:"STE 240 PMB 1271"}),e.jsx("br",{}),"AUSTIN, TX 78741",e.jsx("br",{}),"USA"]})}),e.jsx(Ie,{iconSrc:"assets/Icons/phone.svg",title:"By Phone",description:e.jsx("a",{href:"tel:+16177024088",className:"mt-2 text-gray-600 hover:text-blue-600 transition duration-200 block text-sm",children:"+1 (617) 702-4088"})}),e.jsx(Ie,{iconSrc:"assets/Icons/email.svg",title:"By Email",description:e.jsx("a",{href:"mailto:info@sugarlabs.org",className:"mt-2 text-gray-600 hover:text-blue-600 transition duration-200 block text-sm",children:"info@sugarlabs.org"})}),e.jsx(Ie,{iconSrc:"assets/Icons/chat.svg",title:"Via Matrix Chat",description:e.jsx(F,{to:"matrix",className:"mt-2 text-gray-600 hover:text-blue-600 transition duration-200 block text-sm",children:"Go to Matrix Chat"})})]})]})}),e.jsxs(a.div,{className:"lg:col-span-5 rounded-xl overflow-hidden shadow-md",variants:K,initial:"hidden",animate:"visible",whileHover:{y:-5},transition:{duration:.3},children:[e.jsxs("div",{className:"bg-gradient-to-br from-gray-800 via-gray-850 to-gray-900 p-6 md:p-8 lg:p-10",children:[e.jsxs(a.h2,{className:"text-2xl font-bold text-white mb-6 flex items-center",variants:P,initial:"hidden",animate:"visible",children:[e.jsx("span",{className:"w-1.5 h-6 bg-blue-500 mr-3 rounded-sm"}),"Connect With The Community"]}),e.jsx(a.p,{className:"text-gray-300 text-sm leading-relaxed mb-8",variants:P,initial:"hidden",animate:"visible",transition:{delay:.2},children:"Join our global community of educators, developers, and learners who are passionate about bringing educational software to children around the world."}),e.jsx(a.div,{className:"grid grid-cols-2 sm:grid-cols-3 gap-4 mb-6",variants:H,initial:"hidden",animate:"visible",children:qt.map((s,i)=>e.jsxs(a.a,{href:s.href,target:"_blank",rel:"noopener noreferrer","aria-label":`Visit our ${s.name} page`,className:"group flex flex-col items-center",variants:ne,whileHover:"hover",whileTap:"tap",custom:i,children:[e.jsx("div",{className:"flex items-center justify-center w-12 h-12 bg-white/10 group-hover:bg-white/20 rounded-lg backdrop-blur-sm transition-all duration-300 ease-in-out mb-2 border border-gray-700/50 shadow-sm group-hover:shadow-blue-500/10 group-hover:shadow-md",children:e.jsx("img",{src:s.icon,alt:"",width:20,height:20,className:"filter brightness-0 invert opacity-90","aria-hidden":"true"})}),e.jsx("span",{className:"text-xs text-gray-300 group-hover:text-gray-200 transition-colors duration-200",children:s.name})]},s.href))})]}),e.jsxs(a.div,{className:"bg-gray-800 p-5 md:p-6 border-t border-gray-700/50",variants:P,initial:"hidden",animate:"visible",transition:{delay:.4},children:[e.jsx("h3",{className:"text-xs uppercase font-bold text-gray-300 tracking-wider mb-2",children:"Follow Our Progress"}),e.jsx("p",{className:"text-xs text-gray-400 leading-relaxed",children:"Stay updated with our latest developments and educational initiatives."})]})]})]})})]}),e.jsx(M,{})]}),Ie=({iconSrc:s,title:i,description:r})=>e.jsxs(a.div,{className:"flex items-start",variants:z,children:[e.jsx(a.div,{className:"flex-shrink-0 p-3 bg-blue-50 rounded-lg text-blue-600 border border-blue-100",whileHover:{scale:1.1},transition:{type:"spring",stiffness:400,damping:10},children:e.jsx("img",{src:s,alt:"",className:"h-5 w-5","aria-hidden":"true"})}),e.jsxs("div",{className:"ml-4",children:[e.jsx("h3",{className:"text-sm font-bold text-gray-800 uppercase tracking-wider",children:i}),r]})]}),lr=["all","general","development","activities","installation"],Qe=[{question:"What is Sugar Labs?",answer:"Sugar Labs, a 501(c)(3) non-profit foundation, serves as a support base and gathering place for the community of educators and software developers who want to extend the Sugar platform and who have been creating Sugar-compatible applications.",category:"general"},{question:"What is the mission of Sugar Labs?",answer:"The overarching mission of Sugar Labs is to support the Sugar platform through software development, and community outreach and support. The purpose of the Sugar platform is provide a software and content environment that enhances learning.",category:"general"},{question:"What are the principles that guide Sugar Labs?",answer:"Sugar Labs subscribes to principle that learning thrives within a culture of freedom of expression, hence it has a natural affinity with the free software movement.",category:"general"},{question:"What makes Sugar different from other educational software platforms?",answer:"The Sugar interface, in its departure from the desktop metaphor for computing, is the first serious attempt to create a user interface that is based on both cognitive and social constructivism.",category:"development"},{question:"Who can use Sugar and how do they benefit?",answer:"Sugar is a free software project, freely available to anyone who wants to use it or improve upon it. The Sugar platform was designed for young children (K–6), but it is finding applicability in a number of different venues.",category:"general"},{question:"Are there any platforms where Sugar runs on?",answer:"The Sugar Learning Platform is a leading learning platform that began in the famous One Laptop Per Child project. It is used every day by nearly 3 million children around the world.",category:"installation"},{question:"What are some popular Sugar Activities for beginners?",answer:"Some popular Sugar Activities for beginners include TurtleBlocks (for learning programming through graphics), Write (for writing and journaling), Calculate (for mathematics), Read (for e-books), and Speak (a text-to-speech activity). These activities are designed to be both engaging and educational, helping children learn through exploration and play.",category:"activities"},{question:"How does Sugar Labs sustain its operations?",answer:"Sugar Labs is supported by donations, community contributions, and mentorship programs like Google Summer of Code. It relies heavily on its global volunteer network.",category:"general"},{question:"What age group is Sugar Labs software primarily designed for?",answer:"Sugar Labs focuses primarily on children in the K–6 age range, aiming to provide them with interactive tools for experiential learning.",category:"general"},{question:"Can I contribute to Sugar Labs if I am not a programmer?",answer:"Absolutely! Non-programmers can contribute through translations, documentation, user testing, outreach, or by creating educational content.",category:"development"},{question:"How can I find beginner-friendly issues to contribute to?",answer:'Sugar Labs uses GitHub for tracking issues. You can filter for labels like "good first issue" or "beginner" to find suitable tasks.',category:"development"},{question:"How do Sugar Activities support different subjects?",answer:"Sugar Activities cover a wide range of subjects like math, science, reading, music, and programming—each encouraging learning through exploration and play.",category:"activities"},{question:"Can Sugar Activities be used without the full Sugar environment?",answer:"Many Sugar Activities can run independently on GNU/Linux or through web-based alternatives such as Sugarizer, which provides a full Sugar experience https://www.sugarlabs.org/sugarizer/",category:"activities"},{question:"What is Sugar on a Stick?",answer:"Sugar on a Stick (SoaS) is a version of Sugar that can run from a bootable USB drive. It allows users to try Sugar without installing anything on their computer. Learn more at https://www.sugarlabs.org/sugarizer/",category:"installation"},{question:"Can I run Sugar on Windows or macOS?",answer:"While the original Sugar is Linux-based and typically run via virtualization tools like VirtualBox, you can use Sugarizer, a web-based version of Sugar, on Windows, macOS, and other platforms. Learn more at https://www.sugarlabs.org/sugarizer/",category:"installation"},{question:"Where can I download the Sugar Learning Platform?",answer:"You can download Sugar preloaded on Fedora SoaS - https://fedoraproject.org/spins/soas/download or Trisquel - https://trisquel.info/en/download",category:"installation"}],cr=[{question:"Is Music Blocks free to use?",answer:"Yes, Music Blocks is a 100% free to use, open sourced software.",image:"assets/QuickAnswers/cards.svg"},{question:"What is Music Blocks?",answer:"A visual programming language for creating music and learning coding.",image:"assets/QuickAnswers/Headset.svg"},{question:"Can I use Sugar on any device?",answer:"Yes! It runs on Linux, Windows, macOS, and live USBs.",image:"assets/QuickAnswers/monitor-mobbile.svg"},{question:"Who develops Sugar and Music Blocks?",answer:"Sugar Labs and a global open-source community.",image:"assets/QuickAnswers/people.svg"},{question:"How can I contribute to Sugar Labs?",answer:"By coding, translating, designing, or writing docs!",image:"assets/QuickAnswers/task.svg"},{question:"Is Sugar Labs a nonprofit?",answer:"Yes! It creates free, open-source educational software.",image:"assets/QuickAnswers/card-slash.svg"}],dr={initial:{opacity:0,y:10},animate:{opacity:1,y:0,transition:{duration:.3}}},mr={hover:{scale:1.02}},ur=s=>({initial:{rotate:0},animate:{rotate:s?180:0,transition:{duration:.2}}}),hr=s=>({initial:{height:0,opacity:0},animate:{height:s?"auto":0,opacity:s?1:0,transition:{duration:.3}}}),gr=({index:s,question:i,answer:r})=>{const[o,t]=c.useState(!1),l=()=>t(d=>!d);return e.jsxs(a.div,{className:"border-b last:border-b-0",variants:dr,initial:"initial",animate:"animate",children:[e.jsxs(a.button,{className:"w-full text-left py-4 text-lg font-medium flex justify-between items-center hover:cursor-pointer",onClick:l,whileHover:"hover",variants:mr,children:[i,e.jsx(a.span,{variants:ur(o),initial:"initial",animate:"animate",children:o?"-":"+"})]}),e.jsx(a.div,{variants:hr(o),initial:"initial",animate:"animate",style:{overflow:"hidden"},children:e.jsx("p",{className:"p-4 text-gray-700",children:r})})]},s)},xr=()=>{const[s,i]=c.useState("all"),[r,o]=c.useState(Qe);return c.useEffect(()=>{const t=s==="all"?Qe:Qe.filter(l=>l.category===s);o(t)},[s]),e.jsxs("div",{className:"min-h-screen bg-white text-gray-900",children:[e.jsx(A,{}),e.jsxs("main",{className:"container mx-auto p-4",children:[e.jsx(a.section,{className:"my-8 flex justify-center",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.3},variants:Q.pageSection,children:e.jsxs("div",{className:"max-w-4xl w-4/5 flex flex-col md:flex-row justify-between items-center",children:[e.jsxs(a.div,{className:"md:w-1/2 text-left md:pr-8",variants:$,children:[e.jsx(a.h1,{className:"text-4xl font-bold",variants:Q.headingText,children:"FAQs"}),e.jsx(a.p,{className:"text-gray-600 mt-2 text-lg",variants:Q.paragraphText,children:"Have questions? Here you'll find the answers most valued by our partners, along with access to step-by-step instructions and support."})]}),e.jsx(a.div,{className:"md:w-1/2 flex justify-end",variants:K,children:e.jsx(a.img,{src:O.faq,alt:"FAQs Illustration",className:"w-80 md:w-[400px] lg:w-[500px]",variants:Q.heroImage,whileHover:"hover"})})]})}),e.jsxs("div",{className:"w-4/5 max-w-5xl mx-auto",children:[e.jsxs(a.section,{className:"my-10",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},variants:P,children:[e.jsx(a.h2,{className:"text-3xl font-bold mb-6",variants:G,children:"Quick Answers"}),e.jsx(a.div,{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mt-6",variants:Q.quickAnswersContainer,children:cr.map((t,l)=>e.jsxs(a.div,{className:"bg-white shadow-lg rounded-2xl p-6 flex flex-col items-center border border-gray-200",variants:Q.quickAnswerCard,whileHover:"hover",whileTap:"tap",children:[e.jsx(a.div,{className:"w-12 h-12 bg-white flex items-center justify-center rounded-lg mb-4",variants:Q.quickAnswerIcon,custom:l,children:e.jsx("img",{src:t.image,alt:t.question,className:"w-6 h-6"})}),e.jsx("h3",{className:"font-semibold text-center",children:t.question}),e.jsx("p",{className:"text-gray-600 text-sm text-center mt-2",children:t.answer})]},l))})]}),e.jsxs(a.section,{className:"my-8 max-w-5xl mx-auto",initial:"hidden",whileInView:"visible",viewport:{once:!0},variants:P,children:[e.jsx(a.h2,{className:"text-2xl font-bold mb-4",variants:G,children:"Filter by Category"}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx("button",{onClick:()=>i("all"),className:`px-4 py-2 rounded-full transition-all ${s==="all"?"bg-blue-600 text-white cursor-pointer":"bg-gray-200 hover:bg-gray-300 cursor-pointer"}`,children:"All"}),lr.filter(t=>t!=="all").map(t=>e.jsx("button",{onClick:()=>i(t),className:`px-4 py-2 rounded-full transition-all capitalize ${s===t?"bg-blue-600 text-white cursor-pointer":"bg-gray-200 hover:bg-gray-300 cursor-pointer"}`,children:t},t))]})]}),e.jsxs(a.section,{className:"my-10",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},variants:Q.faqContainer,children:[e.jsx(a.h2,{className:"text-3xl font-bold mb-6 capitalize",variants:G,children:s==="all"?"All FAQs":`${s} FAQs`}),e.jsx(a.div,{className:"bg-white shadow-lg rounded-lg p-6",variants:z,children:r.length>0?r.map((t,l)=>e.jsx(gr,{question:t.question,answer:t.answer,index:l},l)):e.jsx("p",{className:"text-center text-gray-600 py-4",children:"No FAQs found for this category."})})]})]})]}),e.jsx(M,{})]})},pr=()=>e.jsxs("div",{className:"min-h-screen flex flex-col",children:[e.jsx(A,{}),e.jsx("main",{className:"flex-grow bg-[#F6DEC9] p-4",children:e.jsx("div",{className:"max-w-6xl mx-auto space-y-8",children:e.jsx(Zt,{})})}),e.jsx(M,{})]}),br=[{name:"Sourabha G.",username:"Sourabha G. (GSoC 2021 contributor)",body:"This summer was super fun and filled with learning! I enjoyed testing over 60+ activities with kids to get first-hand feedback, which had a positive impact in the way they approach problems. The fact that these activities are used by kids as a tool of learning motivates me to contribute more and more. I'm going to continue to contribute and be a part of Sugar Labs.",img:"https://avatar.vercel.sh/jack"},{name:"Riya Lohia",username:"Riya Lohia (GSoC 2018 contributor)",body:"I would like to thank my mentors Walter Bender and Devin Ulibarri for their constant guidance and motivation. A big thanks to Sugar Labs community and Google Summer of Code (GSoC) for providing such a wonderful opportunity for learning and helping me to be an active member of Open Source Community.",img:"https://avatar.vercel.sh/jill"},{name:"Om Santosh Suneri",username:"Om Santosh Suneri",body:"My first open source contribution was challenging but incredibly rewarding. If you’re hesitant about contributing, just dive in. Find a project you love, pick an issue, and start exploring. Who knows? Your first PR might be just around the corner.",img:"https://media.licdn.com/dms/image/v2/D5603AQEWfqFxGN6Msg/profile-displayphoto-shrink_800_800/B56ZS5vxjvHQAc-/0/1738283097234?e=1749686400&v=beta&t=dT5SgsauobXe5gcQsiGMm91rfY_ILQvxkHT9Ukzck-s"},{name:"Karan Palan",username:"Karan Palan (GSoC 2024 contributor)",body:"Overall, my work on the Masonry project during GSoC 2024 has involved a mix of design, prototyping, and development activities… This experience has not only strengthened my technical skills but also provided valuable insights into the collaborative, iterative nature of open-source development. I look forward to continuing to contribute to the Music Blocks project and helping to create a more accessible and engaging visual programming environment for users around the world.",img:"https://media.licdn.com/dms/image/v2/D5603AQFd4DwGD9a1Ig/profile-displayphoto-shrink_800_800/profile-displayphoto-shrink_800_800/0/1719038630136?e=1749686400&v=beta&t=ZNXwm01ufeYSP0Q1SOuDGaXdMULxU2O_zEjkfni_ktM"},{name:"Diwangshu Kakoty",username:"Diwangshu Kakoty",body:"I wanted to try open-source contributions to learn more about real-world projects. How is software developed? How do developers work in a team? What are the coding practices that professionals use? I sought answers to these questions and found them when I joined Sugar Labs and its awesome community of developers.",img:"https://miro.medium.com/v2/resize:fill:96:96/0*3WyfLW5_tE0JqmZI"},{name:"Tayba Wasim",username:"Tayba Wasim (GSoC 2017 contributor)",body:"Once you successfully solve the bug, you need to create a pull request (PR)… Don’t get disappointed or feel dejected if your PR is not merged at once, it opens up the gate to learning when you work through the suggestions provided by the mentors as they know how the PR can be improved. Once your PR is updated and merged, the momentary sense of achievement you get is a bliss!",img:"https://secure.gravatar.com/blavatar/d51a3c490f489d67f2bf4972eb962731f4fe2da9f8371383ed08cce4efddf56f?s=114"},{name:"Anurag Singh",username:"Anurag Singh (GSoC 2024 contributor)",body:"This summer has been a great experience working with Sugar Labs. I learned and coded across various fields, from RPi to OS to content creation and hardware. It has been a very enriching experience, and I am truly grateful for this opportunity.",img:"https://avatars.githubusercontent.com/u/123321851?s=96&v=4"}],fr=({img:s,name:i,username:r,body:o,delay:t=0})=>e.jsxs(a.div,{className:"bg-white dark:bg-gray-900 rounded-xl p-6 flex flex-col items-center text-center min-h-[250px] h-auto w-[350px] shadow-lg border border-gray-200 dark:border-gray-700 mx-2 justify-between",variants:Kt,initial:"hidden",whileInView:"visible",whileHover:"hover",viewport:{once:!0,amount:.1},transition:{delay:t},children:[e.jsx(a.img,{src:O.apostrophie,alt:"double-quotes",className:"w-10 h-10 self-start opacity-70",variants:W}),e.jsx(a.p,{className:"text-gray-700 dark:text-gray-300 mt-2",variants:Me,children:o}),e.jsxs("div",{className:"flex items-center mt-4 space-x-3 text-left",children:[e.jsx(a.img,{src:s,alt:i,className:"w-12 h-12 rounded-full border border-gray-300",variants:Xt}),e.jsxs(a.div,{variants:Me,children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:i}),e.jsxs("p",{className:"text-sm text-gray-500 dark:text-gray-400",children:["@",r]})]})]})]});function wr(){return e.jsxs("div",{className:"w-full p-6",children:[e.jsxs(a.div,{className:"flex items-center justify-center gap-4 md:gap-6 mb-12",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.6},variants:Pe,children:[e.jsx(a.img,{src:O.leftHeart,alt:"Heart Left",className:"w-8 md:w-12 lg:w-16 fill-current text-red-500 border-none shadow-none",variants:W,animate:"float",custom:1}),e.jsxs("div",{className:"relative flex items-center justify-center gap-4 md:gap-6 lg:gap-8",children:[e.jsx(a.img,{src:O.apostrophie,alt:"Apostrophe Left",className:"w-8 md:w-12 lg:w-16 -translate-y-2 block max-[400px]:hidden",variants:W,custom:2}),e.jsx(a.h2,{className:"font-bold tracking-wider font-Caveat text-3xl md:text-5xl lg:text-6xl text-gray-800 text-center",variants:xt,children:e.jsxs("span",{className:"text-5xl font-bold font-[Caveat]",children:["What do developers say",e.jsx("br",{}),"about their journey?"]})}),e.jsx(a.img,{src:O.apostrophie,alt:"Apostrophe Right",className:"w-8 md:w-12 lg:w-16 -translate-y-2 scale-x-[-1] block max-[400px]:hidden",variants:W,custom:3})]}),e.jsx(a.img,{src:O.rightHeart,alt:"Heart Right",className:"w-8 md:w-12 lg:w-16 fill-current text-red-500 border-none shadow-none",variants:W,animate:"float",custom:4})]}),e.jsxs(a.div,{className:"relative flex flex-col items-center justify-center w-full overflow-hidden mt-6",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.1},variants:Pe,children:[e.jsx(oe,{pauseOnHover:!0,className:"w-full flex",children:br.map((s,i)=>e.jsx(fr,{...s,delay:i*.05},s.username))}),e.jsx("div",{className:"pointer-events-none absolute inset-y-0 left-0 w-1/4 bg-gradient-to-r from-background"}),e.jsx("div",{className:"pointer-events-none absolute inset-y-0 right-0 w-1/4 bg-gradient-to-l from-background"})]})]})}const lt=[{name:"Chat with us on Matrix",url:"https://matrix.to/#/#sugar:matrix.org",icon:"assets/LinksLogos/matrix.svg"},{name:"Developer Guide",url:"https://github.com/sugarlabs/sugar-docs/blob/master/README.md/",icon:"assets/LinksLogos/github.svg"},{name:"Mailing lists (old-school, but still active and useful)",url:"https://lists.sugarlabs.org/",icon:"assets/LinksLogos/mailingList.svg"},{name:"Contribute to Translations",url:"https://translate.sugarlabs.org/",icon:"assets/LinksLogos/translation.svg"},{name:"Related Projects",url:"https://github.com/sugarlabs/sugar-docs/blob/master/README.md",icon:"assets/LinksLogos/projects.svg"},{name:"Who are the developers of Sugar Labs?",url:"https://www.sugarlabs.org/profiles/",icon:"assets/LinksLogos/developer.svg"},{name:"Code of Conduct",url:"https://github.com/sugarlabs/sugar-docs/blob/master/src/CODE_OF_CONDUCT.md",icon:"assets/LinksLogos/conduct.svg"}],vr=()=>{const s={hidden:{opacity:0},visible:{opacity:1,transition:{staggerChildren:.15,delayChildren:.1}}},i={hidden:{y:20,opacity:0},visible:{y:0,opacity:1,transition:{type:"spring",stiffness:300,damping:24}}};return e.jsx("section",{className:"container mx-auto px-6 py-10",children:e.jsx(a.div,{className:"grid grid-cols-1 md:grid-cols-2 gap-5 w-full max-w-6xl mx-auto",variants:s,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},children:lt.map((r,o)=>e.jsxs(a.a,{href:r.url,target:"_blank",rel:"noopener noreferrer",className:`relative flex items-center justify-between px-6 py-5 rounded-xl + border-2 border-gray-200 bg-white shadow-sm hover:shadow-lg + overflow-hidden transition-all duration-300 group h-full`,variants:i,whileHover:{scale:1.02,borderColor:"#D32F2F",backgroundColor:"rgba(240, 249, 255, 0.7)"},whileTap:{scale:.98},children:[e.jsx("span",{className:"absolute inset-0 bg-gradient-to-r from-red-50 to-red-100 opacity-0 group-hover:opacity-100 transition-opacity duration-300"}),e.jsxs("div",{className:"relative flex items-center gap-4 z-10 flex-1",children:[e.jsx("div",{className:"flex-shrink-0 w-10 h-10 rounded-full bg-red-100 flex items-center justify-center group-hover:bg-red-200 transition-colors",children:e.jsx("img",{src:r.icon,alt:r.name,className:"w-5 h-5 group-hover:scale-110 transition-transform"})}),e.jsx("span",{className:"text-base md:text-lg font-medium text-gray-800 group-hover:text-red-700 transition-colors",children:r.name})]}),e.jsx("div",{className:"relative z-10 flex items-center justify-center w-8 h-8 rounded-full bg-red-100 group-hover:bg-red-200 transition-colors ml-4 flex-shrink-0",children:e.jsx("span",{className:"text-gray-600 group-hover:text-red-700 transform group-hover:translate-x-1 transition-all",children:"→"})})]},o))})})},es=()=>{const s=os(),i=ge(),r=s.pathname==="/volunteer",o=s.pathname==="/join-development";return e.jsx("div",{className:"pt-12 md:pt-20",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-center md:justify-between w-full max-w-6xl font-Oswald",children:[e.jsx("div",{className:"w-full md:w-1/2 flex justify-center md:justify-end pr-0 md:pr-12",children:e.jsx("h1",{className:"text-6xl md:text-[10rem] font-extralight tracking-tight text-center md:text-right",children:"JOIN"})}),e.jsxs("div",{className:"w-full md:w-1/2 flex flex-col justify-center items-center md:items-start",children:[e.jsx(a.h2,{className:"text-4xl md:text-[5rem] font-extralight pb-1 md:pb-2 cursor-pointer transition-colors",initial:{opacity:.6,scale:.95},animate:{color:r?"#EF4444":"#D1D5DB",opacity:r?1:.7,scale:r?1.1:1},transition:{duration:.4,ease:"easeInOut"},onClick:()=>!r&&i("/volunteer"),children:"Volunteer"}),e.jsx("div",{className:"border-t border-gray-300 w-3/4 md:w-4/5"}),e.jsx(a.h2,{className:"text-4xl md:text-[5rem] font-extralight pt-1 md:pt-2 cursor-pointer transition-colors",initial:{opacity:.6,scale:.95},animate:{color:o?"#EF4444":"#D1D5DB",opacity:o?1:.7,scale:o?1.1:1},transition:{duration:.4,ease:"easeInOut"},onClick:()=>!o&&i("/join-development"),children:"Development"})]})]})})},yr=()=>(c.useEffect(()=>{window.scrollTo(0,0)},[]),e.jsxs("div",{className:"bg-gradient-to-b to-red-50",children:[e.jsx(A,{}),e.jsxs("main",{className:"container mx-auto flex flex-col items-center justify-center min-h-screen p-6",children:[e.jsx(es,{}),e.jsxs(a.div,{className:"mt-20 max-w-4xl flex flex-col items-center text-center px-6",initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6,delay:.2},children:[e.jsx("h2",{className:"text-5xl font-bold font-[Caveat]",children:"Before Beginning to Contribute"}),e.jsx("hr",{className:"w-32 border-t-2 border-gray-400 mx-auto mt-2"}),e.jsx("p",{className:"text-lg text-gray-700 font-[Inter] mt-6 leading-relaxed",children:"As a developer, whether you are just starting out or you've participated in other development before, there are a few things you need to know about our community. This page has important information on not just where to find the code, documentation, and how to reach us, but it also has information on our philosophy and a link to our Code of Conduct."})]}),e.jsx("div",{className:"w-full mt-16",children:e.jsx(wr,{})}),e.jsx("section",{className:"py-16 w-full",id:"links",children:e.jsxs(a.div,{className:"max-w-5xl mx-auto",variants:V,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.1},children:[e.jsxs("div",{className:"text-center mb-8",children:[e.jsx("span",{className:"inline-block px-3 py-1 bg-red-100 text-red-700 rounded-full text-sm font-semibold mb-4",children:"Resources"}),e.jsx("h2",{className:"text-4xl md:text-5xl font-bold font-[Caveat] mb-4",children:"Important Links for Developers"}),e.jsx("div",{className:"w-24 h-1 bg-red-700 rounded mx-auto mb-6"}),e.jsx("p",{className:"text-lg text-gray-700 max-w-2xl mx-auto",children:"Essential resources for people interested in making development contributions to Sugar Labs"})]}),e.jsx(vr,{})]})})]}),e.jsx(M,{})]})),jr=[{title:"Educator",description:"Sugar Labs is focused on education, and we value the feedback of other educators. Here are ways that educators can participate in Sugar Labs as a volunteer:",points:["Use our software and lesson plans in your classroom, and try our Constructionism learning tools for yourself.","Test software and give your feedback based on your experience as an educator.","Create your own lesson plans for other teachers to use in the classroom."],extra:`Educators are encouraged to contact iaep@sugarlabs.org and ask education-specific questions. "IAEP" stands for "It's an education project". + You may also subscribe to our group mailing list at,`,link:"http://lists.sugarlabs.org/listinfo/iaep"},{title:"Communicator",description:"Help us document stakeholder experiences. Here are a few ways you can help:",points:["If you're a student or former student, you can share your story using Sugar, either in the form of a blog post or on a video.","If you speak multiple languages, we can use assistance creating and testing translations.","Give your feedback about Sugar as a third-party. While not necessarily a 'volunteer', we do appreciate when members of the broader education and/or tech community test our tools and give their feedback."]},{title:"Advocate",description:"Help us spread awareness about Sugar Labs and our unique mission in education. Here are a few ways you can help:",points:["If you're enthusiastic about what Sugar Labs stands for and what we do, you may help us by following us on social media and sharing our message.","Parents and teachers, you can speak to your child's school administrators and tell them about Sugar and its benefits."]}],Nr=""+new URL("Volunteer/volunteer-group.png",import.meta.url).href,kr=()=>{const s=lt.find(o=>o.name.includes("Matrix"))?.url||"https://matrix.to/#/#sugar:matrix.org",i=lt.find(o=>o.name.includes("Mailing"))?.url||"https://lists.sugarlabs.org/",r=()=>{const o=document.getElementById("volunteer-cards");o&&o.scrollIntoView({behavior:"smooth"})};return e.jsxs("div",{children:[e.jsx(A,{}),e.jsxs("main",{className:"container mx-auto flex flex-col items-center justify-center min-h-screen p-6",children:[e.jsx(es,{}),e.jsxs("div",{className:"mt-12 flex flex-col md:flex-row items-center gap-8 max-w-5xl",children:[e.jsxs(a.div,{className:"max-w-lg text-center md:text-left",variants:$,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:[e.jsxs("h2",{className:"text-4xl font-bold",children:["Become a ",e.jsx("span",{className:"text-red-500",children:"Volunteer"})]}),e.jsx("p",{className:"text-lg text-gray-700 mt-4",children:"By bringing together people with diverse skills from around the globe to work toward our mission in education, volunteers in the Sugar Labs community have ample opportunities to grow their skills and learn from one another."}),e.jsx("button",{className:"mt-6 bg-red-500 text-white text-lg font-semibold px-6 py-3 rounded-full hover:cursor-pointer",onClick:r,children:"Get Involved"})]}),e.jsx(a.div,{className:"w-full md:w-1/2 flex justify-center",variants:K,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:e.jsx("img",{src:Nr,alt:"Volunteers working together",className:"w-full max-w-md rounded-lg shadow-lg"})})]}),e.jsxs(a.div,{className:"mt-20 max-w-4xl text-center px-4",variants:V,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:[e.jsx("h2",{className:"text-5xl font-bold font-[Caveat]",children:"Getting Involved as a Volunteer"}),e.jsx("hr",{className:"w-32 border-t-2 border-gray-400 mx-auto mt-2"}),e.jsx("p",{className:"text-lg text-gray-700 font-[Inter] mt-6 leading-relaxed",children:"Sugar Labs is seeking volunteer assistance in the roles of education, communication, advocacy, research, and technical. Sustained, committed help in any of these areas will help us grow as an organization. If you are passionate or curious to learn more about any of these roles, and are able to commit the time necessary, then we encourage you to apply."}),e.jsxs("p",{className:"text-lg text-gray-700 font-[Inter] mt-4 leading-relaxed",children:["Send a notification of your interest to",e.jsxs("a",{href:"mailto:info@sugarlabs.org",className:"text-blue-500 underline",children:[" ","info@sugarlabs.org"]}),", including some information about yourself, what interests you about the volunteer role, and what experience/qualities make you a good candidate."]})]}),e.jsxs("div",{className:"mt-16 max-w-6xl px-4",id:"volunteer-cards",children:[e.jsx(a.h2,{className:"text-5xl font-[Caveat] font-bold text-center",variants:V,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:"Volunteer Roles"}),e.jsx("hr",{className:"w-32 border-t-2 border-gray-400 mx-auto mt-2"}),e.jsx("div",{className:"mt-10 grid grid-cols-1 md:grid-cols-3 gap-6",children:jr.map((o,t)=>e.jsxs(a.div,{className:"border p-6 rounded-lg shadow-lg bg-white text-center",variants:Qt,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},children:[e.jsx("h3",{className:"text-2xl font-bold",children:o.title}),e.jsx("hr",{className:"w-16 border-t-2 border-gray-400 mx-auto mt-2"}),e.jsx("p",{className:"text-gray-700 mt-4",children:o.description}),e.jsx("ul",{className:"text-gray-600 text-left mt-3 space-y-2",children:o.points?.map((l,d)=>e.jsxs("li",{className:"flex items-start",children:[e.jsx("span",{className:"text-red-500 font-bold mr-2",children:"•"}),l]},d))}),o.extra&&e.jsxs("p",{className:"text-gray-700 text-sm mt-3",children:[o.extra," ",o.link&&e.jsx("a",{href:o.link,className:"text-blue-500 underline",children:o.link})]})]},t))})]}),e.jsxs(a.div,{className:"mt-20 max-w-4xl text-center px-4",variants:V,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:[e.jsxs("h2",{className:"text-5xl font-bold font-[Caveat]",children:["Ways to Get ",e.jsx("span",{className:"text-red-500",children:"Involved"})]}),e.jsx("hr",{className:"w-32 border-t-2 border-gray-400 mx-auto mt-2"}),e.jsx("p",{className:"text-lg text-gray-700 font-[Inter] mt-6 leading-relaxed",children:"There are multiple ways to get involved, whether as a developer, educator, advocate, or communicator. Each role plays a vital part in helping us achieve our mission."}),e.jsx("div",{className:"mt-8 w-full flex justify-center",children:e.jsx("div",{className:"w-full max-w-3xl aspect-video",children:e.jsx("iframe",{className:"w-full h-full rounded-lg",src:"https://www.youtube.com/embed/W5ZLFBZkE34",title:"YouTube Video",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})})})]}),e.jsxs(a.div,{className:"mt-20 max-w-4xl text-center px-4",variants:V,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:[e.jsx("h2",{className:"text-5xl font-bold font-[Caveat]",children:"Interested in Helping Out?"}),e.jsx("hr",{className:"w-32 border-t-2 border-gray-400 mx-auto mt-2"}),e.jsxs("p",{className:"text-lg text-gray-700 font-[Inter] mt-6 leading-relaxed",children:["Feel free to reach out to express your interest in volunteering via"," ",e.jsx("a",{href:i,className:"text-blue-500 hover:underline",target:"_blank",rel:"noopener noreferrer",children:"email"})," ","or"," ",e.jsx("a",{href:s,className:"text-blue-500 hover:underline",target:"_blank",rel:"noopener noreferrer",children:"Matrix"}),". Alternatively, you may send"," ",e.jsx(F,{to:"/contact-us",className:"text-blue-600 hover:underline",children:"direct message"})," ","to one of our social media channels."]})]})]}),e.jsx(M,{})]})},_r=()=>{const[s,i]=c.useState(!1),r=5,o=qe.length>r,t=s?qe:qe.slice(0,r);return e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsxs("div",{className:"max-w-6xl mx-auto px-4 sm:px-6 font-sans mt-10 sm:mt-10 mb-10 sm:mb-16",children:[e.jsxs("div",{className:"flex flex-col md:flex-row gap-6 md:gap-10 mt-10",children:[e.jsxs(a.div,{className:"flex-1 order-2 md:order-1",variants:$,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:[e.jsxs("h1",{className:"text-3xl sm:text-4xl font-bold mb-4 sm:mb-6",children:["Make a Lasting ",e.jsx("span",{className:"text-red-500",children:"Impact"})," in Education"]}),e.jsx("p",{className:"text-gray-700 mb-6 sm:mb-8 text-base sm:text-lg",children:"A financial contribution to Sugar Labs is an investment in education. Your tax-deductible donation helps us create innovative tools for teaching and learning while mentoring budding developers from around the world."}),e.jsx(a.div,{className:"flex flex-wrap gap-4 mb-6 sm:mb-8",variants:we,whileHover:"hover",whileTap:"tap",children:e.jsx("a",{href:fe.url,target:"_blank",rel:"noreferrer",children:e.jsx("button",{className:"bg-green-600 hover:bg-green-700 cursor-pointer transition-colors text-white px-6 sm:px-8 py-2 sm:py-3 rounded-full font-medium shadow-md",children:"Donate Now"})})}),e.jsx("div",{className:"bg-gray-100 p-4 rounded-lg border-l-4 border-blue-500 shadow-sm text-xs sm:text-sm",children:e.jsx("p",{className:"text-gray-600",children:"Your donation is tax-deductible in the United States as Sugar Labs is a registered 501(c)(3) nonprofit organization."})})]}),e.jsx(a.div,{className:"flex-1 order-1 md:order-2 mb-6 md:mb-0",variants:K,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:e.jsx("img",{src:$e[0],alt:"Children asking for donations",className:"w-full rounded-lg shadow-lg object-cover h-64 sm:h-full"})})]}),e.jsxs(a.div,{className:"my-10 sm:my-16 bg-gradient-to-r from-blue-50 to-green-50 p-5 sm:p-8 rounded-xl shadow-sm",variants:V,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:[e.jsx("h2",{className:"text-2xl sm:text-3xl font-bold mb-4 sm:mb-6 text-center",children:"Your Donation Directly Assists Our Mission"}),e.jsxs("div",{className:"prose prose-base sm:prose-lg max-w-none",children:[e.jsx("p",{className:"mb-4",children:'Despite the fact that computers, and the software on those computers, run the way much of the world works, there still remains very little support in education, especially at the levels of primary and secondary schooling, to cultivate a computationally literate society. Despite initiatives, a mere "day of code," sometimes as little as "an hour of code," is woefully insufficient to instill computational literacy in a generation of young learners.'}),e.jsx("p",{className:"mb-4",children:"Sugar Labs, as an organization, and the suite of apps, curriculum, rubrics, and mentoring, is well poised to bridge the gap for many learners in the US and around the world - the gap between educational services provided and what youth need developmentally to succeed."})]})]}),e.jsxs(a.div,{className:"my-10 sm:my-16",variants:V,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:[e.jsx("h2",{className:"text-2xl sm:text-3xl font-bold mb-6 sm:mb-8 text-center",children:"How Your Donation Makes a Difference"}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 sm:gap-8",children:Ma.map(l=>e.jsxs("div",{className:"bg-white p-5 sm:p-6 rounded-lg shadow-md border border-gray-100",children:[e.jsx("div",{className:"text-green-500 text-3xl sm:text-4xl font-bold mb-2 sm:mb-3",children:l.value}),e.jsx("h3",{className:"text-lg sm:text-xl font-semibold mb-2",children:l.title}),e.jsx("p",{className:"text-gray-700 text-sm sm:text-base",children:l.description})]},l.title))})]}),e.jsx(a.div,{className:"my-10 sm:my-16",variants:V,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:e.jsxs("div",{className:"bg-gray-50 p-5 sm:p-6 rounded-lg shadow-sm border border-gray-100",children:[e.jsx("h2",{className:"text-xl sm:text-2xl font-semibold mb-3 sm:mb-4 text-gray-800",children:"Our Mission"}),e.jsx("p",{className:"text-gray-800 text-xs sm:text-sm leading-relaxed mb-5 sm:mb-6",children:"Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology to youth around the world. Volunteer mentors and contributors work together to develop activity- focused software for children. All software is developed with learning as the primary goal, necessitating the need for source code to be published publicly for study — worked upon openly within a community where students are invited to make contributions under guidance of experienced mentors."}),e.jsx("div",{className:"mt-4 sm:mt-6",children:e.jsxs("a",{href:fe.url,target:"_blank",rel:"noreferrer",className:"text-green-600 hover:text-green-700 font-medium flex items-center text-sm sm:text-base",children:["Help support our mission",e.jsx("img",{src:$e[1],alt:"Right Arrow",className:"h-4 w-4 ml-1"})]})})]})}),e.jsxs(a.div,{className:"my-10 sm:my-16",id:"financial-transparency",variants:V,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:[e.jsx("h2",{className:"text-2xl sm:text-3xl font-bold mb-6 sm:mb-8 text-center",children:"Financial Transparency"}),e.jsxs("div",{className:"bg-white p-5 sm:p-8 rounded-xl shadow-md",children:[e.jsx("p",{className:"mb-5 sm:mb-6 text-sm sm:text-base",children:"Sugar Labs is committed to full financial transparency. As a 501(c)(3) nonprofit organization, we make our tax filings available for public review."}),e.jsx("h3",{className:"text-lg sm:text-xl font-semibold mb-3 sm:mb-4",children:"Our 990 Tax Filings"}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3 sm:gap-4",children:t.map(l=>e.jsxs("a",{href:l.link,className:"bg-gray-50 hover:bg-gray-100 transition-colors p-3 sm:p-4 rounded-lg flex flex-col items-center text-center",target:"_blank",rel:"noreferrer",children:[e.jsx("img",{src:$e[2],alt:"PDF Icon",className:"h-8 w-8 mb-2"}),e.jsxs("span",{className:"font-medium text-xs sm:text-sm",children:[l.year," Filings"]})]},l.year))}),o&&!s&&e.jsx("div",{className:"mt-6 flex justify-center",children:e.jsx("button",{onClick:()=>i(!0),className:"bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-md text-sm font-medium flex items-center",children:"Show More"})}),e.jsxs("div",{className:"mt-6 sm:mt-8 p-3 sm:p-4 bg-gray-50 rounded-lg border border-gray-200",children:[e.jsx("h4",{className:"font-medium mb-2 text-sm sm:text-base",children:"Note about 2018 and earlier"}),e.jsxs("p",{className:"text-xs sm:text-sm text-gray-700",children:["Sugar Labs Inc. received its 501(c)(3) nonprofit status in 2020. Before 2019, Sugar Labs was a member organization under Software Freedom Conservancy. To view our archived financial data from before 2019, please visit:"," ",e.jsx("a",{href:"https://wiki.sugarlabs.org/go/Finance",className:"text-blue-600 hover:underline",children:"https://wiki.sugarlabs.org/go/Finance"})]})]})]})]}),e.jsxs(a.div,{className:"my-10 sm:my-16 bg-green-50 p-5 sm:p-8 rounded-xl shadow-sm",id:"donate-section",variants:V,initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.5},children:[e.jsx("h2",{className:"text-2xl sm:text-3xl font-bold mb-4 sm:mb-6 text-center",children:"Support Our Mission Today"}),e.jsx("p",{className:"text-center max-w-3xl mx-auto mb-6 sm:mb-8 text-sm sm:text-base",children:"Financial contributions to Sugar Labs helps us continue to create and maintain innovative tools for learning, as well as mentor youth at a critical point in their development. Your support makes a meaningful difference in the lives of children around the world."}),e.jsxs("div",{className:"flex justify-center gap-3 sm:gap-4 flex-wrap",children:[e.jsx("a",{href:fe.url,target:"_blank",rel:"noreferrer",children:e.jsx("button",{className:"bg-green-600 hover:bg-green-700 cursor-pointer transition-colors text-white px-5 sm:px-8 py-2 sm:py-3 rounded-full font-medium shadow-md text-sm sm:text-base",children:"Make a One-Time Donation"})}),e.jsx("a",{href:fe.urlMonth,target:"_blank",rel:"noreferrer",children:e.jsx("button",{className:"bg-blue-600 hover:bg-blue-700 cursor-pointer transition-colors text-white px-5 sm:px-8 py-2 sm:py-3 rounded-full font-medium shadow-md text-sm sm:text-base",children:"Become a Monthly Supporter"})})]})]})]}),e.jsx(M,{})]})},Sr=[{name:"Classic Cotton T-Shirt",description:"Support Sugar Labs®—a US-based 501(c)(3) nonprofit empowering youth through technology education—with this premium cotton t-shirt, designed for comfort and durability.",colors:{blue:"assets/Products/sugarTshirtBlue.jpeg",white:"assets/Products/sugarTshirtWhite.jpeg",green:"assets/Products/sugarTshirtGreen.jpeg",purple:"assets/Products/sugarTshirtPurple.jpeg"},link:"https://www.bonfire.com/store/sugar-labs-merch/"},{name:"SugarLabs USB",description:"Easily install Fedora Sugar On A Stick (SOAS) to your device directly from this USB flash drive. The Fedora SOAS on this USB drive is for Intel and AMD x86_64 systems.",colors:{white:"assets/Products/sugarlabsUsb.jpeg"},link:"https://www.usbmemorydirect.com/store/novelty/sugarlabs/"}],Lr=()=>e.jsx("section",{className:"py-12 px-4",children:e.jsx("div",{className:"max-w-5xl mx-auto grid grid-cols-1 gap-12",children:Sr.map((s,i)=>e.jsx(Cr,{product:s},i))})}),Cr=({product:s})=>{const i=Object.values(s.colors),r=i.length>1,[o,t]=c.useState(0);return e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8 border-b pb-10",children:[e.jsxs("div",{className:"relative group w-full",children:[e.jsx(De.Carousel,{selectedItem:o,onChange:l=>t(l),showArrows:!1,showThumbs:!1,showStatus:!1,showIndicators:!0,infiniteLoop:!0,useKeyboardArrows:!0,swipeable:!0,children:i.map((l,d)=>e.jsx("div",{children:e.jsx("img",{src:l,alt:`${s.name} image ${d+1}`,className:"w-full rounded-lg shadow-md"})},d))}),r&&o>0&&e.jsx("div",{className:"absolute left-0 top-0 h-full w-1/4 bg-gradient-to-r from-black/30 to-transparent opacity-0 group-hover:opacity-100 transition-all duration-300 cursor-pointer z-10",onClick:()=>t(l=>l-1),children:e.jsx("div",{className:"absolute left-4 top-1/2 transform -translate-y-1/2 w-0 h-0 border-t-8 border-b-8 border-r-8 border-transparent border-r-white"})}),r&&o<i.length-1&&e.jsx("div",{className:"absolute right-0 top-0 h-full w-1/4 bg-gradient-to-l from-black/30 to-transparent opacity-0 group-hover:opacity-100 transition-all duration-300 cursor-pointer z-10",onClick:()=>t(l=>l+1),children:e.jsx("div",{className:"absolute right-4 top-1/2 transform -translate-y-1/2 w-0 h-0 border-t-8 border-b-8 border-l-8 border-transparent border-l-white"})})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-3xl font-semibold",children:s.name}),e.jsx("p",{className:"text-gray-600 mt-2",children:s.description}),e.jsx("div",{className:"mt-6",children:e.jsx("a",{href:s.link,target:"_blank",rel:"noopener noreferrer",className:"bg-blue-600 text-white px-6 py-3 rounded-lg text-lg shadow-md hover:bg-blue-700 transition",children:"Buy Now"})})]})]})},Tr=()=>e.jsxs("div",{children:[e.jsx(A,{}),e.jsx("main",{className:"container mx-auto px-4 sm:px-6 md:px-8 py-6",children:e.jsxs(a.div,{variants:H,initial:"initial",animate:"animate",children:[e.jsxs(a.h2,{className:"text-6xl sm:text-7xl md:text-8xl lg:text-9xl font-extralight text-center mb-6 font-[Oswald] tracking-wide py-8",variants:J,children:[e.jsx("span",{className:"text-black",children:"OUR"})," ",e.jsx("span",{className:"text-red-500",children:"MERCHANDISE"})]}),e.jsx(a.div,{variants:Xs,children:e.jsx(Lr,{})})]})}),e.jsx(M,{})]}),Ir=[{name:"Copy Link",action:async s=>{await navigator.clipboard.writeText(s),alert("Link copied to clipboard!")},icon:e.jsxs("svg",{width:"20",height:"20",fill:"none",stroke:"currentColor",strokeWidth:"2",viewBox:"0 0 24 24",children:[e.jsx("path",{d:"M10 14L21 3m0 0v7m0-7h-7"}),e.jsx("path",{d:"M21 14v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h7"})]})},{name:"Twitter",action:(s,i)=>{window.open(`https://twitter.com/intent/tweet?url=${encodeURIComponent(s)}&text=${encodeURIComponent(i)}`,"_blank")},icon:e.jsx("img",{src:"/assets/social/x.svg",alt:"Twitter",width:20,height:20})},{name:"Facebook",action:s=>{window.open(`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(s)}`,"_blank")},icon:e.jsx("img",{src:"/assets/social/facebook.svg",alt:"Facebook",width:20,height:20})},{name:"WhatsApp",action:(s,i)=>{window.open(`https://api.whatsapp.com/send?text=${encodeURIComponent(i+" "+s)}`,"_blank")},icon:e.jsx("img",{src:"/assets/social/whatsapp.svg",alt:"WhatsApp",width:20,height:20})},{name:"LinkedIn",action:(s,i)=>{window.open(`https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(s)}&title=${encodeURIComponent(i)}`,"_blank")},icon:e.jsx("img",{src:"/assets/social/linkedin.svg",alt:"LinkedIn",width:20,height:20})},{name:"Mastodon",action:(s,i)=>{window.open(`https://mastodon.social/share?text=${encodeURIComponent(i+" "+s)}`,"_blank")},icon:e.jsx("img",{src:"/assets/social/mastodon.svg",alt:"Mastodon",width:20,height:20})}],ts=({open:s,onClose:i,url:r,title:o,excerpt:t})=>{if(!s)return null;const l=()=>{navigator.share&&(navigator.share({title:o,text:t,url:r}),i())};return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-transparent transition-all backdrop-blur-sm",children:e.jsxs("div",{className:"relative w-full max-w-sm mx-auto bg-gradient-to-br from-blue-50 via-white to-green-50 rounded-2xl shadow-2xl p-7 animate-fadeIn border border-blue-100",children:[e.jsx("button",{className:"absolute top-4 right-4 text-gray-500 hover:text-blue-600 bg-white rounded-full shadow p-1 cursor-pointer transition-colors duration-200 border border-gray-200",onClick:i,"aria-label":"Close",style:{fontSize:20,lineHeight:1},children:e.jsxs("svg",{width:"20",height:"20",fill:"none",stroke:"currentColor",strokeWidth:"2",viewBox:"0 0 24 24",children:[e.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),e.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})}),e.jsx("h3",{className:"text-xl font-bold mb-4 text-blue-700 text-center",children:"Share this post"}),e.jsx("div",{className:"mb-5 text-xs text-gray-700 bg-white border border-gray-100 rounded px-3 py-2 break-all text-center select-all",children:r}),e.jsxs("div",{className:"flex flex-col gap-3",children:[typeof navigator.share=="function"&&e.jsx("button",{onClick:l,className:"w-full py-2 px-4 rounded-xl bg-gradient-to-r from-blue-600 to-green-600 text-white font-semibold hover:from-blue-700 hover:to-green-700 shadow transition cursor-pointer",style:{fontSize:"1rem"},children:"Share via Device..."}),Ir.map(d=>e.jsxs("button",{onClick:()=>d.action(r,o),className:"w-full flex items-center gap-3 py-2 px-4 rounded-xl border border-gray-200 bg-white hover:bg-gradient-to-r hover:from-blue-100 hover:to-green-100 hover:shadow-lg transition-all duration-200 cursor-pointer text-gray-700 font-medium",style:{fontSize:"1rem"},children:[e.jsx("span",{className:"flex-shrink-0",children:d.icon}),e.jsx("span",{className:"flex-1 text-left",children:d.name})]},d.name))]})]})})},Er="modulepreload",Ar=function(s,i){return new URL(s,i).href},Rt={},n=function(i,r,o){let t=Promise.resolve();if(r&&r.length>0){let k=function(m){return Promise.all(m.map(u=>Promise.resolve(u).then(x=>({status:"fulfilled",value:x}),x=>({status:"rejected",reason:x}))))};const d=document.getElementsByTagName("link"),h=document.querySelector("meta[property=csp-nonce]"),w=h?.nonce||h?.getAttribute("nonce");t=k(r.map(m=>{if(m=Ar(m,o),m in Rt)return;Rt[m]=!0;const u=m.endsWith(".css"),x=u?'[rel="stylesheet"]':"";if(!!o)for(let L=d.length-1;L>=0;L--){const g=d[L];if(g.href===m&&(!u||g.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${m}"]${x}`))return;const v=document.createElement("link");if(v.rel=u?"stylesheet":Er,u||(v.as="script"),v.crossOrigin="",v.href=m,w&&v.setAttribute("nonce",w),document.head.appendChild(v),u)return new Promise((L,g)=>{v.addEventListener("load",L),v.addEventListener("error",()=>g(new Error(`Unable to preload CSS for ${m}`)))})}))}function l(d){const h=new Event("vite:preloadError",{cancelable:!0});if(h.payload=d,window.dispatchEvent(h),!h.defaultPrevented)throw d}return t.then(d=>{for(const h of d||[])h.status==="rejected"&&l(h.reason);return i().catch(l)})},ue=(s,i="")=>Array.isArray(s)?s.join(" ").trim():s?.trim()||i,Mr=async()=>{try{const s=Object.assign({"/src/constants/MarkdownFiles/authors/aditya-singh.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.a),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/aman-chadha.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.b),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/amannaik247.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.c),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/anvita-prasad.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.d),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/bishoy-wadea.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.e),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/diwangshu-kakoty.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.f),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/elwin-li.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.g),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/harshit-verma.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.h),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/justin-charles.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.j),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/krish-pandya.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.k),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/mebin-thattil.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.m),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/muhammad-haroon.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.i),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/nikhil-bhatt.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.n),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/om-santosh-suneri.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.o),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/safwan-sayeed.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.s),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/saumya-shahi.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.l),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/authors/shubham-singh.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.p),[],import.meta.url).then(r=>r.default)}),i=[];for(const[r,o]of Object.entries(s))try{const t=await o(),{frontmatter:l,content:d}=pt(t),h={slug:ue(l.slug),name:ue(l.name),title:ue(l.title),organization:ue(l.organization),description:ue(l.description),avatar:ue(l.avatar),content:d};i.push(h)}catch(t){console.error(`Error processing author file ${r}:`,t)}return i.sort((r,o)=>r.name.localeCompare(o.name))}catch(s){return console.error("Error fetching authors:",s),[]}},ss=async s=>(await Mr()).find(r=>r.slug===s)||null,Pr=async(s,i)=>{if(!s)return null;if(s.includes(".md"))try{const r=s.split("/").pop()?.replace(".md","")||"",o=await ss(r);if(o)return{name:o.name,description:o.description,slug:o.slug,avatar:o.avatar}}catch(r){console.error("Error loading author from file:",r)}return{name:s,description:i||"Author at SugarLabs",slug:s.toLowerCase().replace(/\s+/g,"-")}},pt=s=>{const r=/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/.exec(s);if(!r)return{frontmatter:{},content:s};const[,o,t]=r,l={};return o.split(` +`).forEach(d=>{const h=d.indexOf(":");if(h===-1)return;const w=d.slice(0,h).trim();let k=d.slice(h+1).trim();(k.startsWith('"')&&k.endsWith('"')||k.startsWith("'")&&k.endsWith("'"))&&(k=k.slice(1,-1)),l[w]=w==="tags"&&k?k.split(",").map(m=>m.trim()):k}),{frontmatter:l,content:t}},ee=(s,i="")=>Array.isArray(s)?s.join(" ").trim():s?.trim()||i,Rr=s=>{let i=ee(s,"/assets/Images/SugarNewsLogo.png");return i!=="/assets/Images/SugarNewsLogo.png"&&!/^https?:\/\//.test(i)&&(i="/"+i.replace(/^\/+/,"")),i},je=async s=>{try{const i=Object.assign({"/src/constants/MarkdownFiles/posts/2008-05-15-New-foundation-focused-on-taking-the-Sugar-user-interface-to-the-next-level-of-usability-and-utility.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t._),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2008-12-09-Sugar-Labs-joins-the-Software-Freedom-Conservancy.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.q),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-03-16-La-Asociación-sin-fines-de-lucro-Sugar-Labs-Anuncia-su-Nueva-Versión-de-la-Plataforma-de-Aprendizaje-Sugar-para-Niños-que-Funciona-en-Notebooks-y-PCs.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.r),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs,-organisation-à-but-non-lucratif,-annonce-la-sortie-de-la-nouvelle-version-de-la-plateforme-d’apprentissage-pour-enfants-Sugar-pour-PC-et-netbooks.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.t),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs-Nonprofit-Announces-New-Version-of-Sugar-Learning-Platform-for-Children,-Runs-on-Netbooks-and-PCs.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.u),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs-kündigt-neue-Version-von-Sugar-an—die-Lernplattform-für-Kinder-läuft-auf-Netbooks-und-PCs.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.v),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-04-22-Sugar-Labs-Announces-Beta‑1-of-Sugar-on-a-Stick,-LiveUSB-Version-of-Sugar-Learning-Platform-for-Children.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.w),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-04-22-Sugar-Labs-annonce-la-bêta-1-de-Sugar-on-a-Stick,-version-LiveUSB-de-Sugar,-la-plate-forme-d’apprentissage-pour-enfants.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.x),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-Announces-Immediate-Availability-of-Sugar-on-a-Stick;-Learning-Platform-Runs-on-Any-PC-or-Netbook-In-The-Classroom.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.y),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-annonce-la-disponibilité-immédiate-de-«-Sugar-on-a-Stick-»,-une-plate-forme-d’apprentissage-qui-fonctionne-sur-n’importe-quel-PC-ou-netbook-dans-la-salle-de-classe.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.z),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-annuncia-l’immediata-disponibilità-di-Sugar-on-a-Stick;-La-Piattaforma-di-Apprendimento-in-grado-di-funzionare-su-qualsiasi-PC-o-Netbook-disponibile-in-classe.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.A),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-anuncia-la-disponibilidad-inmediata-de-Sugar-On-A-Stick-(Sugar-en-un-pendrive).-El-plataforma-de-aprendizaje-funciona-en-casi-cualquier-PC-o-portátil.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.B),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-gibt-die-Veröffentlichung-von-Sugar-on-a-Stick-bekannt;-die-Lernplattform-läuft-auf-jedem-PC-oder-Netbook-im-Klassenzimmer..md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.C),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-kondigt-aan-dat-Sugar-on-a-Stick-nu-beschikbaar-is;-dit-leerplatform-draait-op-elke-pc-of-netbook..md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.D),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-11-18-Sugar-Labs-and-Free-Software-Foundation-Celebrate-Software-Freedom-Day,-Announce-Joint-Efforts-to-Promote-the-Sugar-Learning-Platform-for-Children-Worldwide.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.E),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-12-08-L’association-à-but-non-lucratif-Sugar-Labs-annonce-la-version-2-de-“Sugar-on-a-Stick”.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.F),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2009-12-08-Sugar-Labs-Nonprofit-Announces-v2-of-Sugar-on-a-Stick-with-Improved-E-Book-Readers,-Recycles-Any-USB-Stick-Into-Learning-Environment-for-Children;-Partners-with-Nexcopy,-Inc..md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.G),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2010-04-29-L'Office-de-secours-et-de-travaux-des-Nations-unies-choisi-les-ordinateurs-du-projet-One-Laptop-per-Child-et-la-plate-forme-Sugar-pour.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.H),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2010-04-29-United-Nations-Relief-and-Works-Agency-Sceglie-i-Laptop-di-One-Laptop-per-Child-con--Sugar-per-un-Importante-Progetto-Educativo-in-Medio-Oriente.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.I),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2010-04-29-United-Nations-Relief-and-Works-Agency-chooses-One-Laptop-per-Child-Laptops-with-Sugar-for-Major-Education-Project-in-Mideast.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.J),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2010-06-04-La-Plataforma-de-Aprendizaje-Sugar-y-el-Escritorio-GNOME-se-distribuirán-hoy-en-la-One-Laptop-per-Child-modelo-XO-1.5;-también-se-ejecutará-en-el-nuevo-XO-HS-High-School-Edition.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.K),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-Announces-New-Version-of-Sugar-on-a-Stick,-Educational-Software-for-Children.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.L),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-Annuncia-una-Nuova-Versione-di-Sugar-on-a-Stick,-piattaforma-software-educativa-per-bambini.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.M),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-annonce-la-nouvelle-version-de-«Sugar-On-A-Stick»,-son-système-éducatif-à-destination-des-enfants.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.N),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2010-06-14-La-plateforme-éducative-Sugar-et-l'interface-bureautique-GNOME-désormais-présents-sur-le-nouvel-XO-1.5-de-la-fondation-OLPC,-ainsi-que-le-nouveau-modèle-XO-HS-High-School-Edition.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.O),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2010-06-14-Sugar-Learning-Platform-and-GNOME-Desktop-Now-Shipping-on-the-One-Laptop-per-Child-XO-1.5;-Will-Run-On-New-XO-HS.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.P),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2010-06-14-Sugar-Learning-Platform-e-GNOME-Desktop-sono-disponibili-per-gli-XO-1.5-di-One-Laptop-per-Child;-Compatibili-anche-per-i-nuovi-XO-HS-High-School-Edition.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.Q),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2011-04-15-La-organización-sin-fines-de-lucro-Sugar-Labs-patrocina-el-equipo-de-ciclistas-Team-Chipotle-para-dar-a-conocer-su-misión-educativa..md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.R),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2011-04-15-Sugar-Labs-Nonprofit-Sponsoring-Team-Chipotle-to-Raise-Awareness-of-Educational-Mission.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.S),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2013-02-05-La-organización-educacional-sin-fines-de-lucro-Sugar-Labs(R)-celebra-el-Día-del-Aprendizaje-Digital-con-dos-ganadores-del-premio-Google-Code-In.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.T),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2013-02-05-Le-Sugar-Labs(R),-organisme-non-lucratif-à-but-éducatif.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.U),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2013-02-05-Sugar-Labs(R)-Educational-Nonprofit-Celebrates-Digital-Learning-Day-With-Two-Google-Code-In-Grand-Prize-Winners.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.V),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2013-10-12-Children-Programmers-Abound-at-First-International-TurtleArt-Day.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.W),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2013-10-12-Programadores-niños-abundan-en-el-primer-Día-Internacional-de-TurtleArt.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.X),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2013-10-12-Une-foule-d'enfants-programmeurs-participe-à-la-1ère-Journée-Internationale-TurtleArt.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.Y),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2014-01-22-Sugar-Labs(R),-organización-sin-fines-de-lucro-para-la-Educación-celebra-dos-Ganadores-del-Gran-Premio-de-Google-Code-In.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.Z),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2014-01-22-Sugar-Labs(R)-Educational-Nonprofit-Celebrates-Two-Google-Code-In-Grand-Prize-Winners.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.$),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2016-05-15-The-connection-between-Sugar---Students---Teachers.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a0),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-05-01-Sugar-Labs-receives-eleven-contributor-projects-for-GSoC-2024.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a1),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-05-03-Sugar-Labs-Past-Present-Future.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a2),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-05-08-Sugar-Labs-announces-nonprofit-status-new-executive-director.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a3),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-05-10-Musical-Squares-From-Turtle-Blocks-to-Music-Blocks-and-beyond.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a4),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-05-17-Learn-to-make-games-with-Gameeky.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a5),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-05-24-An-OLPC-update-with-Lylian-Peraza.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a6),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-05-31-Learn-How-to-git-involved-with-Sugar-Labs-this-summer.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a7),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-06-07-GSoC+DMP-contributors-initial-check-in-1-of-2-Music-Blocks-projects.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a8),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-09-13-Writing-new-Activities-and-sharing-sugar-with-youth.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a9),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-09-20-sweet-spot.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aa),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-11-08-fall-board-elections-how-to-participate.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ab),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-11-22-elections-extension.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ac),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-12-03-help-SL-continue-to-transform-education.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ad),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-12-19-election-results.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ae),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-12-25-Reflections-as-Parents-and-Teachers-Sugar-at-home-and-in-their-classroom.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.af),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2024-12-29-sweet-spot-002.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ag),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-01-21-SoaS-USB-announcement.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ah),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-03-24-annual-report-2024.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ai),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-03-31-sweet-spot-003.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aj),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-05-12-Role-of-generative-AI-in-education.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ak),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-05-20-JSeditor-updates.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.al),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-05-25-gsoc-25-AdityaKrSingh26-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.am),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-01-gsoc-25-AdityaKrSingh26-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.an),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-07-gsoc-25-Elwin-Li-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ao),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-AmanNaik-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ap),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-AnvitaPrasad-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aq),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-justin212407-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ar),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-therealharshit-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.as),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-AdityaKrSingh26-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.at),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-BishoyWadea-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.au),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-FirePheonix-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.av),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-MebinThattil-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aw),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-Nikhil-Bhatt-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ax),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-SafwanSayeed-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ay),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-SaumyaShahi-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.az),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-diwangshu-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aA),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-mostlyk-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aB),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-omsuneri-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aC),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-08-ssoc-2025-MuhammadHaroon-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aD),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-09-KaranPalan-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aE),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-10-gsoc-25-AdityaKrSingh26-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aF),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-Elwin-Li-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aG),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-MebinThattil-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aH),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-firepheonix-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aI),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-mostlyk-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aJ),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-saumya-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aK),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-AmanNaik-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aL),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-justin212407-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aM),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-therealharshit-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aN),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-BishoyWadea-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aO),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-Nikhil-Bhatt-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aP),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-SafwanSayeed-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aQ),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-diwangshu-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aR),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-omsuneri-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aS),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-15-ssoc-2025-MuhammadHaroon-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aT),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-17-gsoc-25-AdityaKrSingh26-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aU),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-20-gsoc-25-AdityaKrSingh26-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aV),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-21-dmp-25-AmanNaik-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aW),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-Elwin-Li-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aX),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-MebinThattil-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aY),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-mostlyk-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.aZ),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-22-DMP-25-justin212407-week3.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a_),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-22-dmp-25-AnvitaPrasad-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.a$),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-BishoyWadea-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b0),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-Nikhil-Bhatt-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b1),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-SafwanSayeed-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b2),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-diwangshu-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b3),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-omsuneri-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b4),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-saumya-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b5),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-22-ssoc-2025-MuhammadHaroon-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b6),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-23-dmp-25-therealharshit-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b7),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-25-gsoc25-firepheonix-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b8),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-28-dmp-25-AmanNaik-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b9),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-BishoyWadea-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.ba),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-Elwin-Li-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bb),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-mostlyk-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bc),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-29-dmp-24-justin212407-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bd),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-29-dmp-25-AnvitaPrasad-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.be),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-29-dmp-25-therealharshit-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bf),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-MebinThattil-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bg),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-Nikhil-Bhatt-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bh),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-SafwanSayeed-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bi),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-diwangshu-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bj),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-omsuneri-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bk),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-saumya-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bl),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-30-gsoc-25-AdityaKrSingh26-week07.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bm),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-06-30-ssoc-2025-MuhammadHaroon-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bn),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-01-gsoc-25-firepheonix-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bo),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-05-dmp-25-AmanNaik-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bp),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-2025-mostlyk-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bq),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-BishoyWadea-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.br),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-Elwin-Li-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bs),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-MebinThattil-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bt),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-firepheonix-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bu),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-Nikhil-Bhatt-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bv),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-SafwanSayeed-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bw),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-diwangshu-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bx),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-omsuneri-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.by),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-06-ssoc-2025-MuhammadHaroon-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bz),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-07-dmp-25-justin212407-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bA),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-07-dmp-25-therealharshit-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bB),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-08-gsoc-25-AdityaKrSingh26-week08.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bC),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-12-dmp-25-AmanNaik-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bD),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-12-gsoc-25-Elwin-Li-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bE),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-12-gsoc-25-saumya-week05-06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bF),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-12-mostlyk-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bG),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-MebinThattil-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bH),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-Nikhil-Bhatt-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bI),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-SafwanSayeed-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bJ),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-diwangshu-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bK),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-firepheonix-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bL),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-omsuneri-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bM),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-14-dmp-25-therealharshit-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bN),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-14-gsoc-25-BishoyWadea-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bO),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-15-gsoc-25-AdityaKrSingh26-week09.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bP),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-19-gsoc-25-Elwin-Li-week07.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bQ),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-20-gsoc-25-AdityaKrSingh26-week10.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bR),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-20-gsoc-25-diwangshu-week07.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bS),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/2025-07-21-dmp-25-therealharshit-week07.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bT),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/TESTMarkdownFormat.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bU),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/YYYY-MM-DD-GSoC_DMP_SSoC_Template.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bV),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bW),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bX),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week03.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bY),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week04.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.bZ),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week01.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b_),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week02.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.b$),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week05.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.c0),[],import.meta.url).then(t=>t.default),"/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week06.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(t=>t.c1),[],import.meta.url).then(t=>t.default)}),r=[];for(const[t,l]of Object.entries(i))try{const d=await l(),{frontmatter:h,content:w}=pt(d),k=t.split("/").pop()?.replace(".md","")||"",m=await Pr(ee(h.author),ee(h.description)),u={id:k,title:ee(h.title,"Untitled"),excerpt:ee(h.excerpt),content:w,category:ee(h.category,"UNCATEGORIZED"),date:ee(h.date,"No date"),slug:ee(h.slug,k),author:m,tags:Array.isArray(h.tags)?h.tags:h.tags?[h.tags]:[],image:Rr(h.image)};r.push(u)}catch(d){console.error(`Error processing ${t}:`,d)}const o=r.sort((t,l)=>{const d=new Date(t.date).getTime()||0;return(new Date(l.date).getTime()||0)-d});return s?o.filter(t=>t.category===s):o}catch(i){return console.error("Error fetching markdown posts:",i),[]}},Dr=async s=>(await je()).filter(r=>r.author?.slug===s),Fr=async s=>(await je()).filter(r=>r.tags.some(o=>o.toLowerCase()===s.toLowerCase())),Br=async()=>{const s=await je(),i=new Set;return s.forEach(r=>{r.tags.forEach(o=>i.add(o))}),Array.from(i).sort()},Or=async s=>(await je()).find(r=>r.slug===s)||null,Vr=async()=>je(),zr=s=>{const i={All:s};return s.forEach(r=>{const o=r.category||"UNCATEGORIZED";i[o]||(i[o]=[]),i[o].push(r)}),i},Dt=()=>{const[s,i]=c.useState(!1),[r,o]=c.useState(null),t=ge(),{category:l}=ye(),[d,h]=c.useState({}),[w,k]=c.useState([]),[m,u]=c.useState("All"),[x,f]=c.useState(6),[v,L]=c.useState(!0),[g,j]=c.useState(null),[I,S]=c.useState("grid"),[N,C]=c.useState("");c.useEffect(()=>{async function b(){L(!0);try{const T=await Vr(),U=zr(T);h(U),k(Object.keys(U))}catch(T){console.error(T),j("Failed to load news")}finally{L(!1)}}b()},[]),c.useEffect(()=>{if(l){const b=l.toLowerCase().replace(/-/g," ").trim(),T=w.find(U=>U.toLowerCase()===b);if(T){u(T);return}}u("All")},[l,w]),c.useEffect(()=>{const b=m==="All"?"all":m.toLowerCase().replace(/\s+/g,"-");t(`/news/${b}`,{replace:!0}),f(6)},[m,t]);const y=c.useMemo(()=>["All",...w.filter(T=>T!=="All").sort((T,U)=>T.localeCompare(U))],[w]),D=c.useMemo(()=>{let b=d[m]||[];return N&&(b=b.filter(T=>T.title.toLowerCase().includes(N.toLowerCase())||T.excerpt?.toLowerCase().includes(N.toLowerCase())||T.category?.toLowerCase().includes(N.toLowerCase()))),b},[d,m,N]),B=c.useMemo(()=>D.slice(0,x),[D,x]),q=D.length>x,X=b=>u(b),_=()=>{const b=D.length;f(T=>Math.min(T+6,b))},R=b=>{const T=m==="All"?"all":m.toLowerCase().replace(/\s+/g,"-");t(`/news/${T}/${b}`)},p=(b,T)=>{T.stopPropagation(),o(b),i(!0)};return v?e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsx("div",{className:"min-h-screen bg-gradient-to-br from-blue-50 via-white to-green-50",children:e.jsx("div",{className:"container mx-auto px-4 py-20",children:e.jsxs(a.div,{className:"text-center max-w-2xl mx-auto",variants:Ct,initial:"hidden",animate:"visible",children:[e.jsxs("div",{className:"relative mb-9",children:[e.jsx("h1",{className:"text-8xl font-bold font-Caveat text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-green-600",children:"NEWS"}),e.jsx("div",{className:"absolute -top-4 -right-5",children:e.jsx(wt,{className:"text-yellow-400 animate-pulse",size:30})})]}),e.jsxs("div",{className:"bg-white rounded-2xl p-8 shadow-xl",children:[e.jsx("div",{className:"animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-600 mx-auto mb-6"}),e.jsx("h2",{className:"text-xl font-semibold text-gray-800 mb-2",children:"Loading Latest News"}),e.jsx("p",{className:"text-gray-600",children:"Fetching the most recent stories from Sugar Labs community..."})]})]})})}),e.jsx(M,{})]}):g?e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsx("div",{className:"min-h-screen bg-gradient-to-br from-blue-50 via-white to-green-50",children:e.jsxs("div",{className:"container mx-auto px-4 py-20 text-center",children:[e.jsx(a.h1,{className:"text-8xl font-bold font-Caveat text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-green-600 mb-8",variants:Ct,initial:"hidden",animate:"visible",children:"NEWS"}),e.jsxs("div",{className:"bg-white rounded-2xl p-8 shadow-xl max-w-md mx-auto",children:[e.jsx("div",{className:"text-red-500 mb-4",children:e.jsx("svg",{className:"w-16 h-16 mx-auto",fill:"currentColor",viewBox:"0 0 20 20",children:e.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})})}),e.jsx("h2",{className:"text-xl font-semibold text-gray-800 mb-2",children:"Oops! Something went wrong"}),e.jsx("p",{className:"text-red-600 mb-6",children:g}),e.jsx("button",{onClick:()=>window.location.reload(),className:"px-6 py-3 bg-blue-600 text-white rounded-xl hover:bg-blue-700 transition-all duration-300 font-medium shadow-lg hover:shadow-xl transform hover:-translate-y-1",children:"Try Again"})]})]})}),e.jsx(M,{})]}):e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsxs("div",{className:"min-h-screen bg-gradient-to-br from-blue-50 via-white to-green-50",children:[e.jsxs("div",{className:"relative overflow-hidden",children:[e.jsxs("div",{className:"absolute inset-0",children:[e.jsx("div",{className:"absolute top-10 left-10 w-32 h-32 bg-blue-200 opacity-20 rounded-full"}),e.jsx("div",{className:"absolute bottom-10 right-10 w-48 h-48 bg-green-200 opacity-15 rounded-full"}),e.jsx("div",{className:"absolute top-1/2 left-1/3 w-24 h-24 bg-blue-300 opacity-10 rounded-full"})]}),e.jsx("div",{className:"relative container mx-auto px-4 py-20",children:e.jsxs(a.div,{className:"text-center max-w-4xl mx-auto",variants:P,initial:"hidden",animate:"visible",children:[e.jsxs("div",{className:"flex items-center justify-center mb-6",children:[e.jsx(wt,{className:"text-blue-500 mr-4 animate-pulse",size:32}),e.jsx("h1",{className:"text-8xl font-bold font-Caveat text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-green-600",children:"NEWS"}),e.jsx(Ht,{className:"text-green-500 ml-4 animate-bounce",size:32})]}),e.jsx("p",{className:"text-xl mb-8 text-gray-700 leading-relaxed",children:"Discover the latest innovations, community updates, and educational insights from the Sugar Labs ecosystem"}),e.jsx("div",{className:"flex flex-wrap justify-center gap-4 text-sm"})]})})]}),e.jsxs("div",{className:"container mx-auto px-4 py-8",children:[e.jsxs("div",{className:"bg-white rounded-2xl shadow-xl p-6 mb-8 border border-gray-100",children:[e.jsxs("div",{className:"flex flex-col lg:flex-row gap-6",children:[e.jsx("div",{className:"flex-1",children:e.jsxs("div",{className:"relative",children:[e.jsx(Fe,{className:"absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400",size:20}),e.jsx("input",{type:"text",placeholder:"Search articles, topics, or categories...",value:N,onChange:b=>C(b.target.value),className:"w-full pl-10 pr-4 py-3 border border-gray-200 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-300"})]})}),e.jsx("div",{className:"flex items-center gap-4",children:e.jsxs("div",{className:"flex bg-gray-100 rounded-xl p-1",children:[e.jsx("button",{onClick:()=>S("grid"),className:`p-3 rounded-lg transition-all duration-300 ${I==="grid"?"bg-white text-blue-600 shadow-md":"text-gray-600 hover:text-blue-600"}`,title:"Grid View",children:e.jsx(dt,{size:18})}),e.jsx("button",{onClick:()=>S("list"),className:`p-3 rounded-lg transition-all duration-300 ${I==="list"?"bg-white text-blue-600 shadow-md":"text-gray-600 hover:text-blue-600"}`,title:"List View",children:e.jsx(mt,{size:18})})]})})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-gray-200",children:[e.jsxs("div",{className:"flex items-center mb-4",children:[e.jsx(st,{className:"text-gray-600 mr-2",size:20}),e.jsx("h3",{className:"text-lg font-semibold text-gray-800",children:"Categories"})]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:y.map(b=>e.jsxs(a.button,{onClick:()=>X(b),className:`px-4 py-2 rounded-full text-sm font-medium transition-all duration-300 ${m===b?"bg-[#144EEC] text-white shadow-lg":"bg-gray-100 text-gray-700 hover:bg-gray-200 hover:shadow-md"}`,whileHover:{scale:1.05,cursor:"pointer"},whileTap:{scale:.95},children:[b,m===b&&e.jsx("span",{className:"ml-2 text-xs bg-white text-black bg-opacity-30 rounded-full px-2 py-1",children:(d[b]||[]).length})]},b))})]})]}),m.toLowerCase()==="template"&&e.jsx(a.div,{className:"bg-amber-50 border border-amber-200 rounded-2xl p-6 mb-8 shadow-sm",initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.3},children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(ns,{className:"text-amber-600 mt-1 flex-shrink-0",size:20}),e.jsx("div",{children:e.jsxs("p",{className:"text-amber-800 font-medium",children:[e.jsx("strong",{children:"Note:"})," These are developer templates for post formatting."]})})]})}),e.jsxs(a.div,{className:"text-center mb-8",variants:V,initial:"hidden",animate:"visible",children:[e.jsxs("h2",{className:"text-5xl font-Caveat text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-green-600 mb-2",children:[m," ",N&&`· "${N}"`]}),e.jsxs("p",{className:"text-gray-600 flex items-center justify-center gap-2",children:[e.jsxs("span",{children:[D.length," articles found"]}),N&&e.jsx("button",{onClick:()=>C(""),className:"text-blue-600 hover:text-blue-700 underline text-sm",children:"Clear search"})]})]}),e.jsx(Y,{mode:"wait",children:B.length===0?e.jsx(a.div,{className:"text-center py-20",initial:{opacity:0},animate:{opacity:1},children:e.jsxs("div",{className:"bg-white rounded-2xl p-12 shadow-xl max-w-md mx-auto",children:[e.jsx("div",{className:"text-6xl mb-6",children:"🔍"}),e.jsx("h3",{className:"text-2xl font-bold text-gray-800 mb-4",children:"No articles found"}),e.jsx("p",{className:"text-gray-600 mb-6",children:N?`No articles match "${N}" in this category.`:"There are no articles in this category yet."}),N&&e.jsx("button",{onClick:()=>C(""),className:"px-6 py-3 bg-blue-600 text-white rounded-xl hover:bg-blue-700 transition-colors",children:"Clear Search"})]})}):e.jsx(a.div,{className:`mb-12 ${I==="grid"?"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8":I==="list"?"space-y-8":"grid grid-cols-1 lg:grid-cols-2 gap-8"}`,initial:"hidden",animate:"visible",children:B.map((b,T)=>e.jsxs(a.article,{className:`bg-white rounded-2xl shadow-lg hover:shadow-2xl transition-all duration-500 cursor-pointer overflow-hidden group ${I==="list"?"flex":""}`,onClick:()=>R(b.slug),variants:ve,custom:T,layout:!0,whileHover:{y:-5},children:[e.jsxs("div",{className:`${I==="list"?"w-1/3":""} relative`,children:[e.jsx("div",{className:`${I==="list"?"h-full":"h-56"} overflow-hidden`,children:b.image?e.jsx("img",{src:b.image,alt:b.title,className:"w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"}):e.jsx("div",{className:"w-full h-full bg-gradient-to-br from-blue-100 via-purple-50 to-green-100 flex items-center justify-center",children:e.jsx("div",{className:"text-6xl opacity-50",children:"📰"})})}),b.category&&e.jsx("span",{className:"absolute top-4 left-4 px-3 py-1 text-xs font-bold bg-green-500 text-white rounded-full shadow-lg",children:b.category}),e.jsx("div",{className:"absolute top-4 right-4 flex gap-2",children:e.jsx("button",{onClick:U=>p(b,U),className:"p-2 rounded-full bg-gradient-to-r from-blue-600 to-blue-700 text-white shadow hover:from-blue-700 hover:to-green-600 focus:outline-none focus:ring-2 focus:ring-blue-400 transition-all duration-300 cursor-pointer",title:"Share",type:"button",children:e.jsx(Ut,{size:16,className:"text-white"})})})]}),e.jsxs("div",{className:`${I==="list"?"w-2/3":""} p-6 flex flex-col justify-between`,children:[e.jsxs("div",{children:[e.jsx("h3",{className:`font-bold text-gray-800 mb-3 line-clamp-2 group-hover:text-blue-600 transition-colors ${I==="list"?"text-xl":"text-lg"}`,children:b.title}),e.jsx("p",{className:"text-gray-600 text-sm line-clamp-3 mb-4 leading-relaxed",children:b.excerpt})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[b.date&&e.jsxs("div",{className:"flex items-center text-sm text-gray-500",children:[e.jsx(ls,{size:14,className:"mr-2"}),b.date]}),e.jsxs("div",{className:"flex items-center text-blue-600 text-sm font-medium group-hover:text-blue-700",children:["Read more",e.jsx(vt,{size:14,className:"ml-1 group-hover:translate-x-1 transition-transform duration-300"})]})]})]})]},b.slug))})}),q&&e.jsx("div",{className:"flex justify-center",children:e.jsxs(a.button,{onClick:_,className:"relative px-8 py-4 bg-gradient-to-r from-blue-600 to-green-600 text-white hover:from-blue-700 hover:to-green-700 cursor-pointer transition-all duration-300 rounded-2xl shadow-lg hover:shadow-2xl font-medium flex items-center gap-3 group overflow-hidden",variants:ne,initial:"hidden",animate:"visible",whileHover:"hover",whileTap:"tap",children:[e.jsx("div",{className:"absolute inset-0 bg-white opacity-0 group-hover:opacity-10 transition-opacity duration-300"}),e.jsx("span",{className:"relative z-10",children:"Load More Articles"}),e.jsx(vt,{size:18,className:"relative z-10 group-hover:translate-x-1 transition-transform duration-300"}),e.jsx("div",{className:"absolute -top-1 -right-1 w-6 h-6 bg-yellow-400 rounded-full flex items-center justify-center",children:e.jsx("span",{className:"text-xs font-bold text-gray-800",children:Math.min(6,D.length-x)})})]})})]})]}),e.jsx(ts,{open:s,onClose:()=>i(!1),url:r?`${window.location.origin}/news/${m==="All"?"all":m.toLowerCase().replace(/\s+/g,"-")}/${r.slug}`:"",title:r?.title||"",excerpt:r?.excerpt||""}),e.jsx(M,{})]})},Hr={":smile:":"😊",":heart:":"❤️",":thumbsup:":"👍",":thumbsdown:":"👎",":rocket:":"🚀",":star:":"⭐",":fire:":"🔥",":warning:":"⚠️",":info:":"ℹ️",":check:":"✅",":x:":"❌",":eyes:":"👀",":tada:":"🎉",":bug:":"🐛",":sparkles:":"✨",":wrench:":"🔧",":gear:":"⚙️",":bulb:":"💡",":package:":"📦",":memo:":"📝",":link:":"🔗",":lock:":"🔒",":unlock:":"🔓",":zap:":"⚡",":boom:":"💥",":computer:":"💻",":phone:":"📱",":email:":"📧",":calendar:":"📅",":clock:":"🕐",":house:":"🏠",":car:":"🚗",":plane:":"✈️",":coffee:":"☕",":pizza:":"🍕"},Ft={note:{icon:"ℹ️",bg:"bg-blue-50",border:"border-blue-200",text:"text-blue-800"},tip:{icon:"💡",bg:"bg-green-50",border:"border-green-200",text:"text-green-800"},important:{icon:"❗",bg:"bg-purple-50",border:"border-purple-200",text:"text-purple-800"},warning:{icon:"⚠️",bg:"bg-yellow-50",border:"border-yellow-200",text:"text-yellow-800"},caution:{icon:"🚨",bg:"bg-red-50",border:"border-red-200",text:"text-red-800"}},Ur={...xe,tagNames:[...xe.tagNames||[],"mark","iframe","details","summary","kbd","del","ins","figure","figcaption"],attributes:{...xe.attributes,mark:["class","data-*"],iframe:["src","allow","allowfullscreen","frameborder","title","style","width","height","loading","class"],details:["open","class"],summary:["class"],kbd:["class"],figure:["class"],figcaption:["class"],div:["class","style"],"*":[...xe.attributes?.["*"]||[],"className","data-*","aria-*"]},protocols:{...xe.protocols,src:["http","https","data"]}},Gr=s=>{let i=s;return Object.entries(Hr).forEach(([r,o])=>{i=i.replace(new RegExp(r.replace(/[-\\/\\^$*+?.()|[\]{}]/g,"\\$&"),"g"),o)}),i=i.replace(/==([\s\S]*?)==/g,'<mark class="bg-yellow-200 px-1 rounded">$1</mark>'),i=i.replace(/\[\[([^\]]+)\]\]/g,'<kbd class="px-2 py-1 text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-300 rounded-lg shadow-sm">$1</kbd>'),i=i.replace(/~~([\s\S]*?)~~/g,'<del class="line-through text-gray-500">$1</del>'),i=i.replace(/:::details\s+(.*?)\n([\s\S]*?):::/gim,'<details class="my-4 border border-gray-200 rounded-lg overflow-hidden bg-white"><summary class="bg-gray-50 px-4 py-3 cursor-pointer font-medium text-gray-800 hover:bg-gray-100 transition-colors border-b border-gray-200">$1</summary><div class="px-4 py-3 text-gray-700">$2</div></details>'),i=i.replace(/:::(\w+)\s*(.*?)\n([\s\S]*?):::/gim,(r,o,t,l)=>{const d=Ft[o]||Ft.note;return`<div class="my-4 p-4 border-l-4 ${d.border} ${d.bg} rounded-r-lg"> + <div class="flex items-center mb-2"> + <span class="mr-2 text-lg">${d.icon}</span> + <strong class="${d.text} font-semibold uppercase text-sm tracking-wide">${o}${t?`: ${t}`:""}</strong> + </div> + <div class="${d.text}">${l}</div> + </div>`}),i=i.replace(/\[youtube:\s*([\w-]+)\]/gim,(r,o)=>`<div class="my-8 mx-auto max-w-4xl"><div class="relative rounded-xl shadow-lg overflow-hidden bg-black" style="aspect-ratio: 16/9;"> + <iframe src="https://www.youtube.com/embed/${o}?autoplay=0&rel=0&modestbranding=1" class="absolute inset-0 w-full h-full border-0" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen loading="lazy" title="YouTube video player"></iframe></div></div>`),i},bt=({content:s,setZoomableImages:i,frontmatter:r})=>{const o=c.useMemo(()=>Gr(s),[s]),t=c.useCallback(()=>{const m=window.location.hash;if(m&&m.length>1){const u=m.substring(1);setTimeout(()=>{const x=document.getElementById(u);x&&x.scrollIntoView({behavior:"smooth",block:"start"})},100)}},[]),l=c.useCallback(async m=>{const u=m.target.closest(".copy-code-btn");if(!u)return;const x=u.getAttribute("data-code")||"";try{await navigator.clipboard.writeText(x);const f=u.nextElementSibling;f&&(f.classList.remove("hidden"),f.classList.add("flex"),setTimeout(()=>{f.classList.add("hidden"),f.classList.remove("flex")},2e3))}catch{const f=document.createElement("textarea");f.value=x,f.style.cssText="position:fixed;opacity:0;",document.body.appendChild(f),f.select(),document.execCommand("copy"),document.body.removeChild(f)}},[]),d=c.useCallback(m=>{const u=m.target;if(u.closest(".copy-code-btn"))return;const x=u.closest('a[href^="#"]');if(x){m.preventDefault();const f=x.getAttribute("href");if(f&&f.startsWith("#")){const v=f.substring(1),L=document.getElementById(v);if(L){const g=window.location.pathname+window.location.search;window.history.pushState(null,"",`${g}${f}`),L.scrollIntoView({behavior:"smooth"})}}}},[]);c.useEffect(()=>(document.addEventListener("click",l),document.addEventListener("click",d),()=>{document.removeEventListener("click",l),document.removeEventListener("click",d)}),[l,d]),c.useEffect(()=>{if(i){const m=document.querySelectorAll('img[data-zoomable="true"]');i(Array.from(m))}},[o,i]),c.useEffect(()=>{t();const m=()=>{t()};return window.addEventListener("popstate",m),()=>{window.removeEventListener("popstate",m)}},[o,t]);const h={h1:"text-3xl font-bold my-6 text-gray-900 group flex items-center border-b border-gray-200 pb-2",h2:"text-2xl font-semibold my-5 text-gray-900 group flex items-center border-b border-gray-200 pb-1",h3:"text-xl font-semibold my-4 text-gray-900 group flex items-center",h4:"text-lg font-semibold my-3 text-gray-900",h5:"text-base font-semibold my-3 text-gray-900",h6:"text-sm font-semibold my-3 text-gray-600 uppercase tracking-wide"},w=m=>({children:u,...x})=>{const f=m;return e.jsx(f,{...x,className:h[m],children:u})},k={h1:w("h1"),h2:w("h2"),h3:w("h3"),h4:w("h4"),h5:w("h5"),h6:w("h6"),p:({children:m,...u})=>e.jsx("p",{...u,className:"my-4 text-gray-700 leading-relaxed",children:m}),blockquote:({children:m,...u})=>e.jsx("blockquote",{...u,className:"border-l-3 border-blue-500 bg-blue-50 pl-5 pr-5 py-2 my-4 italic text-blue-800 rounded-r-2xl shadow-sm hover:shadow-md transition-shadow duration-200 ",children:e.jsx("div",{className:"relative z-10",children:m})}),code:({inline:m,className:u,children:x,...f})=>{if(m===!0||!u&&typeof x=="string")return e.jsx("code",{...f,className:"bg-gray-100 text-pink-600 px-2 py-1 rounded-md text-sm font-mono border border-gray-200 shadow-sm",children:x});const L=c.Children.toArray(x).reduce((j,I)=>typeof I=="string"?j+I:j,""),g=u?.replace("language-","")||"text";return e.jsxs("div",{className:"relative rounded-xl overflow-hidden shadow-lg border border-gray-800 bg-gray-900 my-6 group",children:[e.jsxs("div",{className:"flex items-center justify-between px-6 py-3 bg-gray-200 border-b border-gray-200",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx("div",{className:"w-3 h-3 rounded-full bg-red-500"}),e.jsx("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),e.jsx("div",{className:"w-3 h-3 rounded-full bg-green-500"}),e.jsx("span",{className:"text-xs font-semibold text-gray-600 uppercase",children:g})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsxs("button",{className:"copy-code-btn bg-gray-200 hover:bg-gray-300 text-gray-700 text-xs px-4 py-2 rounded-lg transition-all duration-200 flex items-center space-x-2 hover:scale-105 shadow-sm hover:shadow-md","data-code":L,"aria-label":"Copy code to clipboard",children:[e.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"})}),e.jsx("span",{className:"font-medium",children:"Copy"})]}),e.jsx("div",{className:"copy-success-message hidden items-center space-x-2 bg-green-100 text-green-800 text-xs px-4 py-2 rounded-lg border border-green-200",children:e.jsx("span",{className:"font-medium",children:"Copied!"})})]})]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsx("pre",{className:"p-6 bg-gray-50 text-sm leading-relaxed",children:e.jsx("code",{className:`${u||""} text-gray-800 font-mono block whitespace-pre`,children:x})})})]})},img:({src:m="",alt:u="",title:x,...f})=>{const v=m===""&&r?.image?String(r.image):m;return e.jsxs("figure",{className:"flex flex-col items-center my-6",children:[e.jsx("div",{className:"overflow-hidden rounded-lg shadow-md hover:shadow-lg transition-all duration-300 border border-gray-200",children:e.jsx("img",{...f,src:v,alt:u,title:x||u||"",className:"max-w-full h-auto rounded-lg object-contain hover:scale-105 transition-transform duration-300","data-zoomable":"true",loading:"lazy",onError:L=>{L.target.src="/assets/Images/SugarNewsLogo.png"}})}),(x||u)&&e.jsx("figcaption",{className:"text-center text-sm text-gray-600 mt-3 italic",children:x||u})]})},table:({children:m,...u})=>e.jsx("div",{className:"overflow-x-auto my-6 rounded-lg shadow-sm border border-gray-200",children:e.jsx("table",{...u,className:"min-w-full divide-y divide-gray-200",children:m})}),thead:({children:m,...u})=>e.jsx("thead",{...u,className:"bg-gray-50",children:m}),tbody:({children:m,...u})=>e.jsx("tbody",{...u,className:"bg-white divide-y divide-gray-200",children:m}),tr:({children:m,...u})=>e.jsx("tr",{...u,className:"hover:bg-gray-50 transition-colors",children:m}),th:({children:m,...u})=>e.jsx("th",{...u,className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider border-r last:border-r-0 border-gray-200",children:m}),td:({children:m,...u})=>e.jsx("td",{...u,className:"px-6 py-4 whitespace-nowrap text-sm text-gray-900 border-r last:border-r-0 border-gray-200",children:m}),ul:({children:m,...u})=>e.jsx("ul",{...u,className:"list-disc pl-6 my-4 space-y-1",children:m}),ol:({children:m,...u})=>e.jsx("ol",{...u,className:"list-decimal pl-6 my-4 space-y-1",children:m}),li:({children:m,...u})=>e.jsx("li",{...u,className:"text-gray-700 leading-relaxed",children:m}),a:({href:m="#",children:u,...x})=>{const f=m?.startsWith("http"),v=m?.startsWith("#");return e.jsxs("a",{href:m,...x,className:"text-blue-600 hover:text-blue-800 hover:underline transition-colors font-medium",target:f?"_blank":void 0,rel:f?"noopener noreferrer":void 0,"data-anchor-link":v?"true":void 0,children:[u,f&&e.jsx("svg",{className:"inline w-3 h-3 ml-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"})})]})},strong:({children:m,...u})=>e.jsx("strong",{...u,className:"font-semibold text-gray-900",children:m}),em:({children:m,...u})=>e.jsx("em",{...u,className:"italic text-gray-700",children:m}),del:({children:m,...u})=>e.jsx("del",{...u,className:"line-through text-gray-500",children:m}),hr:({...m})=>e.jsx("hr",{...m,className:"my-8 border-t border-gray-300"}),input:({...m})=>e.jsx("input",{...m,disabled:!0,className:"form-checkbox h-4 w-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 mr-2"}),sub:({children:m})=>e.jsx("sub",{className:"text-xs",children:m}),sup:({children:m})=>e.jsx("sup",{className:"text-xs",children:m}),mark:({children:m})=>e.jsx("mark",{className:"bg-yellow-200 px-1 rounded",children:m}),kbd:({children:m})=>e.jsx("kbd",{className:"px-2 py-1 text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-300 rounded-lg shadow-sm",children:m}),details:({children:m,...u})=>e.jsx("details",{className:"my-4 border border-gray-200 rounded-lg overflow-hidden bg-white",...u,children:m}),summary:({children:m})=>e.jsx("summary",{className:"bg-gray-50 px-4 py-3 cursor-pointer font-medium text-gray-800 hover:bg-gray-100 transition-colors border-b border-gray-200",children:m})};return e.jsx("div",{className:"prose prose-lg max-w-none",children:e.jsx(cs,{remarkPlugins:[gs,xs,ps],rehypePlugins:[ds,[ms,Ur],us,[hs,{behavior:"append",properties:{className:["ml-2","text-blue-600","opacity-0","group-hover:opacity-100","transition-opacity","no-underline"],ariaLabel:"Permalink to section",title:"Permalink to section"},content:ze("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20"},[ze("path",{d:"M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5z"}),ze("path",{d:"M7.414 15.414a2 2 0 01-2.828-2.828l3-3a2 2 0 012.828 0 1 1 0 001.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5z"})])}]],components:k,children:o})})},Wr=()=>{const[s,i]=c.useState(!1),{slug:r,category:o}=ye(),t=ge(),[l,d]=c.useState(null),[h,w]=c.useState(!0),[k,m]=c.useState(null),[u,x]=c.useState(null),[f,v]=c.useState([]);c.useEffect(()=>{if(!r)return;(async()=>{w(!0);try{const C=await Or(r);C?(d(C),m(null),document.title=C.title||"News Detail"):(m("Post not found"),d(null))}catch(C){console.error("Error loading post:",C),m("Failed to load the post. Please try again later."),d(null)}finally{w(!1)}})()},[r]),c.useEffect(()=>{if(!h&&f.length>0){const N=C=>{const y=C.target;x({src:y.src,alt:y.alt||"Image"}),document.body.classList.add("overflow-hidden")};return f.forEach(C=>C.addEventListener("click",N)),()=>{f.forEach(C=>C.removeEventListener("click",N))}}},[h,f]),c.useEffect(()=>{const N=C=>{C.key==="Escape"&&u&&g()};return window.addEventListener("keydown",N),()=>window.removeEventListener("keydown",N)});const L=c.useCallback(()=>{t(o?`/news/${o}`:"/news/community-news")},[t,o]),g=c.useCallback(()=>{x(null),document.body.classList.remove("overflow-hidden")},[]),j=c.useCallback(N=>{t(`/tags/${N}`)},[t]),I=c.useCallback(()=>{l?.author?.slug&&t(`/authors/${l.author.slug}`)},[t,l]),S=()=>{i(!0)};return h&&!l?e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsx("div",{className:"container mx-auto px-4 py-16 flex justify-center items-center min-h-screen",children:e.jsxs("div",{className:"flex flex-col items-center",children:[e.jsx("div",{className:"animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-600 mb-4"}),e.jsx("p",{className:"text-gray-600",children:"Loading article..."})]})}),e.jsx(M,{})]}):k||!l?e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsxs("div",{className:"container mx-auto px-4 py-16 text-center min-h-screen flex flex-col justify-center",children:[e.jsx("h1",{className:"text-3xl font-bold mb-4 text-blue-600",children:k||"Post Not Found"}),e.jsx("p",{className:"mb-8 text-gray-600",children:"The post you're looking for doesn't exist or has been removed."}),e.jsx("button",{onClick:L,className:"px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors mx-auto focus:outline-none focus:ring-2 focus:ring-blue-400",children:"Back to News"})]}),e.jsx(M,{})]}):e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsxs("div",{className:"container mx-auto px-4 py-8 max-w-4xl bg-white mt-10",children:[e.jsxs(a.button,{onClick:L,className:"mb-6 px-4 py-2 flex items-center text-blue-600 hover:text-blue-700 transition-colors rounded-md hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-blue-400",whileHover:{scale:1.05},whileTap:{scale:.95},"aria-label":"Back to news list",children:[e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5 mr-2",viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{fillRule:"evenodd",d:"M9.707 14.707a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 1.414L7.414 9H15a1 1 0 110 2H7.414l2.293 2.293a1 1 0 010 1.414z",clipRule:"evenodd"})}),"Back to News"]}),e.jsxs("div",{className:"mb-8 border-b border-gray-200 pb-6",children:[l.category&&e.jsx("span",{className:"inline-block px-3 py-1 text-sm font-semibold bg-green-100 text-green-600 mb-4 rounded-full",children:l.category}),e.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[e.jsx("h1",{className:"text-4xl font-bold text-gray-900",children:l.title}),e.jsx("button",{onClick:S,className:"p-2 rounded-full bg-gradient-to-r from-blue-600 to-blue-700 text-white shadow hover:from-blue-700 hover:to-green-600 focus:outline-none focus:ring-2 focus:ring-blue-400 transition-all duration-300 cursor-pointer",title:"Share",type:"button",children:e.jsx(Ut,{size:16,className:"text-white"})})]}),e.jsxs("div",{className:"flex flex-wrap items-center text-gray-500 mb-3",children:[l.date&&e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"mr-4 flex items-center",children:[e.jsx("svg",{className:"w-4 h-4 mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"})}),e.jsx("time",{dateTime:l.date,children:l.date})]}),l.author&&e.jsx("span",{className:"mr-4",children:"•"})]}),l.author&&e.jsxs("span",{className:"flex items-center cursor-pointer hover:text-blue-600 transition-colors",onClick:I,children:[e.jsx("svg",{className:"w-4 h-4 mr-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"})}),l.author.name]})]}),l.tags&&l.tags.length>0&&e.jsx("div",{className:"flex flex-wrap gap-2 mt-3",children:l.tags.map((N,C)=>e.jsxs("span",{onClick:()=>j(N),className:"text-xs bg-gray-100 text-gray-600 px-2 py-1 rounded-md hover:bg-blue-100 hover:text-blue-700 cursor-pointer transition-colors",children:["#",N]},C))})]}),l.image&&e.jsx(a.div,{className:"mb-8 rounded-lg overflow-hidden shadow-lg max-w-2xl mx-auto bg-gray-50",initial:{opacity:0,y:-20},animate:{opacity:1,y:0},transition:{duration:.5},children:e.jsx("img",{src:l.image,alt:l.title,className:"w-full h-auto max-h-80 object-contain mx-auto cursor-pointer hover:scale-105 transition-transform duration-300",onClick:()=>x({src:l.image,alt:l.title}),"data-zoomable":"true"})}),e.jsx(a.div,{className:"mb-12",initial:{opacity:0},animate:{opacity:1},transition:{duration:.5},children:e.jsx(bt,{content:l.content,setZoomableImages:v})},r),l.author&&e.jsxs(a.div,{className:"bg-blue-50 rounded-lg p-6 my-8 flex items-center space-x-4 cursor-pointer hover:bg-blue-100 transition-colors",onClick:I,whileHover:{scale:1.02},children:[e.jsx("div",{className:"w-16 h-16 flex-shrink-0",children:l.author.avatar?e.jsx("img",{src:l.author.avatar,alt:l.author.name,className:"w-16 h-16 rounded-full object-cover"}):e.jsx("div",{className:"w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center text-blue-600 font-bold text-xl",children:l.author.name.charAt(0).toUpperCase()})}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("h4",{className:"font-semibold text-lg text-gray-800 hover:text-blue-600 transition-colors",children:["About ",l.author.name]}),e.jsx("p",{className:"text-gray-600 mt-1",children:l.author.description}),e.jsx("p",{className:"text-sm text-blue-600 mt-2",children:"Click to view profile →"})]})]}),l.tags&&l.tags.length>0&&e.jsxs("div",{className:"border-t border-gray-200 pt-6 mb-8",children:[e.jsx("h3",{className:"text-xl font-semibold mb-4 text-gray-700",children:"Tags"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:l.tags.map((N,C)=>e.jsxs("span",{onClick:()=>j(N),className:"px-3 py-1 bg-gray-100 text-gray-700 rounded-full text-sm hover:bg-blue-100 hover:text-blue-700 cursor-pointer transition-colors",children:["#",N]},C))})]}),e.jsx("div",{className:"fixed bottom-8 right-8 z-50",children:e.jsx(a.button,{onClick:()=>window.scrollTo({top:0,behavior:"smooth"}),className:"p-3 bg-blue-600 text-white rounded-full shadow-lg hover:bg-blue-700 transition-colors focus:outline-none focus:ring-2 focus:ring-blue-400","aria-label":"Back to top",whileHover:{scale:1.05},whileTap:{scale:.95},children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-6 w-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor","aria-hidden":"true",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 15l7-7 7 7"})})})})]}),u&&e.jsx(a.div,{className:"fixed inset-0 bg-black bg-opacity-80 z-50 flex items-center justify-center p-4",initial:{opacity:0},animate:{opacity:1},onClick:N=>{N.target===N.currentTarget&&g()},role:"dialog","aria-modal":"true","aria-labelledby":"modal-image-title",children:e.jsxs("div",{className:"relative max-w-4xl max-h-full",children:[e.jsx(a.img,{src:u.src,alt:u.alt,className:"max-w-full max-h-[90vh] object-contain",initial:{scale:.8,opacity:0},animate:{scale:1,opacity:1},transition:{type:"spring",stiffness:300,damping:25},id:"modal-image-title"}),e.jsx("p",{className:"text-white text-center mt-2 text-sm",children:u.alt}),e.jsx("button",{onClick:g,className:"absolute top-2 right-2 text-white text-2xl hover:text-gray-300 bg-black bg-opacity-50 rounded-full w-8 h-8 flex items-center justify-center focus:outline-none focus:ring-2 focus:ring-white","aria-label":"Close image",children:"×"})]})}),e.jsx(ts,{open:s,onClose:()=>i(!1),url:l?`${window.location.origin}/news/${o||"all"}/${l.slug}`:"",title:l?.title||"",excerpt:l?.excerpt||""}),e.jsx(M,{})]})},$r=()=>{const{slug:s}=ye(),i=ge(),[r,o]=c.useState(null),[t,l]=c.useState([]),[d,h]=c.useState([]),[w,k]=c.useState(!0),[m,u]=c.useState(null),[x,f]=c.useState(6),[v,L]=c.useState(""),[g,j]=c.useState("All"),[I,S]=c.useState("grid"),[N,C]=c.useState("date");c.useEffect(()=>{(async()=>{if(s){k(!0);try{const[R,p]=await Promise.all([ss(s),Dr(s)]);if(!R){u("Author not found");return}o(R),l(p),h(p),document.title=`${R.name} - SugarLabs`}catch(R){console.error("Error loading author:",R),u("Failed to load author information")}finally{k(!1)}}})()},[s]),c.useEffect(()=>{let _=[...t];v&&(_=_.filter(R=>R.title.toLowerCase().includes(v.toLowerCase())||R.excerpt?.toLowerCase().includes(v.toLowerCase())||R.tags.some(p=>p.toLowerCase().includes(v.toLowerCase())))),g!=="All"&&(_=_.filter(R=>R.category===g)),_.sort((R,p)=>N==="date"?new Date(p.date).getTime()-new Date(R.date).getTime():R.title.localeCompare(p.title)),h(_),f(6)},[t,v,g,N]);const y=_=>{const R=_.category.toLowerCase().replace(/\s+/g,"-");i(`/news/${R}/${_.slug}`)},D=()=>{f(_=>Math.min(_+6,d.length))},B=()=>["All",...Array.from(new Set(t.map(R=>R.category))).sort()],q=d.slice(0,x),X=d.length>x;return w?e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsx("div",{className:"container mx-auto px-4 py-16 flex justify-center items-center min-h-screen",children:e.jsxs("div",{className:"flex flex-col items-center",children:[e.jsx("div",{className:"animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-600 mb-4"}),e.jsx("p",{className:"text-gray-600",children:"Loading author profile..."})]})}),e.jsx(M,{})]}):m||!r?e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsxs("div",{className:"container mx-auto px-4 py-16 text-center min-h-screen flex flex-col justify-center",children:[e.jsx("h1",{className:"text-3xl font-bold mb-4 text-blue-600",children:"Author Not Found"}),e.jsx("p",{className:"mb-8 text-gray-600",children:"The author profile you're looking for doesn't exist."}),e.jsx("button",{onClick:()=>i("/news"),className:"px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors mx-auto",children:"Back to News"})]}),e.jsx(M,{})]}):e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsx("div",{className:"min-h-screen bg-gradient-to-br from-blue-50 via-white to-green-50",children:e.jsxs("div",{className:"container mx-auto px-4 py-8 max-w-7xl",children:[e.jsxs(a.button,{onClick:()=>i(-1),className:"mb-6 px-4 py-2 flex items-center text-blue-600 hover:text-blue-700 transition-colors rounded-md hover:bg-blue-50",whileHover:{scale:1.05},whileTap:{scale:.95},children:[e.jsx(ut,{className:"h-5 w-5 mr-2"}),"Back"]}),e.jsx(a.div,{className:"bg-white rounded-2xl shadow-xl p-4 sm:p-6 lg:p-8 mb-8",initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5},children:e.jsxs("div",{className:"flex flex-col sm:flex-row items-center sm:items-start gap-6 lg:gap-8",children:[e.jsx("div",{className:"flex-shrink-0",children:r.avatar?e.jsx("img",{src:r.avatar,alt:r.name,className:"w-24 h-24 sm:w-28 sm:h-28 lg:w-32 lg:h-32 rounded-full object-cover border-4 border-blue-100"}):e.jsx("div",{className:"w-24 h-24 sm:w-28 sm:h-28 lg:w-32 lg:h-32 bg-blue-100 rounded-full flex items-center justify-center",children:e.jsx(Gt,{className:"w-12 h-12 sm:w-14 sm:h-14 lg:w-16 lg:h-16 text-blue-600"})})}),e.jsxs("div",{className:"flex-1 text-center sm:text-left",children:[e.jsx("h1",{className:"text-2xl sm:text-3xl lg:text-4xl font-bold text-gray-900 mb-2",children:r.name}),e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center gap-2 mb-3",children:[e.jsx("span",{className:"text-lg lg:text-xl text-blue-600 font-medium",children:r.title}),r.organization&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"hidden sm:inline text-gray-400",children:"at"}),e.jsxs("div",{className:"flex items-center justify-center sm:justify-start gap-1 text-gray-700",children:[e.jsx(Ee,{className:"w-4 h-4"}),e.jsx("span",{className:"font-medium",children:r.organization})]})]})]}),e.jsx("p",{className:"text-gray-600 text-base lg:text-lg mb-4 max-w-2xl",children:r.description}),e.jsxs("div",{className:"flex flex-wrap justify-center sm:justify-start gap-4 text-sm text-gray-600",children:[e.jsxs("div",{className:"flex items-center gap-1 bg-blue-50 px-3 py-1 rounded-full",children:[e.jsx(at,{className:"w-4 h-4"}),e.jsxs("span",{children:[t.length," ",t.length===1?"Article":"Articles"]})]}),r.organization&&e.jsxs("div",{className:"flex items-center gap-1 bg-gray-50 px-3 py-1 rounded-full",children:[e.jsx(Ee,{className:"w-4 h-4"}),e.jsx("span",{children:r.organization})]})]})]})]})}),e.jsxs("div",{className:"grid grid-cols-1 xl:grid-cols-4 gap-6 lg:gap-8",children:[e.jsxs(a.div,{className:"xl:col-span-3 order-2 xl:order-1",initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{duration:.5,delay:.2},children:[e.jsx("div",{className:"bg-white rounded-2xl shadow-xl p-4 sm:p-6 lg:p-8 mb-6 lg:mb-8",children:e.jsx(bt,{content:r.content})}),e.jsxs("div",{className:"bg-white rounded-2xl shadow-xl p-4 sm:p-6 lg:p-8",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(at,{className:"w-5 h-5 text-blue-600"}),e.jsxs("h3",{className:"text-xl lg:text-2xl font-bold text-gray-900",children:["Articles (",d.length,")"]})]}),t.length>0&&e.jsxs("div",{className:"flex flex-col sm:flex-row gap-3",children:[e.jsxs("div",{className:"relative",children:[e.jsx(Fe,{className:"absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4"}),e.jsx("input",{type:"text",placeholder:"Search articles...",value:v,onChange:_=>L(_.target.value),className:"pl-10 pr-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm w-full sm:w-auto"})]}),e.jsx("select",{value:g,onChange:_=>j(_.target.value),className:"px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm",children:B().map(_=>e.jsx("option",{value:_,children:_},_))}),e.jsxs("select",{value:N,onChange:_=>C(_.target.value),className:"px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm",children:[e.jsx("option",{value:"date",children:"Sort by Date"}),e.jsx("option",{value:"title",children:"Sort by Title"})]}),e.jsxs("div",{className:"flex bg-gray-100 rounded-lg p-1",children:[e.jsx("button",{onClick:()=>S("grid"),className:`p-2 rounded-md transition-colors ${I==="grid"?"bg-white text-blue-600 shadow-sm":"text-gray-600"}`,children:e.jsx(dt,{className:"w-4 h-4"})}),e.jsx("button",{onClick:()=>S("list"),className:`p-2 rounded-md transition-colors ${I==="list"?"bg-white text-blue-600 shadow-sm":"text-gray-600"}`,children:e.jsx(mt,{className:"w-4 h-4"})})]})]})]}),d.length===0?e.jsxs("div",{className:"text-center py-12",children:[e.jsx("div",{className:"text-4xl mb-4",children:v||g!=="All"?"🔍":"📝"}),e.jsx("h4",{className:"text-lg font-semibold text-gray-700 mb-2",children:v||g!=="All"?"No matching articles":"No articles published yet"}),e.jsx("p",{className:"text-gray-600",children:v||g!=="All"?"Try adjusting your search or filter criteria":"Articles will appear here when published"}),(v||g!=="All")&&e.jsx("button",{onClick:()=>{L(""),j("All")},className:"mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors",children:"Clear Filters"})]}):e.jsxs(e.Fragment,{children:[e.jsx(a.div,{className:I==="grid"?"grid grid-cols-1 md:grid-cols-2 gap-6":"space-y-4",initial:"hidden",animate:"visible",children:e.jsx(Y,{children:q.map((_,R)=>e.jsxs(a.article,{className:` + border border-gray-200 rounded-lg hover:border-blue-300 hover:shadow-md + transition-all duration-300 cursor-pointer group bg-white + ${I==="list"?"flex gap-4 p-4":"p-4"} + `,onClick:()=>y(_),initial:{opacity:0,y:20},animate:{opacity:1,y:0},exit:{opacity:0,y:-20},transition:{duration:.3,delay:R*.05},whileHover:{scale:1.02},children:[I==="list"&&_.image&&e.jsx("div",{className:"w-24 h-24 flex-shrink-0",children:e.jsx("img",{src:_.image,alt:_.title,className:"w-full h-full object-cover rounded-lg"})}),e.jsxs("div",{className:"flex-1",children:[e.jsx("h4",{className:"font-semibold text-gray-900 mb-2 line-clamp-2 group-hover:text-blue-600 transition-colors",children:_.title}),e.jsx("p",{className:"text-sm text-gray-600 mb-3 line-clamp-2",children:_.excerpt}),e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-2 text-xs text-gray-500",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(ht,{className:"w-3 h-3"}),_.date]}),_.tags.length>0&&e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"w-1 h-1 bg-gray-400 rounded-full"}),e.jsx("span",{children:_.tags.slice(0,2).join(", ")}),_.tags.length>2&&e.jsxs("span",{children:["+",_.tags.length-2]})]})]}),e.jsx("span",{className:"px-2 py-1 bg-blue-100 text-blue-600 rounded-full text-xs font-medium",children:_.category})]})]})]},_.slug))})}),X&&e.jsx("div",{className:"text-center mt-8",children:e.jsxs(a.button,{onClick:D,className:"px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium flex items-center gap-2 mx-auto",whileHover:{scale:1.05},whileTap:{scale:.95},children:["Load More Articles",e.jsx(Wt,{className:"w-4 h-4"}),e.jsxs("span",{className:"text-xs bg-blue-500 px-2 py-1 rounded-full",children:["+",Math.min(6,d.length-x)]})]})})]})]})]}),e.jsxs(a.div,{className:"order-1 xl:order-2",initial:{opacity:0,x:20},animate:{opacity:1,x:0},transition:{duration:.5,delay:.3},children:[e.jsxs("div",{className:"bg-white rounded-2xl shadow-xl p-6 mb-6",children:[e.jsx("h3",{className:"text-lg font-bold text-gray-900 mb-4",children:"Profile Stats"}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("span",{className:"text-gray-600",children:"Total Articles"}),e.jsx("span",{className:"font-semibold text-blue-600",children:t.length})]}),e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("span",{className:"text-gray-600",children:"Categories"}),e.jsx("span",{className:"font-semibold text-gray-900",children:B().length-1})]})]})]}),B().length>2&&e.jsxs("div",{className:"bg-white rounded-2xl shadow-xl p-6",children:[e.jsx("h3",{className:"text-lg font-bold text-gray-900 mb-4",children:"Categories"}),e.jsx("div",{className:"space-y-2",children:B().slice(1).map(_=>{const R=t.filter(p=>p.category===_).length;return e.jsxs("button",{onClick:()=>j(_),className:`w-full flex justify-between items-center p-2 rounded-lg transition-colors text-left ${g===_?"bg-blue-50 text-blue-700":"hover:bg-gray-50"}`,children:[e.jsx("span",{className:"text-sm font-medium",children:_}),e.jsx("span",{className:"text-xs bg-gray-100 px-2 py-1 rounded-full",children:R})]},_)})})]})]})]})]})}),e.jsx(M,{})]})},qr=()=>{const{tag:s}=ye(),i=ge(),[r,o]=c.useState([]),[t,l]=c.useState([]),[,d]=c.useState([]),[h,w]=c.useState(!0),[k,m]=c.useState(null),[u,x]=c.useState(8),[f,v]=c.useState(""),[L,g]=c.useState("All"),[j,I]=c.useState("grid"),[S,N]=c.useState("date");c.useEffect(()=>{(async()=>{if(s){w(!0);try{const[b,T]=await Promise.all([Fr(s),Br()]);o(b),l(b),d(T),document.title=`#${s} - SugarLabs`}catch(b){console.error("Error loading tag posts:",b),m("Failed to load posts")}finally{w(!1)}}})()},[s]),c.useEffect(()=>{let p=[...r];f&&(p=p.filter(b=>b.title.toLowerCase().includes(f.toLowerCase())||b.excerpt?.toLowerCase().includes(f.toLowerCase()))),L!=="All"&&(p=p.filter(b=>b.category===L)),p.sort((b,T)=>{switch(S){case"date":return new Date(T.date).getTime()-new Date(b.date).getTime();case"title":return b.title.localeCompare(T.title);case"relevance":{const U=b.tags.filter(Ve=>Ve.toLowerCase().includes(s?.toLowerCase()||"")).length;return T.tags.filter(Ve=>Ve.toLowerCase().includes(s?.toLowerCase()||"")).length-U}default:return 0}}),l(p),x(8)},[r,f,L,S,s]);const C=p=>{const b=p.category.toLowerCase().replace(/\s+/g,"-");i(`/news/${b}/${p.slug}`)},y=p=>{p!==s&&i(`/tags/${p}`)},D=()=>{x(p=>Math.min(p+8,t.length))},B=()=>["All",...Array.from(new Set(r.map(b=>b.category))).sort()],q=()=>{const p={};return r.forEach(b=>{b.tags.forEach(T=>{T!==s&&(p[T]=(p[T]||0)+1)})}),Object.entries(p).sort(([,b],[,T])=>T-b).slice(0,8).map(([b])=>b)},X=t.slice(0,u),_=t.length>u,R=q();return h?e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsx("div",{className:"container mx-auto px-4 py-16 flex justify-center items-center min-h-screen",children:e.jsxs("div",{className:"flex flex-col items-center",children:[e.jsx("div",{className:"animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-600 mb-4"}),e.jsx("p",{className:"text-gray-600",children:"Loading posts..."})]})}),e.jsx(M,{})]}):k?e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsxs("div",{className:"container mx-auto px-4 py-16 text-center min-h-screen flex flex-col justify-center",children:[e.jsx("h1",{className:"text-3xl font-bold mb-4 text-red-600",children:"Error Loading Posts"}),e.jsx("p",{className:"mb-8 text-gray-600",children:k}),e.jsx("button",{onClick:()=>i("/news"),className:"px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors mx-auto",children:"Back to News"})]}),e.jsx(M,{})]}):e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsx("div",{className:"min-h-screen bg-gradient-to-br from-blue-50 via-white to-green-50",children:e.jsxs("div",{className:"container mx-auto px-4 py-8 max-w-7xl",children:[e.jsxs(a.button,{onClick:()=>i(-1),className:"mb-6 px-4 py-2 flex items-center text-blue-600 hover:text-blue-700 transition-colors rounded-md hover:bg-blue-50",whileHover:{scale:1.05},whileTap:{scale:.95},children:[e.jsx(ut,{className:"h-5 w-5 mr-2"}),"Back"]}),e.jsx(a.div,{className:"bg-white rounded-2xl shadow-xl p-6 sm:p-8 mb-8",initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5},children:e.jsxs("div",{className:"text-center",children:[e.jsxs("div",{className:"flex items-center justify-center gap-3 mb-4",children:[e.jsx("div",{className:"p-3 bg-blue-100 rounded-full",children:e.jsx(st,{className:"w-8 h-8 text-blue-600"})}),e.jsxs("h1",{className:"text-3xl sm:text-4xl lg:text-5xl font-bold text-gray-900",children:["#",s]})]}),e.jsxs("p",{className:"text-gray-600 text-lg mb-6",children:[r.length," ",r.length===1?"article":"articles"," ","tagged with #",s]}),e.jsxs("div",{className:"flex flex-wrap justify-center gap-4 text-sm",children:[e.jsxs("div",{className:"flex items-center gap-2 bg-blue-50 px-4 py-2 rounded-full",children:[e.jsx(at,{className:"w-4 h-4 text-blue-600"}),e.jsxs("span",{className:"font-medium",children:[r.length," Articles"]})]}),e.jsxs("div",{className:"flex items-center gap-2 bg-green-50 px-4 py-2 rounded-full",children:[e.jsx(Ht,{className:"w-4 h-4 text-green-600"}),e.jsxs("span",{className:"font-medium",children:[B().length-1," Categories"]})]}),e.jsxs("div",{className:"flex items-center gap-2 bg-purple-50 px-4 py-2 rounded-full",children:[e.jsx(st,{className:"w-4 h-4 text-purple-600"}),e.jsxs("span",{className:"font-medium",children:[R.length," Related Tags"]})]})]})]})}),e.jsxs("div",{className:"grid grid-cols-1 xl:grid-cols-4 gap-6 lg:gap-8",children:[e.jsxs("div",{className:"xl:col-span-3",children:[r.length>0&&e.jsx(a.div,{className:"bg-white rounded-2xl shadow-xl p-4 sm:p-6 mb-6",initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5,delay:.1},children:e.jsxs("div",{className:"flex flex-col lg:flex-row lg:items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(bs,{className:"w-5 h-5 text-gray-600"}),e.jsxs("span",{className:"font-medium text-gray-900",children:["Showing ",t.length," of ",r.length," ","articles"]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-3",children:[e.jsxs("div",{className:"relative",children:[e.jsx(Fe,{className:"absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4"}),e.jsx("input",{type:"text",placeholder:"Search in results...",value:f,onChange:p=>v(p.target.value),className:"pl-10 pr-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm w-full sm:w-auto"})]}),e.jsx("select",{value:L,onChange:p=>g(p.target.value),className:"px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm",children:B().map(p=>e.jsx("option",{value:p,children:p},p))}),e.jsxs("select",{value:S,onChange:p=>N(p.target.value),className:"px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm",children:[e.jsx("option",{value:"date",children:"Latest First"}),e.jsx("option",{value:"title",children:"A-Z"}),e.jsx("option",{value:"relevance",children:"Most Relevant"})]}),e.jsxs("div",{className:"flex bg-gray-100 rounded-lg p-1",children:[e.jsx("button",{onClick:()=>I("grid"),className:`p-2 rounded-md transition-colors ${j==="grid"?"bg-white text-blue-600 shadow-sm":"text-gray-600"}`,children:e.jsx(dt,{className:"w-4 h-4"})}),e.jsx("button",{onClick:()=>I("list"),className:`p-2 rounded-md transition-colors ${j==="list"?"bg-white text-blue-600 shadow-sm":"text-gray-600"}`,children:e.jsx(mt,{className:"w-4 h-4"})})]})]})]})}),t.length===0?e.jsxs(a.div,{className:"bg-white rounded-2xl shadow-xl p-12 text-center",initial:{opacity:0},animate:{opacity:1},children:[e.jsx("div",{className:"text-6xl mb-6",children:f||L!=="All"?"🔍":"🏷️"}),e.jsx("h3",{className:"text-2xl font-bold text-gray-800 mb-4",children:f||L!=="All"?"No matching articles":"No articles found"}),e.jsx("p",{className:"text-gray-600 mb-6",children:f||L!=="All"?"Try adjusting your search or filter criteria":`No articles are tagged with #${s} yet.`}),(f||L!=="All")&&e.jsx("button",{onClick:()=>{v(""),g("All")},className:"px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors",children:"Clear Filters"})]}):e.jsxs(e.Fragment,{children:[e.jsx(a.div,{className:j==="grid"?"grid grid-cols-1 md:grid-cols-2 gap-6 mb-8":"space-y-6 mb-8",initial:"hidden",animate:"visible",children:e.jsx(Y,{children:X.map((p,b)=>e.jsxs(a.article,{className:` + bg-white rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 + cursor-pointer overflow-hidden group + ${j==="list"?"flex":""} + `,onClick:()=>C(p),initial:{opacity:0,y:20},animate:{opacity:1,y:0},exit:{opacity:0,y:-20},transition:{duration:.3,delay:b*.05},whileHover:{y:-5},children:[e.jsx("div",{className:j==="list"?"w-1/3 sm:w-1/4":"",children:p.image?e.jsx("img",{src:p.image,alt:p.title,className:`w-full object-cover ${j==="list"?"h-full":"h-48 sm:h-56"}`}):e.jsx("div",{className:`w-full bg-gradient-to-br from-blue-100 to-purple-100 flex items-center justify-center ${j==="list"?"h-full":"h-48 sm:h-56"}`,children:e.jsx("div",{className:"text-4xl opacity-50",children:"📰"})})}),e.jsxs("div",{className:`p-4 sm:p-6 ${j==="list"?"w-2/3 sm:w-3/4":""}`,children:[e.jsx("div",{className:"flex items-center gap-2 mb-3",children:e.jsx("span",{className:"px-3 py-1 text-xs font-bold bg-green-500 text-white rounded-full",children:p.category})}),e.jsx("h2",{className:`font-bold text-gray-900 mb-3 group-hover:text-blue-600 transition-colors line-clamp-2 ${j==="list"?"text-lg":"text-xl"}`,children:p.title}),e.jsx("p",{className:"text-gray-600 mb-4 line-clamp-2 text-sm",children:p.excerpt}),e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-4 text-sm text-gray-500",children:[p.date&&e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(ht,{className:"w-4 h-4"}),e.jsx("span",{children:p.date})]}),p.author&&e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(Gt,{className:"w-4 h-4"}),e.jsx("span",{children:p.author.name})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-1",children:[p.tags.slice(0,3).map(T=>e.jsxs("button",{onClick:U=>{U.stopPropagation(),y(T)},className:`px-2 py-1 text-xs rounded-full transition-colors ${T===s?"bg-blue-100 text-blue-600 font-semibold":"bg-gray-100 text-gray-600 hover:bg-blue-50 hover:text-blue-600"}`,children:["#",T]},T)),p.tags.length>3&&e.jsxs("span",{className:"px-2 py-1 text-xs bg-gray-100 text-gray-500 rounded-full",children:["+",p.tags.length-3]})]})]})]})]},p.slug))})}),_&&e.jsx("div",{className:"text-center",children:e.jsxs(a.button,{onClick:D,className:"px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium flex items-center gap-2 mx-auto",whileHover:{scale:1.05},whileTap:{scale:.95},children:["Load More Articles",e.jsx(Wt,{className:"w-4 h-4"}),e.jsxs("span",{className:"text-xs bg-blue-500 px-2 py-1 rounded-full",children:["+",Math.min(8,t.length-u)]})]})})]})]}),e.jsxs(a.div,{className:"space-y-6",initial:{opacity:0,x:20},animate:{opacity:1,x:0},transition:{duration:.5,delay:.2},children:[R.length>0&&e.jsxs("div",{className:"bg-white rounded-2xl shadow-xl p-6",children:[e.jsx("h3",{className:"text-lg font-bold text-gray-900 mb-4",children:"Related Tags"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:R.map(p=>e.jsxs("button",{onClick:()=>y(p),className:"px-3 py-1 text-sm bg-gray-100 text-gray-700 rounded-full hover:bg-blue-100 hover:text-blue-700 transition-colors",children:["#",p]},p))})]}),e.jsxs("div",{className:"bg-white rounded-2xl shadow-xl p-6",children:[e.jsx("h3",{className:"text-lg font-bold text-gray-900 mb-4",children:"Tag Statistics"}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("span",{className:"text-gray-600",children:"Total Articles"}),e.jsx("span",{className:"font-semibold text-blue-600",children:r.length})]}),e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("span",{className:"text-gray-600",children:"Categories"}),e.jsx("span",{className:"font-semibold text-gray-900",children:B().length-1})]}),e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("span",{className:"text-gray-600",children:"Related Tags"}),e.jsx("span",{className:"font-semibold text-gray-900",children:R.length})]})]})]}),B().length>2&&e.jsxs("div",{className:"bg-white rounded-2xl shadow-xl p-6",children:[e.jsx("h3",{className:"text-lg font-bold text-gray-900 mb-4",children:"Categories"}),e.jsx("div",{className:"space-y-2",children:B().slice(1).map(p=>{const b=r.filter(T=>T.category===p).length;return e.jsxs("button",{onClick:()=>g(p),className:`w-full flex justify-between items-center p-2 rounded-lg transition-colors text-left ${L===p?"bg-blue-50 text-blue-700":"hover:bg-gray-50"}`,children:[e.jsx("span",{className:"text-sm font-medium",children:p}),e.jsx("span",{className:"text-xs bg-gray-100 px-2 py-1 rounded-full",children:b})]},p)})})]})]})]})]})}),e.jsx(M,{})]})},Ze=(s,i="")=>Array.isArray(s)?s.join(" ").trim():s?.trim()||i,ft=async()=>{try{const s=Object.assign({"/src/constants/MarkdownFiles/more/culture.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.c2),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/more/markdown-test.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.c3),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/more/parents.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.c4),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/more/school-admin.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.c5),[],import.meta.url).then(r=>r.default),"/src/constants/MarkdownFiles/more/students.md":()=>n(()=>import("./mdfiles-Dv9bnDYr.js").then(r=>r.c6),[],import.meta.url).then(r=>r.default)}),i=[];for(const[r,o]of Object.entries(s))try{const t=await o(),{frontmatter:l,content:d}=pt(t),h=r.split("/").pop()?.replace(".md","")||"",w={id:h,title:Ze(l.title,"Untitled"),content:d,slug:Ze(l.slug,h),category:Ze(l.category,"Uncategorized")};i.push(w)}catch(t){console.error(`Error processing ${r}:`,t)}return i.sort((r,o)=>r.title.localeCompare(o.title))}catch(s){return console.error("Error fetching more pages:",s),[]}},Yr=async s=>(await ft()).find(r=>r.slug===s)||null,Jr=async()=>{const s=await ft(),i={All:s};return s.forEach(r=>{const o=r.category||"Uncategorized";i[o]||(i[o]=[]),i[o].push(r)}),i},Kr=async()=>{const s=await ft();return s.length>0?s[0].slug:null},Bt=()=>{const{slug:s}=ye(),i=ge(),[r,o]=c.useState(null),[t,l]=c.useState(!0),[d,h]=c.useState([]),[w,k]=c.useState({}),[m,u]=c.useState("All"),[x,f]=c.useState(null),[v,L]=c.useState([]),[g,j]=c.useState(null);c.useEffect(()=>{(async()=>{l(!0);try{const N=await Jr();if(k(N),h(["All",...Object.keys(N).filter(C=>C!=="All")]),s){const C=await Yr(s);C?(o(C),f(null),document.title=C.title+" - Sugar Labs",C.category&&u(C.category)):(o(null),f(s??null),document.title="Page Not Found - Sugar Labs")}else{const C=await Kr();C&&i(`/more/${C}`,{replace:!0})}}catch(N){console.error("Error loading page:",N),o(null),f(s??null)}finally{l(!1)}})()},[s,i]),c.useEffect(()=>{if(!t&&v.length>0){const S=N=>{const C=N.target;j({src:C.src,alt:C.alt||"Image"}),document.body.classList.add("overflow-hidden")};return v.forEach(N=>N.addEventListener("click",S)),()=>{v.forEach(N=>N.removeEventListener("click",S))}}},[t,v]),c.useEffect(()=>{const S=N=>{N.key==="Escape"&&g&&I()};return window.addEventListener("keydown",S),()=>window.removeEventListener("keydown",S)});const I=()=>{j(null),document.body.classList.remove("overflow-hidden")};return t?e.jsx("div",{className:"container mx-auto px-4 py-16 flex justify-center items-center min-h-screen",children:e.jsx("div",{className:"animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-600"})}):e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsxs("div",{className:"container mx-auto px-4 py-8 mt-10",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx(F,{to:"/",className:"text-blue-600 hover:underline mb-2 inline-block",children:e.jsxs(a.button,{className:"mb-6 px-4 py-2 flex items-center text-blue-600 hover:text-blue-700 transition-colors rounded-md hover:bg-blue-50",whileHover:{scale:1.05},whileTap:{scale:.95},children:[e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5 mr-2",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M9.707 14.707a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 1.414L7.414 9H15a1 1 0 110 2H7.414l2.293 2.293a1 1 0 010 1.414z",clipRule:"evenodd"})}),"Back to Home"]})}),e.jsx("h2",{className:"text-3xl font-bold border-b-2 border-red-500 pb-2",children:r?r.title:"Page Not Found"})]}),e.jsxs("div",{className:"flex flex-col md:flex-row gap-8",children:[e.jsx("div",{className:"md:w-1/4",children:e.jsxs("div",{className:"bg-gray-50 p-4 rounded-lg shadow-md",children:[e.jsxs("div",{className:"mb-6",children:[e.jsx("h3",{className:"font-bold text-xl mb-2",children:"Categories"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:d.map(S=>e.jsx("button",{onClick:()=>u(S),className:`px-3 py-1 rounded-full text-sm ${m===S?"bg-blue-600 text-white":"bg-gray-200 text-gray-700 hover:bg-gray-300"}`,children:S},S))})]}),e.jsx("h3",{className:"font-bold text-xl mb-4",children:m==="All"?"All Pages":m+" Pages"}),e.jsx("ul",{className:"space-y-2",children:w[m]?.map(S=>e.jsx("li",{children:e.jsx(F,{to:`/more/${S.slug}`,className:`block p-2 rounded hover:bg-gray-100 transition ${S.slug===r?.slug?"bg-red-100 text-red-600 font-medium":"text-gray-700"}`,children:S.title})},S.slug))})]})}),e.jsx(a.div,{className:"md:w-3/4",initial:{opacity:0},animate:{opacity:1},transition:{duration:.5},children:e.jsx("div",{className:"bg-white rounded-lg shadow-md p-6",children:r?e.jsx("div",{className:"prose prose-lg max-w-none",children:e.jsx(bt,{content:r.content,setZoomableImages:L,frontmatter:{title:r.title,slug:r.slug,category:r.category??null}})}):e.jsxs("div",{className:"text-center py-8",children:[e.jsx("div",{className:"mx-auto w-20 h-20 flex items-center justify-center bg-red-100 rounded-full mb-6",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-10 w-10 text-red-500",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),e.jsx("h3",{className:"text-2xl font-bold mb-4 text-gray-800",children:"The page you are looking for has been deleted or is not present"}),x&&e.jsx("p",{className:"mb-4 text-gray-600",children:"Page was not found."}),e.jsx("div",{className:"mb-8",children:e.jsx(F,{to:"/",className:"inline-block px-6 py-3 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors",children:"Go Back to Home"})})]})})},r?.slug)]})]}),g&&e.jsx(a.div,{className:"fixed inset-0 bg-black bg-opacity-80 z-50 flex items-center justify-center p-4",initial:{opacity:0},animate:{opacity:1},onClick:S=>{S.target===S.currentTarget&&I()},role:"dialog","aria-modal":"true","aria-labelledby":"modal-image-title",children:e.jsxs("div",{className:"relative max-w-4xl max-h-full",children:[e.jsx(a.img,{src:g.src,alt:g.alt,className:"max-w-full max-h-[90vh] object-contain",initial:{scale:.8,opacity:0},animate:{scale:1,opacity:1},transition:{type:"spring",stiffness:300,damping:25},id:"modal-image-title"}),e.jsx("p",{className:"text-white text-center mt-2 text-sm",children:g.alt}),e.jsx("button",{onClick:I,className:"absolute top-2 right-2 text-white text-2xl hover:text-gray-300 bg-black bg-opacity-50 rounded-full w-8 h-8 flex items-center justify-center focus:outline-none focus:ring-2 focus:ring-white","aria-label":"Close image",children:"×"})]})}),e.jsx(M,{})]})},le=({data:s})=>{const[i,r]=c.useState(0);return e.jsxs(a.section,{className:"w-[90%] mx-auto py-10 flex flex-col md:flex-row items-center gap-10",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},variants:ce.section,children:[e.jsxs(a.div,{className:"md:w-1/2 text-center md:text-left",variants:ce.textContainer,children:[e.jsx("h1",{className:"text-5xl font-bold text-blue-600",children:s.title}),e.jsx("h2",{className:"text-4xl font-bold text-black mt-2",children:s.subtitle}),e.jsx("p",{className:"text-lg font-semibold mt-4",children:s.quote}),e.jsx("p",{className:"text-gray-700 mt-4",children:s.description})]}),e.jsx(a.div,{className:"md:w-1/2 flex flex-col justify-center items-center relative",variants:ce.imageContainer,children:s.images&&s.images.length>0?e.jsx(De.Carousel,{selectedItem:i,onChange:o=>r(o),showThumbs:!1,showStatus:!1,infiniteLoop:!0,autoPlay:!0,interval:3e3,transitionTime:600,emulateTouch:!0,dynamicHeight:!0,children:s.images.map((o,t)=>e.jsx(a.div,{className:"w-full max-w-lg",children:e.jsx(a.img,{src:o.src,alt:o.alt,className:"w-full rounded-lg shadow-md",initial:"hidden",animate:"visible",whileHover:"hover",variants:ce.image})},t))}):e.jsx(a.div,{className:"w-full max-w-lg h-64 bg-gray-300 rounded-lg flex items-center justify-center",initial:"hidden",animate:"visible",variants:ce.image,children:e.jsx("p",{className:"text-gray-500",children:"No Image Available"})})}),s.note&&e.jsx(a.p,{className:"text-black font-bold mt-6 text-center w-full",initial:"hidden",whileInView:"visible",viewport:{once:!0},variants:ce.note,children:s.note})]})},ct=(s,i)=>!i?.length||!s?s:[...i].sort((o,t)=>t.text.length-o.text.length).reduce((o,{text:t,url:l})=>{const d=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),h=new RegExp(d,"g");return o.replace(h,`<a href="${l}" target="_blank" rel="noopener noreferrer" class="text-blue-600 hover:underline">${t}</a>`)},s),he=({title:s,content:i,button:r,buttonLink:o,links:t})=>{const l=i.includes(` +`)?i.split(` +`):[i];return e.jsxs(a.section,{className:"w-[90%] mx-auto text-center my-10",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},variants:pe.section,children:[e.jsx(a.h2,{className:"text-4xl font-semibold border-b-2 border-gray-300 inline-block pb-2 font-[Caveat]",variants:pe.text,children:s}),l.length>1?e.jsx("ul",{className:"text-gray-700 mt-4 list-disc list-inside text-left",children:l.map((d,h)=>e.jsx(a.li,{className:"mb-2",custom:h,variants:pe.listItem(h),children:e.jsx("span",{dangerouslySetInnerHTML:{__html:rt.sanitize(ct(d.trim(),t))}})},h))}):e.jsx(a.p,{className:"text-gray-700 mt-4",variants:pe.text,children:e.jsx("span",{dangerouslySetInnerHTML:{__html:rt.sanitize(ct(i,t))}})}),r&&e.jsx(a.button,{className:"mt-4 bg-blue-600 text-white font-bold py-2 px-6 rounded-full shadow-lg hover:bg-blue-700 transition",whileHover:"hover",variants:pe.button,onClick:()=>window.open(o,"_blank"),children:r})]})},Xr={title:"Turtle Blocks",subtitle:"Playground for Coding",quote:"“Knowledge is a noun; learning is a verb.” — Walter Bender, Sugar Labs founder",description:"Turtle Blocks JavaScript lets users create colorful art with a Logo-inspired turtle using snap-together coding blocks. It’s beginner-friendly yet powerful enough for advanced programming, graphics, and math exploration.",images:[{src:"assets/TryNowImages/turtleblocks2.png",alt:"Turtle Blocks Example 1"},{src:"assets/TryNowImages/turtleblocks1.png",alt:"Turtle Blocks Example 2"},{src:"assets/TryNowImages/turtleBlocks.png",alt:"Turtle Blocks Example 3"}]},Qr=[{title:"Using turtle art JS",content:"Turtle Blocks Javascript is designed to run in a browser. Most of the development has been done in Chrome, but it also works in Firefox. You can run it directly from index.html, from a server maintained by Sugar Labs, from the github repo, or by setting up a local server. Once you've launched it in your browser, start by clicking on (or dragging) blocks from the Turtle palette. Use multiple blocks to create drawings; as the turtle moves under your control, colorful lines are drawn. You add blocks to your program by clicking on or dragging them from the palette to the main area. You can delete a block by dragging it back onto the palette. Click anywhere on a 'stack' of blocks to start executing that stack or by clicking in the Rabbit (fast) or Turtle (slow) on the Main Toolbar.",button:null,links:[{text:"server maintained by Sugar Labs",url:"http://turtle.sugarlabs.org/"},{text:"local server",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/server.md"},{text:"github repo",url:"http://rawgit.com/sugarlabs/turtleblocksjs/master/index.html"}]},{title:"Getting Started Documentation",content:"The basic buttons and basic blocks are explained in detail in Documentation. A guide to programming with Turtle Blocks is available in Turtle Blocks Guide. A quick start: Google Code-in participant Jasmine Park has created some guides to using Turtle Blocks: Turtle Blocks: An Introductory Manual and Turtle Blocks: A Manual for Advanced Blocks.",links:[{text:"Documentation",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/documentation/README.md"},{text:"Turtle Blocks Guide",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/guide/README.md"},{text:"Turtle Blocks: An Introductory Manual",url:"http://people.sugarlabs.org/walter/TurtleBlocksIntroductoryManual.pdf"},{text:"Turtle Blocks: A Manual for Advanced Blocks",url:"http://people.sugarlabs.org/walter/TurtleBlocksAdvancedBlocksManual.pdf"}],button:null},{title:"Found a Bug?",content:"Bugs can be reported in the issues section of the repository",links:[{text:"issues section",url:"https://github.com/sugarlabs/turtleblocksjs/issues"}],button:null},{title:"Advance Features",content:"Turtle Blocks has a plugin mechanism that is used to add new blocks. You can learn more about how to use plugins (and how to write them) from the Plugins Guide.",links:[{text:"Plugins Guide",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/README.md"}],button:null},{title:"List of Plugins",content:`Mindstorms: blocks to interact with the LEGO mindstorms robotics kit + RoDi: blocks to interact with Rodi wireless robot + Maths: addition blocks for some more advanced mathematics + Translate: blocks for translating strings between languages, e.g., English to Spanish + Dictionary: a block to look up dictionary definitions + Weather: blocks to retrieve global weather forecasts + Logic: blocks for bitwise Boolean operations + Finance: a block for looking up market prices + Bitcoin: a block for looking up bitcoin exchange rates + Nutrition: blocks for exploring the nutritional content of food + Facebook: a block for publishing a project to facebook + Heap: blocks to support a heap and for loading and saving data + Accelerometer: blocks for accessing an accelerometer + Turtle: blocks to support advanced features when using multiple turtles + Gmap: blocks to support generation of Google maps.`,links:[{text:"Mindstorms",url:"https://github.com/SAMdroid-apps/turtlestorm"},{text:"RoDi",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/rodi.json"},{text:"Maths",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/maths.json"},{text:"Translate",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/translate.json"},{text:"Dictionary",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/dictionary.json"},{text:"Weather",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/weather.json"},{text:"Logic",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/logic.json"},{text:"Finance",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/finance.json"},{text:"Bitcoin",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/bitcoin.json"},{text:"Nutrition",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/nutrition.json"},{text:"Facebook",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/facebook.json"},{text:"Heap",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/heap.json"},{text:"Accelerometer",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/accelerometer.json"},{text:"Turtle",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/turtle.json"},{text:"Gmap",url:"https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/gmap.json"}],button:null}],Zr={path:"assets/TryNowImages/turtleMockup.png"},ei=()=>e.jsxs("div",{children:[e.jsx(A,{}),e.jsxs("main",{className:"container mx-auto px-4 sm:px-6 md:px-8 py-6",children:[e.jsx(a.div,{className:"absolute top-[10vh] left-[5vw] sm:left-[35vw] z-[-1] pointer-events-none",variants:J,initial:"initial",animate:"animate",children:e.jsx("img",{src:"assets/FloatingSVGs/turtle-blocks-1.svg",alt:"Turtle Blocks 1",className:"w-[clamp(100px,10vw,180px)]"})}),e.jsx(a.div,{className:"absolute top-[60vh] right-[5vw] sm:right-[50vw] z-[-1] pointer-events-none",variants:J,initial:"initial",animate:"animate",children:e.jsx("img",{src:"assets/FloatingSVGs/turtle-blocks-2.svg",alt:"Turtle Blocks 2",className:"w-[clamp(80px,9vw,160px)]"})}),e.jsx(le,{data:Xr}),e.jsx("p",{className:"w-[80%] mx-auto flex justify-center font-bold",children:"Note: Turtle Blocks JS closely parallels the Python version of Turtle Blocks, the version included in the Sugar distribution. Sugar users probably want to use Turtle Blocks rather than Turtle Blocks JS."}),e.jsx(a.img,{src:Zr.path,alt:"TurtleMockup",variants:Oe,initial:"initial",animate:"animate",className:"w-[80%] mx-auto"}),Qr.map((s,i)=>e.jsx(he,{title:s.title,content:s.content,button:s.button,links:s.links},i))]}),e.jsx(M,{})]}),Ne=({data:s})=>e.jsx("section",{className:"w-[90%] mx-auto py-6 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6",children:s.map((i,r)=>e.jsxs(a.div,{className:"bg-white shadow-lg rounded-xl p-6 flex flex-col items-center text-center border border-blue-500",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},variants:We.card,custom:r,whileHover:"hover",children:[e.jsx(a.div,{className:"w-24 h-24 bg-yellow-300 flex items-center justify-center rounded-full",whileHover:"hover",variants:We.logoContainer,children:e.jsx("img",{src:i.logo,alt:i.title,className:"w-12 h-12"})}),e.jsx("h3",{className:"text-xl font-bold text-blue-600 mt-4",children:i.title}),e.jsx("hr",{className:"w-full my-3 border-gray-300"}),e.jsx("ul",{className:"text-gray-600 text-sm text-left list-disc list-inside",children:i.description.map((o,t)=>e.jsx("li",{children:o},t))}),i.buttons&&e.jsx("div",{className:"mt-4 flex flex-wrap gap-2 justify-center",children:i.buttons.map((o,t)=>e.jsx(a.a,{href:o.link,target:"_blank",rel:"noopener noreferrer",className:"px-4 py-2 bg-blue-600 text-white font-bold rounded-full shadow-md hover:bg-blue-700 transition duration-200",whileHover:"hover",whileTap:"tap",variants:We.button,children:o.text},t))})]},r))}),ti=[{logo:"assets/TryMoreSvgs/web.svg",title:"Web",description:["Try Sugarizer directly from your browser.","A great way to get a taste of sugar!","No installation needed.","Works on desktop, laptop, and mobile devices.","Works on any operating system (Windows, Mac, GNU/Linux, etc.)"],buttons:[{text:"Try Sugarizer in your Browser now",link:"https://try.sugarizer.org/"}]},{logo:"assets/TryMoreSvgs/android.svg",title:"Mobile (Android)",description:["Try Sugarizer on your android tablet of phone.","Available in Google Play and F-Droid for Android users.","Utilizes your device's touch capabilities.","Most functionality works both online and offline.","Android devices can be an economical choice for bringing Sugar to your school."],buttons:[{text:"Install Sugarizer from Google Play",link:"https://play.google.com/store/apps/details?id=org.olpc_france.sugarizer&pli=1"},{text:"Install Sugarizer from F-Droid",link:"https://f-droid.org/packages/org.olpc_france.sugarizer/"}]},{logo:"assets/TryMoreSvgs/ios.svg",title:"Mobile (iOS)",description:["Try Sugarizer on your android tablet of phone.","Available in the App store for iOS users.","Utilizes your device's touch capabilities.","Most functionality works both online and offline."],buttons:[{text:"Install Sugarizer from the App Store",link:"https://apps.apple.com/us/app/sugarizer/id978495303"}]},{logo:"assets/TryMoreSvgs/deploy.svg",title:"Deploy",description:["This option is best for sysadmins of schools looking to run their own Sugarizer Learning Platform.","An entire server-side stack is available for deployment.","Comes with tools for administrators and teachers.","Comes with collaboration features for students to work together.","A great choice for schools who want to use Sugar comprehensively."],buttons:[{text:"Learn more about Sugarizer Server",link:"https://github.com/llaske/sugarizer-server"}]},{logo:"assets/TryMoreSvgs/windows.svg",title:"Windows",description:["Run Sugar on your Windows machine.","Get a taste of Sugar with Sugarizer on your Windows laptop or desktop.","Comes with the complete set of applications available on other platforms.","Installs within Windows; no boot necessary."],buttons:[{text:"Download Sugarizer for Windows",link:"https://sugarizer.org/download/Sugarizer-Setup-1.8.0.exe"}]},{logo:"assets/TryMoreSvgs/mac.svg",title:"MacOS",description:["Run Sugarizer on your Apple desktop or laptop.","Get a taste of Sugar with Sugarizer on your MacOS laptop or desktop.","Comes with the complete set of applications available on other platforms.","Installs within MacOS; no boot necessary."],buttons:[{text:"Download Sugarizer for MacOS",link:"https://sugarizer.org/download/Sugarizer-1.8.0.dmg"}]},{logo:"assets/TryMoreSvgs/linux.svg",title:"GNU- Linux",description:["Run Sugarizer on your GNU/Linux desktop or laptop.","Get a taste of Sugar with Sugarizer on your GNU/Linux laptop or desktop.","Comes with the complete set of applications available on other platforms.","Experience the Sugar differently from its 'classic' Desktop Environment with Sugarizer.","Installs within your current distribution as a Debian file or AppImage."],buttons:[{text:"Download Sugarizer Debian file",link:"https://sugarizer.org/download/Sugarizer_1.8.0_amd64.deb"},{text:"Download Sugarizer AppImage file",link:"https://sugarizer.org/download/Sugarizer-1.8.0.AppImage"}]}],si={title:"Sugarizer",subtitle:"is Multi-Platform",quote:"“Debugging is one of the most powerful educational ideas of the 21st century.” — Cynthia Solomon",description:"Sugarizer makes the Sugar Learning Platform and its activities available on web, mobile, Windows, and MacOS.",images:[{src:"assets/TryNowImages/sugarizer.png",alt:"Sugarizer Example"}]},ai={path:"assets/TryNowImages/sugarizerMockup.png"},ri=()=>e.jsxs("div",{children:[e.jsx(A,{}),e.jsxs("main",{className:"container mx-auto px-4 sm:px-6 md:px-8 py-6",children:[e.jsx(le,{data:si}),e.jsx(a.div,{className:"absolute top-[28vh] left-[5vw] sm:left-[30vw] z-[-1] pointer-events-none",variants:J,initial:"initial",animate:"animate",children:e.jsx("img",{src:"assets/FloatingSVGs/sugarizer-1.svg",alt:"Sugarizer 1",className:"w-[clamp(100px,10vw,180px)]"})}),e.jsx(a.img,{src:ai.path,alt:"SugarizerMockup",variants:Oe,initial:"initial",animate:"animate",className:"w-[80%] mx-auto"}),e.jsx("h2",{className:"text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mt-10",children:"Try it now!"}),e.jsx(Ne,{data:ti})]}),e.jsx(M,{})]}),ii={title:"Boot SOAS",subtitle:"Sugar On A Stick",quote:"“Through Sugar, we strive to provide every child with the opportunity to learn learning within a context that will allow them both to engage in an on-going critical dialog with others and to develop independent means towards their personal goals.” — Walter Bender",description:"Learn how to boot Sugar Labs OS on your computer. Follow our step-by-step guide to get started easily.",images:[{src:"assets/TryNowImages/step7.png",alt:"Boot SOAS step 7"}]},Ot=[{step:1,title:"Sugar On a Stick",description:"To boot Sugar Labs OS on your computer, you will need a bootable Sugar on Stick setup already. To see how to set it up, visit the wiki.",links:[{text:"wiki",url:"https://wiki.sugarlabs.org/go/Sugar_on_a_Stick/Installation"}],image:"assets/TryNowImages/step1.jpg"},{step:2,title:"Insert the USB Drive",description:"Plug the prepared Sugar on a Stick USB drive into an available USB port on your computer.",image:"assets/TryNowImages/step2.jpg"},{step:3,title:"Access Advanced Boot Options (Windows)",description:"On Windows systems, access the advanced boot options by holding the 'Shift' key while clicking 'Restart.' This will bring you to the advanced boot menu.",image:"assets/TryNowImages/step3.jpg"},{step:4,title:"Choose to Boot from USB (Windows)",description:"In the advanced boot menu, select 'Use a Device' to proceed with booting from the USB drive.",image:"assets/TryNowImages/step4.jpg"},{step:5,title:" Select the USB Drive (Windows)",description:"Choose your USB drive from the list of devices to boot into the Sugar OS.",image:"assets/TryNowImages/step5.jpg"},{step:6,title:"Traditional Boot Method (Non-Windows Systems)",description:"For non-Windows computers:Power on your computer and immediately press the appropriate key (commonly F9, F12, or Esc) repeatedly to access the boot menu or BIOS settings. In the boot menu, select your USB drive, often identified by its brand or model name, and press 'Enter' to boot into Sugar.",image:"assets/TryNowImages/step6.jpg"},{step:7,title:"Enjoy Sugar on a Stick",description:"After selecting the USB drive, your computer should boot into the Sugar OS interface. If you encounter any issues during the boot process, seek assistance in the Sugar Labs Matrix room. For detailed instructions and additional resources, visit the Sugar Labs Booting SoaS page.",image:"assets/TryNowImages/step7.png",links:[{text:"Matrix room",url:"https://matrix.to/#/#sugar:matrix.org"}]}],oi={path:"assets/TryNowImages/boatsoasMockup.png"},ni=()=>{const[s,i]=c.useState(0);return e.jsxs("section",{className:"w-[90%] mx-auto py-8",children:[e.jsx("h2",{className:"text-3xl font-bold text-center text-black mb-6",children:"Steps to Boot Sugar on a Stick"}),e.jsx("div",{className:"relative w-full sm:w-[80%] md:w-[70%] lg:w-[60%] mx-auto",children:e.jsx(De.Carousel,{selectedItem:s,onChange:r=>i(r),showArrows:!1,showThumbs:!1,showStatus:!1,showIndicators:!0,useKeyboardArrows:!0,infiniteLoop:!0,children:Ot.map((r,o)=>e.jsxs("div",{className:"relative text-center",children:[e.jsxs("div",{className:"text-lg font-semibold text-gray-600",children:["Step ",o+1]}),e.jsx("h3",{className:"text-2xl font-semibold text-black mt-1",children:r.title}),e.jsx("p",{className:"text-gray-700 mt-2",dangerouslySetInnerHTML:{__html:rt.sanitize(ct(r.description,r.links))}}),e.jsxs("div",{className:"relative group mx-auto mt-4 rounded-lg shadow-lg overflow-hidden",children:[e.jsx("img",{src:r.image,alt:r.title,className:"w-full h-auto rounded-lg"}),o>0&&e.jsx("div",{className:"absolute left-0 top-0 h-full w-1/4 bg-gradient-to-r from-black/30 to-transparent opacity-0 group-hover:opacity-100 transition-all duration-300 cursor-pointer z-10",onClick:()=>i(s-1),children:e.jsx("div",{className:"absolute left-2 top-1/2 transform -translate-y-1/2 w-0 h-0 border-t-8 border-b-8 border-r-8 border-transparent border-r-white"})}),o<Ot.length-1&&e.jsx("div",{className:"absolute right-0 top-0 h-full w-1/4 bg-gradient-to-l from-black/30 to-transparent opacity-0 group-hover:opacity-100 transition-all duration-300 cursor-pointer z-10",onClick:()=>i(s+1),children:e.jsx("div",{className:"absolute right-2 top-1/2 transform -translate-y-1/2 w-0 h-0 border-t-8 border-b-8 border-l-8 border-transparent border-l-white"})})]})]},o))})})]})},li=()=>e.jsxs("div",{children:[e.jsx(A,{}),e.jsxs("main",{className:"container mx-auto px-4 sm:px-6 md:px-8 py-6",children:[e.jsx(le,{data:ii}),e.jsx(a.img,{src:oi.path,alt:"BootableSoasMockup",variants:Oe,initial:"initial",animate:"animate",className:"w-[80%] mx-auto"}),e.jsx(ni,{}),e.jsx(a.div,{children:e.jsxs("p",{className:"justify-self-center mt-4 text-2xl text-gray-700",children:["Cut to the chase and get your pre-installed Sugar on a Stick"," ",e.jsx("a",{className:"text-blue-700 hover:underline font-semibold",href:"/Products",children:"now!"})]})})]}),e.jsx(M,{})]}),ci={title:"Trisquel",subtitle:"Sugar in total freedom",quote:"“Sugar is a free software platform that is designed for children for learning. Our goal is to raise a generation of critical thinkers and problem-solvers by establishing a culture of independent thinking and learning.” — Walter Bender, Sugar Labs founder",description:"Trisquel GNU/Linux is a fully free operating system (OS) for homes, businesses, and schools, which receives reliable support for Sugar Desktop. It's a great choice for booting or installing Sugar on any computer.",images:[{src:"assets/TryNowImages/trisquel.png",alt:"Trisquel Sugar Blocks 1"},{src:"assets/TryNowImages/trisquel2.png",alt:"Trisquel Turtle Blocks 2"}]},di=[{logo:"assets/TryMoreSvgs/trisquel-desktop.svg",title:"Download an ISO with Sugar Desktop",description:["Great if you have a laptop or desktop you can dedicate for this purpose.","Gratis and free: Trisquel asks for a donation, but does not require payment.","Respect for privacy: Your data is safely stored locally on your computer.","Ad-free and simple: Zero distractions, so your child can stay focused."],buttons:[{text:"Download: Trisquel Sugar TOAST",link:"https://trisquel.info/en/download"}]},{logo:"assets/TryMoreSvgs/trisquel-community.svg",title:"Get community support for Trisquel",description:["There is no paid support for Trisquel. Go to the community forum for assistance.","Multi-lingual: Forums are supported in English, Spanish, French, Italian, Galego, and German."],buttons:[{text:"Explore community forums",link:"https://trisquel.info/en/forum"}]},{logo:"assets/TryMoreSvgs/trisquel-documentation.svg",title:"Read the documentation",description:["Learn more about what makes Trisquel different.","Read about Trisquel’s commitment to accessibility.","Read about all the different ways that you can get community help for Trisquel.","Read about how you can get involved."],buttons:[{text:"Explore Sugar Labs’s documentation",link:"https://wiki.sugarlabs.org/go/Trisquel_On_A_Sugar_Toast"}]}],mi=[{title:"Trisquel is fully free 'as in freedom'",content:"What makes Trisquel different from other OSes like Windows and iOS is it’s fully free as in freedom, including the freedom to study the source code. The Trisquel maintainers have given reliable support for Sugar, which is another reason that we recommend it as a great option for those of you interested in booting the Sugar Learning Environment (aka Sugar Desktop) from a live USB or installing onto your computer.",button:""}],ui=()=>e.jsxs("div",{children:[e.jsx(A,{}),e.jsxs("main",{className:"container mx-auto px-4 sm:px-6 md:px-8 py-6",children:[e.jsx(le,{data:ci}),mi.map((s,i)=>e.jsx(he,{title:s.title,content:s.content,button:s.button},i)),e.jsx("h2",{className:"text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mt-10",children:"Learn and Try!"}),e.jsx(Ne,{data:di})]}),e.jsx(M,{})]}),hi={title:"Raspberry-Pi",subtitle:"Sugar on RaspberryPi",quote:"“Programming should be on every child’s low shelf, within reach for frequent use.” — Walter Bender, Sugar Labs founder",description:"Raspberry Pi are a series of small, low cost, low power computers. The Sugar Desktop Environment can be run on a Raspberry Pi. You will need a display, keyboard, and a mouse.",images:[{src:"assets/TryNowImages/raspberry.jpg",alt:"RaspberryPi 1"}]},gi=[{title:"Recommendation",content:"As of August 2017, the best way to experience the Sugar learning platform on a Raspberry Pi (RPi) is by using Sugar on a Stick (SoaS), a portable version of Sugar that runs from a USB drive. SoaS offers a rich collection of educational activities, making it ideal for learners, and it benefits from regular security updates to ensure a safe and stable environment. Designed as a spin of the Fedora operating system, SoaS combines the flexibility of Fedora with the educational focus of Sugar. For setup instructions, refer to the SoaS/RPi documentation, which guides users through the process of downloading, installing, and running it on a Raspberry Pi.",button:"",links:[{text:"Sugar on a Stick/Raspberry Pi",url:"https://github.com/sugarlabs/RPi-Docs/blob/main/src/installation.md"}]},{title:"Developers",content:"Developers may focus on Fedora or Debian when setting up a development environment for Sugar on Raspberry Pi, because Sugar development on generic computers is focused on those operating systems.",button:"",links:[{text:"Fedora",url:"https://github.com/sugarlabs/sugar/blob/master/docs/fedora.md"},{text:"Debian",url:"https://github.com/sugarlabs/sugar/blob/master/docs/debian.md"}]}],xi=[{logo:"assets/TryMoreSvgs/trisquel-desktop.svg",title:"using Raspbian",description:["Raspbian (now known as Raspberry Pi OS) is the most widely used OS for Raspberry Pi and is based on Debian.","You can install the Sugar learning environment using package managers or custom scripts.","It’s lightweight, actively maintained, and optimized for Raspberry Pi hardware.","Best suited for users already familiar with Raspberry Pi setups."],buttons:[{text:"Read Raspbian installation guide",link:"https://wiki.sugarlabs.org/go/Raspbian"}]},{logo:"assets/TryMoreSvgs/fedora.svg",title:"using Fedora",description:["Fedora offers a reliable and cutting-edge platform to run Sugar on various hardware, including Raspberry Pi.","Sugar on a Stick (SoaS) is a Fedora-based spin tailored for educational purposes.","You can run Sugar live from a USB stick or install it on the Pi directly with some configuration.","Suitable for users seeking a polished Linux experience with SELinux and Wayland support."],buttons:[{text:"View Fedora instructions",link:"https://github.com/sugarlabs/sugar/blob/master/docs/fedora.md"}]},{logo:"assets/TryMoreSvgs/debian.svg",title:"using Debian",description:["Debian is the upstream source of Raspbian and offers a very stable environment for Sugar.","You can install Sugar via APT repositories or build it from source for more customization.","Recommended for developers and advanced users familiar with Debian packaging and systems.","You gain fine-grained control over packages and system updates."],buttons:[{text:"Read Debian instructions",link:"https://github.com/sugarlabs/sugar/blob/master/docs/debian.md"}]},{logo:"assets/TryMoreSvgs/ubuntu.svg",title:"using Ubuntu",description:["Ubuntu is a user-friendly Linux distribution and supports running Sugar with a few extra steps.","You can install Sugar directly via terminal or explore Ubuntu derivatives for a lighter setup.","Popular among new users due to its graphical interface and large support community.","Ideal if you’re already using Ubuntu on other machines and want consistency."],buttons:[{text:"View Ubuntu setup guide",link:"https://github.com/sugarlabs/sugar/blob/master/docs/ubuntu.md"}]}],pi=()=>e.jsxs("div",{children:[e.jsx(A,{}),e.jsxs("main",{className:"container mx-auto px-4 sm:px-6 md:px-8 py-6",children:[e.jsx(le,{data:hi}),gi.map((s,i)=>e.jsx(he,{title:s.title,content:s.content,button:s.button,links:s.links},i)),e.jsx(Ne,{data:xi})]}),e.jsx(M,{})]}),bi=({members:s})=>e.jsxs(a.section,{className:"w-[90%] mx-auto text-center py-12",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},variants:se.section,children:[e.jsx(a.h1,{className:"text-5xl font-[Caveat] font-bold",variants:se.heading,children:"Music Blocks Offline Edition"}),e.jsxs(a.h2,{className:"text-4xl font-[Caveat] font-bold mt-2",variants:se.heading,children:["and ",e.jsx("br",{})," Curriculum Development Team"]}),e.jsx(a.hr,{className:"w-24 border-t-2 border-gray-500 mx-auto mt-4",variants:se.heading}),e.jsx(a.div,{className:"grid md:grid-cols-2 gap-10 mt-12 bg-gray-100 p-10 rounded-lg",initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},variants:se.section,children:s.map((i,r)=>e.jsxs(a.div,{className:"flex flex-col md:flex-row items-center bg-white shadow-lg rounded-lg p-6",variants:se.memberCard,children:[e.jsx(a.img,{src:i.image,alt:i.name,className:"w-32 h-32 rounded-full object-cover border-4 border-gray-300",variants:se.memberImage}),e.jsxs("div",{className:"md:ml-6 text-left mt-4 md:mt-0",children:[e.jsx("h3",{className:"text-lg font-bold px-3 py-1 rounded-lg inline-block",style:{backgroundColor:i.bgColor},children:i.name}),e.jsx("p",{className:"text-gray-700 mt-2",children:i.description})]})]},r))})]}),Re=({number:s,title:i,description:r,image:o,borderColor:t,link:l})=>e.jsxs(a.a,{href:l,target:"_blank",rel:"noopener noreferrer",className:"relative flex flex-col items-center text-center p-6 rounded-2xl shadow-md cursor-pointer no-underline",style:{border:`2px solid ${t}`},initial:"hidden",whileInView:"visible",viewport:{once:!0,amount:.2},variants:Ge.card,whileHover:"hover",children:[e.jsx(a.div,{className:"absolute -top-6 w-12 h-12 flex items-center justify-center rounded-full text-white text-xl font-bold",style:{backgroundColor:t},variants:Ge.numberCircle,children:s}),e.jsx("h3",{className:"text-lg font-semibold mt-6",children:i}),e.jsx("p",{className:"text-gray-700 mt-2",children:r}),o&&e.jsx(a.img,{src:o,alt:i,className:"w-full h-auto mt-4 rounded-lg",variants:Ge.image})]}),fi={title:"Music Blocks",subtitle:"A Musical Microworld",quote:"“All musicians are subconsciously mathematicians” – Thelonious Monk, jazz pianist and composer",description:"Music Blocks is a collection of manipulative tools for exploring fundamental musical concepts in an integrative and fun way.",images:[{src:"assets/TryNowImages/musicBlocks1.png",alt:"Music Blocks Example 1"},{src:"assets/TryNowImages/musicBlocks2.png",alt:"Music Blocks Example 2"},{src:"assets/TryNowImages/musicBlocks3.png",alt:"Music Blocks Example 3"},{src:"assets/TryNowImages/musicBlocks4.png",alt:"Music Blocks Example 4"}]},wi=[{title:"Using Music Blocks",content:"Music Blocks is designed to run in the browser. It is derived from Turtle Blocks JS which can be found here. You can run the software locally from the index.html file, from the GitHub repository, or by setting up a local server. If you want to run Music Blocks offline, download this repo and point your browser to the index.html file found in the musicblocks directory on your local file system. See Using Music Blocks and Music Blocks Guide",button:"Try Music Blocks Now",links:[{text:"here",url:"https://github.com/sugarlabs/turtleblocksjs"},{text:"Github",url:"https://github.com/sugarlabs/musicblocks/"},{text:"Using Music Blocks",url:"http://github.com/sugarlabs/musicblocks/tree/master/documentation"},{text:"Music Blocks Guide",url:"http://github.com/sugarlabs/musicblocks/tree/master/guide"}]},{title:"Credits",content:`Music Blocks is a fork of TurtleArtJS created by Walter Bender. (Turtle Blocks JS has many contributors). + Devin Ulibarri has contributed functional and user-interface designs. Many of his contributions were inspired by the music education ideas, representations and practices (e.g. aspects of matrix, musical cups) developed and published by Dr. Lawrence Scripp with whom Devin studied at New England Conservatory and for whom he worked at Affron Scripp & Associates, LLC. + Much of the initial coding of the fork from Turtle Blocks was done by Yash Khandelwal as part of Google Summer of Code (GSoC) 2015. Hemant Kasat contributed to additional widgets as part of GSoC 2016. Additional contributions are being made by Tayba Wasim, Dinuka Tharangi Jayaweera, Prachi Agrawal, Cristina Del Puerto, and Hrishi Patel as part of GSoC 2017. During GSoC 2018, Riya Lohia developed a Temperament Widget. Ritwik Abhishek added a keyboard widget and a pitch-tracking widget. + Many students contributed to the project as part of Google Code-in (2015–16, 2016–17, and 2017–2018). Sam Parkinson built the Planet during GCI 2016–17. Euan Ong redesigned the Planet code as a series of GCI tasks in 2017–18.`,button:null,links:[{text:"contributors",url:"https://github.com/sugarlabs/turtleblocksjs/graphs/contributors"}]}],vi={path:"assets/TryNowImages/musicMockup.png"},yi={path:"assets/TryNowImages/mbText.png"},ji=[{title:"Found a Bug?",content:"Report it in the issues section of THIS repository.",links:[{text:"issues",url:"https://github.com/sugarlabs/musicblocks/issues"}],button:null}],Ni=[{logo:"assets/TryNowImages/mbLogoCard1.png",title:"Music Blocks Online",description:["Children can learn programming from scratch and have fun creating music and videos by combining blocks that control instruments, rhythms, and changing pitch values."],buttons:[{text:"Trying out Music Blocks",link:"https://musicblocks.sugarlabs.org/",target:"_blank"}]},{logo:"assets/TryNowImages/mbLogoCard2.png",title:"Videos to learn how to use Music Blocks",description:["You can learn the basics of Music Blocks through videos. We will explain what you can do with the software, how to start using it, how to program, and more."],buttons:[{text:"Go to Youtube channel",link:"https://www.youtube.com/channel/UCdXacR2zOXff4XCKRLTSnRw",target:"_blank"}]},{logo:"assets/TryNowImages/mbLogoCard3.png",title:"Videos that teach you how to create works using Music Blocks",description:["This article explains how to create music and video works while programming using Music Blocks. Feel free to create your own original works."],buttons:[{text:"Go to Youtube channel",link:"https://www.youtube.com/channel/UCdXacR2zOXff4XCKRLTSnRw",target:"_blank"}]},{logo:"assets/TryNowImages/mbLogoCard4.png",title:"Music Blocks Challenge Print",description:["This is a quiz-style printout that teaches you about the functions of Music Blocks and how to create works. Click the link below to download the PDF file."],buttons:[{text:"Download PDF file",link:"https://gakken-steam.jp/music_blocks/common/pdf/challengeprint.zip",target:"_blank"}]}],ki=[{name:"WALTER BENDER",role:"Developer of Music Blocks",description:"Developer of Music Blocks. Former director of the MIT Media Lab. Founder of the OLPC (One Laptop Per Child) project, which provides $100 computers to children in developing countries. Founder of the nonprofit organization Sugar Labs.",image:"assets/TryNowImages/walter.png",bgColor:"#B0D0FF"},{name:"DEVIN ULIBARRI",role:"CEO of Remake Music LLC",description:"Developer of Music Blocks. CEO of Remake Music LLC. Head of Music + Code Lead Teaching Artist Training at MAP Family Learning Center.",image:"assets/TryNowImages/devin.png",bgColor:"#FFB3C6"}],_i=[{number:"1",title:"You can create music through programming!",description:"Rhythms and melodies can be created intuitively, so anyone can easily create original music.",image:"assets/TryNowImages/mbNumberedCard1.png",borderColor:"#FFED51"},{number:"2",title:"You can study math!",description:"Since musical elements such as 'note length' and 'performance speed' are controlled numerically, students will develop mathematical literacy.",image:"assets/TryNowImages/mbNumberedCard2.png",borderColor:"#FFED51"},{number:"3",title:"You can show your work all over the world!",description:"You can publish your work on a dedicated cloud. Download the work you like and collaborate with friends around the world.",image:"assets/TryNowImages/mbNumberedCard3.png",borderColor:"#FFED51"}],Si=[{number:"1",title:"You can create music through programming!",description:"Rhythms and melodies can be created intuitively, so anyone can easily create original music.",image:"",borderColor:"#F8251F"},{number:"2",title:"You can study math!",description:"Since musical elements such as 'note length' and 'performance speed' are controlled numerically, students will develop mathematical literacy.",image:"",borderColor:"#F8251F"},{number:"3",title:"You can show your work all over the world!",description:"You can publish your work on a dedicated cloud. Download the work you like and collaborate with friends around the world.",image:"",borderColor:"#F8251F"}],Li=()=>e.jsxs("div",{className:"relative",children:[e.jsx(a.div,{className:"absolute top-[10vh] left-[5vw] sm:left-[30vw] z-[-1] pointer-events-none",variants:J,initial:"initial",animate:"animate",children:e.jsx("img",{src:"assets/FloatingSVGs/music-block-1.svg",alt:"Music Block 1",className:"w-[clamp(100px,10vw,180px)]"})}),e.jsx(a.div,{className:"absolute top-[65vh] right-[5vw] sm:right-[50vw] z-[-1] pointer-events-none",variants:J,initial:"initial",animate:"animate",children:e.jsx("img",{src:"assets/FloatingSVGs/music-block-2.svg",alt:"Music Block 2",className:"w-[clamp(80px,9vw,160px)]"})}),e.jsx(a.div,{className:"absolute top-[10vh] right-[10vw] sm:right-[15vw] z-[-1] pointer-events-none",variants:J,initial:"initial",animate:"animate",children:e.jsx("img",{src:"assets/FloatingSVGs/music-block-3.svg",alt:"Music Block 3",className:"w-[clamp(90px,10vw,170px)]"})}),e.jsx(A,{}),e.jsxs("main",{className:"container mx-auto px-4 sm:px-6 md:px-8 py-6",children:[e.jsx(le,{data:fi}),e.jsxs("p",{className:"flex justify-center",children:[e.jsx("span",{className:"text-[#436EA6]",children:"Learn music"})," ",e.jsx("span",{children:","})," ",e.jsx("span",{className:"text-[#FEC613]",children:"math"})," ",e.jsx("span",{children:", and"})," ",e.jsx("span",{className:"text-[#AB486A]",children:"programming"})," together."]}),e.jsx("div",{className:"w-[80%] mx-auto flex justify-center",children:e.jsx("img",{src:yi.path,alt:"Music Blocks",className:"w-[60%] max-w-xs"})}),e.jsx("div",{className:"w-[80%] mx-auto flex justify-center",children:e.jsx(a.img,{src:vi.path,alt:"MusicBlocksMockup",variants:Oe,initial:"initial",animate:"animate",className:"w-[80%] mx-auto"})}),e.jsx("p",{className:"w-[80%] mx-auto flex justify-center",children:"Music Blocks is an American-made educational software that teaches music, math, and programming all at once. By combining blocks that indicate instruments and rhythms, and by changing the pitch values, children can create music from scratch, even if they are not familiar with music, are not good at math, or are new to programming. It is a groundbreaking software that allows children to learn these things."}),wi.map((s,i)=>e.jsx(he,{title:s.title,content:s.content,button:s.button,links:s.links},i)),e.jsxs("h2",{className:"text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mt-10",children:["What can you do with"," ",e.jsx("span",{className:"text-[#68A6F7]",children:"Music Blocks"}),"??"]}),e.jsx(Ne,{data:Ni}),e.jsxs("h2",{className:"text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mt-10",children:["How ",e.jsx("span",{className:"text-[#68A6F7]",children:"Music Blocks"})," help your child's education??"]}),e.jsx("div",{className:"grid md:grid-cols-3 gap-8 mt-12",children:_i.map((s,i)=>e.jsx(Re,{number:s.number,title:s.title,description:s.description,image:s.image,borderColor:s.borderColor},i))}),e.jsx("div",{className:"grid md:grid-cols-3 gap-8 mt-12",children:Si.map((s,i)=>e.jsx(Re,{number:s.number,title:s.title,description:s.description,image:s.image,borderColor:s.borderColor},i))}),e.jsx("div",{children:e.jsx(bi,{members:ki})}),ji.map((s,i)=>e.jsx(he,{title:s.title,content:s.content,button:s.button,links:s.links},i))]}),e.jsx(M,{})]}),Ci={title:"Sugar on Flatpak",subtitle:"Simplified Learning Platform Distribution",quote:"“The context of human development is always a culture, not an isolated technology.” – Seymour Papert, computer scientist and educator",description:"Flatpak enables easy installation and distribution of Sugar Labs educational activities across different Linux platforms.",images:[{src:"assets/TryNowImages/flathub1.png",alt:"Sugar Labs Activities Installation"}]},Ti=[{title:"Flatpak and Sugar",content:"Flatpak provides a streamlined way to package and distribute Sugar Labs educational activities. It ensures that learning tools can be easily installed on various Linux distributions, making education more accessible.",button:"Explore Sugar Labs Activities",buttonLink:"https://flathub.org/apps/search?q=sugar%20labs"}],Ii=[{logo:"assets/Cards/Flathub.png",title:"Educational Activities",description:["Access 34+ educational activities including Paint, Abacus, Music Keyboard, and Story"],buttons:[{text:"Browse Activities",link:"https://flathub.org/apps/collection/developer/Sugar%20Labs%20Community/1",target:"_blank"}]},{logo:"assets/TryNowImages/fpLogoCard2.png",title:"Easy Installation",description:["Install Sugar activities with just a few commands on any Linux distribution"],buttons:[{text:"Get Started",link:"https://flatpak.org/setup/",target:"_blank"}]},{logo:"assets/TryNowImages/fpLogoCard3.png",title:"Cross-Platform Support",description:["Compatible with multiple Linux distributions and learning environments"],buttons:[{text:"Explore Platforms",link:"https://flathub.org/setup",target:"_blank"}]}],Ei=[{number:"1",title:"Install Flatpak",description:"Add Flatpak repository to your Linux system",borderColor:"#68A6F7",link:"https://flatpak.org/setup/"},{number:"2",title:"Find Sugar Activities",description:"Browse the collection of 34+ educational applications",borderColor:"#68A6F7",link:"https://flathub.org/apps/collection/developer/Sugar%20Labs%20Community/1"}],Ai=[{number:"3",title:"Install Activities",description:"Download educational tools like Paint, Abacus, and Music Keyboard",borderColor:"#F8251F"},{number:"4",title:"Start Learning",description:"Explore interactive educational experiences for all ages",borderColor:"#F8251F"}],Mi=()=>e.jsxs("div",{className:"relative",children:[e.jsx(a.div,{className:"absolute top-[10vh] md:top-[15vh] left-[5vw] md:left-[35vw] z-[-1] pointer-events-none",variants:J,initial:"initial",animate:"animate",children:e.jsx("img",{src:"assets/FloatingSVGs/flathub-1.svg",alt:"Flathub SVG 1",className:"w-[clamp(100px,10vw,150px)]"})}),e.jsx(a.div,{className:"absolute top-[10vh] sm:top-[65vh] right-[5vw] xs:right-[50vw] z-[-1] pointer-events-none",variants:J,initial:"initial",animate:"animate",children:e.jsx("img",{src:"assets/FloatingSVGs/flathub-2.svg",alt:"Flathub SVG 2",className:"w-[clamp(40px,9vw,16px)]"})}),e.jsx(A,{}),e.jsxs("main",{className:"container mx-auto px-4 sm:px-6 md:px-8 py-6",children:[e.jsx(le,{data:Ci}),Ti.map((s,i)=>e.jsx(he,{title:s.title,content:s.content,button:s.button,buttonLink:s.buttonLink},i)),e.jsxs("h2",{className:"text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mt-10",children:["What can you do with ",e.jsx("span",{className:"text-[#68A6F7]",children:"Flatpak"}),"?"]}),e.jsx("div",{className:"flex justify-center",children:e.jsx(Ne,{data:Ii})}),e.jsxs("div",{className:"flex flex-col md:flex-row justify-center space-y-4 md:space-y-0 md:space-x-4 my-8",children:[e.jsxs("div",{className:"w-full md:w-1/2",children:[e.jsx("h2",{className:"text-2xl font-semibold mb-4 text-center font-Caveat",children:"Getting Started"}),e.jsx("div",{className:"grid grid-cols-1 gap-4 mt-6 p-4",children:Ei.map((s,i)=>e.jsx(Re,{number:s.number,title:s.title,description:s.description,borderColor:s.borderColor,link:s.link},i))})]}),e.jsxs("div",{className:"w-full md:w-1/2",children:[e.jsx("h2",{className:"text-2xl font-semibold mb-4 text-center font-[Caveat]",children:"Next Steps"}),e.jsx("div",{className:"grid grid-cols-1 gap-4 mt-6 p-4",children:Ai.map((s,i)=>e.jsx(Re,{number:s.number,title:s.title,description:s.description,borderColor:s.borderColor},i))})]})]}),e.jsxs("div",{className:"my-12 p-6 bg-gray-50 rounded-lg shadow-sm",children:[e.jsxs("h2",{className:"text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mb-6",children:["For ",e.jsx("span",{className:"text-blue-600",children:"Developers"})]}),e.jsxs("div",{className:"max-w-3xl mx-auto",children:[e.jsx("p",{className:"text-lg mb-4",children:"Looking to package and distribute Sugar activities using Flatpak? Our comprehensive guide walks you through the entire process of creating, building, and publishing Flatpak applications."}),e.jsx("div",{className:"flex justify-center mt-6",children:e.jsx("a",{href:"https://github.com/tchx84/sugarapp/blob/master/flatpak-guide.md",target:"_blank",rel:"noopener noreferrer",className:`flex items-center justify-center px-6 py-3 rounded-xl font-semibold + text-white bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 + hover:to-blue-800 transition-all duration-300`,children:e.jsx("span",{className:"mr-2",children:"View Developer Guide"})})})]})]})]}),e.jsx(M,{})]}),Pi=[{id:"organization",title:"Organization",description:"Discussion about our organization's projects, events, and planning.",url:"https://matrix.to/#/#sugar:matrix.org",icon:"building"},{id:"webdev",title:"Web Development",description:"Join our web development community room to discuss web technologies, frameworks, and best practices.",url:"https://matrix.to/#/#sugarlabs-web:matrix.org",icon:"code"},{id:"mbdev",title:"Music Blocks Development",description:"Music Blocks software development discussions and coding challenges.",url:"https://matrix.to/#/#musicblocksdev:matrix.org",icon:"terminal"},{id:"sugarizerdev",title:"Sugarizer Development",description:"Sugarizer software development discussions and coding challenges.",url:"https://matrix.to/#/#sugarizer:matrix.org",icon:"terminal"}],Ri=({step:s,title:i,description:r,icon:o,isLeft:t,link:l})=>e.jsxs(a.div,{variants:z,className:"relative",children:[e.jsxs("div",{className:"md:hidden relative pl-12 pb-10",children:[e.jsx("div",{className:"absolute left-0 top-0 w-8 h-8 rounded-full bg-[#D4B062] flex items-center justify-center z-10",children:e.jsx("span",{className:"text-white font-bold",children:s})}),e.jsx("div",{className:"absolute left-4 top-8 h-full w-[1px] bg-[#D4B062]/30"}),e.jsx("div",{className:"bg-[#D4B062] p-2 rounded-full border-2 border-[#D4B062] text-white mb-3 inline-flex",children:o}),e.jsxs("div",{className:"bg-white p-5 rounded-lg shadow-md",children:[e.jsx("h3",{className:"text-lg font-bold text-magazine-navy mb-2",children:i}),e.jsxs("p",{className:"text-gray-600 text-sm leading-relaxed",children:[r,l&&e.jsxs("a",{href:l.url,target:"_blank",rel:"noopener noreferrer",className:"text-[#D4B062] hover:underline ml-1 inline-flex items-center",children:[l.text," ",e.jsx(He,{className:"h-3 w-3 ml-1"})]})]})]})]}),e.jsx("div",{className:"hidden md:flex flex-row items-center",children:t?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"w-1/2 pr-8 mb-0 text-right",children:e.jsxs("div",{className:"bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300",children:[e.jsx("h3",{className:"text-xl font-bold text-magazine-navy mb-2",children:i}),e.jsxs("p",{className:"text-gray-600 leading-relaxed",children:[r,l&&e.jsxs("a",{href:l.url,target:"_blank",rel:"noopener noreferrer",className:"text-[#D4B062] hover:underline ml-1 inline-flex items-center",children:[l.text," ",e.jsx(He,{className:"h-3 w-3 ml-1"})]})]})]})}),e.jsx("div",{className:"absolute left-1/2 transform -translate-x-1/2 w-8 h-8 rounded-full bg-[#D4B062] flex items-center justify-center z-10",children:e.jsx("span",{className:"text-white font-bold",children:s})}),e.jsx("div",{className:"w-1/2 pl-8 text-left",children:e.jsxs(a.div,{className:"flex items-center",whileHover:{x:5},children:[e.jsx("div",{className:"bg-[#D4B062] p-2 rounded-full border-2 border-[#D4B062] text-white mr-3",children:o}),e.jsx("span",{className:"text-magazine-navy font-bold text-lg",children:i.split(" ")[0]})]})})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"w-1/2 pr-8 mb-0 text-right",children:e.jsxs(a.div,{className:"flex items-center justify-end",whileHover:{x:-5},children:[e.jsx("span",{className:"text-magazine-navy font-bold text-lg mr-3",children:i.split(" ")[0]}),e.jsx("div",{className:"bg-[#D4B062] p-2 rounded-full border-2 border-[#D4B062] text-white",children:o})]})}),e.jsx("div",{className:"absolute left-1/2 transform -translate-x-1/2 w-8 h-8 rounded-full bg-[#D4B062] flex items-center justify-center z-10",children:e.jsx("span",{className:"text-white font-bold",children:s})}),e.jsx("div",{className:"w-1/2 pl-8",children:e.jsxs("div",{className:"bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300",children:[e.jsx("h3",{className:"text-xl font-bold text-magazine-navy mb-2",children:i}),e.jsxs("p",{className:"text-gray-600 leading-relaxed",children:[r,l&&e.jsxs("a",{href:l.url,target:"_blank",rel:"noopener noreferrer",className:"text-[#D4B062] hover:underline ml-1 inline-flex items-center",children:[l.text," ",e.jsx(He,{className:"h-3 w-3 ml-1"})]})]})]})})]})})]}),Di=({link:s,getIcon:i})=>e.jsx(a.div,{variants:Jt,whileHover:"hover",className:"bg-white rounded-xl shadow-md overflow-hidden border border-gray-100 hover:shadow-lg transition-all duration-300 h-full",children:e.jsxs("div",{className:"p-4 sm:p-6 flex flex-col h-full",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[e.jsx("div",{className:"bg-[#D4B062] p-2 sm:p-3 rounded-full text-white flex-shrink-0",children:i(s.icon)}),e.jsx("h3",{className:"font-bold text-lg sm:text-xl",children:s.title})]}),e.jsx("p",{className:"text-gray-600 mb-4 sm:mb-6 leading-relaxed text-sm sm:text-base flex-grow",children:s.description}),e.jsxs(a.a,{href:s.url,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center text-[#D4B062] hover:text-magazine-navy transition-colors font-medium mt-auto",whileHover:{x:5},children:["Join Room ",e.jsx(gt,{className:"ml-2 h-4 w-4"})]})]})},s.id),Fi=()=>{const s=r=>{switch(r){case"code":return e.jsx(it,{className:"h-5 w-5 sm:h-6 sm:w-6"});case"terminal":return e.jsx(jt,{className:"h-5 w-5 sm:h-6 sm:w-6"});case"building":return e.jsx(Ee,{className:"h-5 w-5 sm:h-6 sm:w-6"});case"message":return e.jsx(yt,{className:"h-5 w-5 sm:h-6 sm:w-6"});default:return e.jsx(gt,{className:"h-5 w-5 sm:h-6 sm:w-6"})}},i=[{step:1,title:"Choose a Matrix client",description:"Element is the most popular Matrix client, available on web, desktop, iOS, and Android.",icon:e.jsx(jt,{className:"h-5 w-5"}),isLeft:!0,link:{url:"https://element.io/get-started",text:"element.io"}},{step:2,title:"Create an account",description:"You can create an account on the Matrix.org homeserver or any other public homeserver. You'll need to provide a username and password.",icon:e.jsx(Ee,{className:"h-5 w-5"}),isLeft:!1},{step:3,title:"Join our rooms",description:"Use the links in the section above to join our community rooms. You can also search for rooms within your Matrix client using the room addresses.",icon:e.jsx(yt,{className:"h-5 w-5"}),isLeft:!0},{step:4,title:"Engage with the community",description:"Introduce yourself, ask questions, share your expertise, and become an active part of our growing Matrix community.",icon:e.jsx(it,{className:"h-5 w-5"}),isLeft:!1}];return e.jsxs("div",{className:"min-h-screen flex flex-col font-sans bg-[#FFFEF9]",children:[e.jsx(A,{}),e.jsxs("main",{className:"flex-grow",children:[e.jsxs(a.section,{initial:"hidden",animate:"visible",variants:z,className:"relative py-16 sm:py-20 md:py-28 overflow-hidden bg-gradient-to-b from-black via-gray-800 to-white",children:[e.jsxs("div",{className:"absolute inset-0 z-0 overflow-hidden",children:[e.jsx("div",{className:"absolute inset-0 opacity-10"}),e.jsx("div",{className:"absolute inset-0",style:{backgroundImage:"radial-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1px)",backgroundSize:"20px 20px"}})]}),e.jsx("div",{className:"container mx-auto px-4 md:px-6",children:e.jsxs("div",{className:"flex flex-col items-center text-center z-10 relative",children:[e.jsxs(a.h1,{className:"font-black text-4xl sm:text-5xl md:text-6xl lg:text-7xl mb-4 sm:mb-6 text-white",variants:G,children:["Matrix ",e.jsx("span",{className:"text-[#D4B062]",children:"Chat"})]}),e.jsx(a.div,{className:"w-16 sm:w-24 h-1 bg-[#D4B062] mb-4 sm:mb-6 rounded-full",initial:{width:0},animate:{width:96},transition:{duration:.8,delay:.3}}),e.jsx(a.p,{className:"text-base sm:text-lg md:text-xl mb-8 sm:mb-10 text-gray-300 max-w-2xl leading-relaxed px-4",variants:ve,children:"Connect with our vibrant community through Matrix — an open network for secure, decentralized communication that puts you in control."}),e.jsx(a.a,{href:"#get-started",className:"bg-[#D4B062] hover:bg-white hover:text-black text-black font-medium px-6 sm:px-8 py-2.5 sm:py-3 rounded-full transition-all duration-300 shadow-lg hover:shadow-xl text-sm sm:text-base",whileHover:{scale:1.05},whileTap:{scale:.95},children:"Get Started"})]})})]}),e.jsx(a.section,{initial:"hidden",whileInView:"visible",viewport:{once:!0,margin:"-100px"},variants:P,className:"py-12 sm:py-16 bg-[#FFFEF9]",children:e.jsx("div",{className:"container mx-auto px-4 md:px-6",children:e.jsxs("div",{className:"max-w-3xl mx-auto",children:[e.jsx(a.h2,{className:"text-2xl sm:text-3xl font-bold mb-6 text-magazine-navy border-b-2 border-[#D4B062] pb-2 inline-block",variants:P,children:"What is Matrix?"}),e.jsxs(a.div,{className:"space-y-4 text-base sm:text-lg leading-relaxed",variants:P,children:[e.jsx("p",{children:"Matrix is an open source project that publishes the Matrix open standard for secure, decentralized, real-time communication, and its Apache licensed reference implementations."}),e.jsx("p",{children:"It defines a set of open APIs for decentralized communication, suitable for securely publishing, persisting and subscribing to data over a global open federation of servers with no single point of control."}),e.jsx("p",{children:"Matrix can be used for instant messaging, VoIP/WebRTC signaling, IoT communication, and anywhere you need a standard HTTP API for publishing and subscribing to data while tracking the history and the current state."})]})]})})}),e.jsx(a.section,{initial:"hidden",whileInView:"visible",viewport:{once:!0,margin:"-100px"},variants:H,className:"py-12 sm:py-16 md:py-24 bg-[#FFFEF9]",children:e.jsxs("div",{className:"container mx-auto px-4 md:px-6",children:[e.jsxs(a.div,{className:"text-center mb-8 sm:mb-12",variants:P,children:[e.jsx("h2",{className:"text-2xl sm:text-3xl font-bold mb-3 text-magazine-navy",children:"Join Our Matrix Rooms"}),e.jsx("div",{className:"w-16 h-1 bg-[#D4B062] mx-auto rounded-full"})]}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6 lg:gap-8",children:Pi.map(r=>e.jsx(Di,{link:r,getIcon:s},r.id))})]})}),e.jsx(a.section,{id:"get-started",initial:"hidden",whileInView:"visible",viewport:{once:!0,margin:"-100px"},variants:H,className:"py-12 sm:py-16 bg-[#FFFEF9]",children:e.jsxs("div",{className:"container mx-auto px-4 md:px-6",children:[e.jsxs(a.div,{className:"text-center mb-8 sm:mb-12",variants:P,children:[e.jsx("h2",{className:"text-2xl sm:text-3xl font-bold mb-3 text-magazine-navy",children:"How to Get Started with Matrix"}),e.jsx("div",{className:"w-16 h-1 bg-[#D4B062] mx-auto rounded-full"})]}),e.jsx("div",{className:"max-w-4xl mx-auto",children:e.jsxs("div",{className:"relative",children:[e.jsx(a.div,{className:"absolute left-1/2 transform -translate-x-1/2 w-1 bg-orange-500/70 hidden md:block",variants:Qs,initial:"hidden",whileInView:"visible",viewport:{once:!0},style:{background:"linear-gradient(to bottom, rgba(212,176,98,0.1), rgba(212,176,98,0.7), rgba(212,176,98,0.1))"}}),e.jsx("div",{className:"space-y-8 md:space-y-16",children:i.map((r,o)=>e.jsx(Ri,{step:r.step,title:r.title,description:r.description,icon:r.icon,isLeft:r.isLeft,link:r.link},o))})]})})]})})]}),e.jsx(M,{})]})},Bi=()=>e.jsxs("div",{className:"min-h-screen flex flex-col font-sans bg-[#FFFEF9]",children:[e.jsx(A,{}),e.jsxs("main",{className:"flex-grow",children:[e.jsxs(a.section,{initial:"hidden",animate:"visible",variants:P,className:"relative py-5 md:py-15 overflow-hidden bg-gradient-to-b from-black via-gray-800 to-white",children:[e.jsxs("div",{className:"absolute inset-0 z-0 overflow-hidden",children:[e.jsx("div",{className:"absolute inset-0 opacity-10"}),e.jsx("div",{className:"absolute inset-0",style:{backgroundImage:"radial-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1px)",backgroundSize:"20px 20px"}})]}),e.jsx("div",{className:"container mx-auto px-4 md:px-6",children:e.jsxs("div",{className:"flex flex-col items-center text-center z-10 relative",children:[e.jsx(a.div,{className:"flex items-center justify-center mb-6",variants:W,initial:"hidden",animate:"visible",children:e.jsx("div",{className:"bg-[#D4B062] p-4 rounded-full border-4 border-white/20",children:e.jsx(fs,{className:"h-12 w-12 text-white"})})}),e.jsx(a.h1,{className:"font-black text-5xl md:text-6xl lg:text-7xl mb-6 text-white",variants:V,initial:"hidden",animate:"visible",children:e.jsx("span",{className:"text-[#D4B062]",children:"Page Not Found"})}),e.jsx(a.div,{className:"w-20 h-1 bg-[#D4B062] mb-6",variants:Be,initial:"hidden",animate:"visible"}),e.jsx(a.p,{className:"text-lg md:text-xl mb-10 text-gray-300 max-w-2xl leading-relaxed",variants:P,initial:"hidden",animate:"visible",transition:{delay:.3},children:"Oops! It looks like the page you were looking for doesn't exist or has been moved."}),e.jsx(a.a,{href:"#solutions",className:"bg-[#D4B062] hover:bg-white hover:text-black text-black font-medium px-8 py-3 rounded-full transition-all duration-300 shadow-lg hover:shadow-xl",variants:ne,initial:"hidden",animate:"visible",whileHover:"hover",whileTap:"tap",children:"Find Solutions"})]})})]}),e.jsx(a.section,{initial:"hidden",whileInView:"visible",viewport:{once:!0,margin:"-100px"},variants:P,className:"py-16 bg-[#FFFEF9]",children:e.jsx("div",{className:"container mx-auto px-4 md:px-6 max-w-4xl",children:e.jsx("div",{className:"bg-white rounded-xl shadow-lg overflow-hidden border border-gray-100 p-8",children:e.jsxs("div",{className:"flex flex-col lg:flex-row items-center justify-center",children:[e.jsx(a.div,{className:"w-full lg:w-1/2 flex justify-center mb-8 lg:mb-0",variants:$,transition:{duration:.5},children:e.jsxs("div",{className:"relative w-64 h-64 flex items-center justify-center",children:[[...Array(4)].map((s,i)=>e.jsx(a.div,{className:"absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-[#D4B062]/30",style:{width:`${(i+1)*50}px`,height:`${(i+1)*50}px`},animate:{scale:[1,1.5,1],opacity:[0,.5,0]},transition:{duration:2,delay:i*.5,repeat:1/0}},i)),e.jsx(a.div,{className:"absolute z-10",animate:{y:[0,-10,0],rotate:[0,-2,0]},transition:{duration:3,repeat:1/0,repeatType:"reverse"},children:e.jsxs("div",{className:"relative",children:[e.jsxs("svg",{width:"120",height:"120",viewBox:"0 0 120 120",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("circle",{cx:"60",cy:"60",r:"60",fill:"#D4B062"}),e.jsx("text",{x:"60",y:"65",textAnchor:"middle",dominantBaseline:"middle",fill:"white",fontSize:"32",fontWeight:"bold",style:{fontFamily:"Arial, sans-serif"},children:"404"})]}),e.jsx(a.div,{className:"absolute inset-0 rounded-full border-4 border-[#D4B062]",animate:{scale:[1,1.15,1],opacity:[.7,.3,.7]},transition:{duration:2,repeat:1/0}})]})})]})}),e.jsxs(a.div,{variants:K,className:"w-full lg:w-1/2 lg:pl-8",transition:{duration:.5,delay:.2},children:[e.jsx("h3",{className:"font-bold text-2xl text-magazine-navy mb-4 border-b-2 border-[#D4B062] pb-2 inline-block",children:"Connection Status"}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs(a.div,{className:"flex items-center",whileHover:{x:5},children:[e.jsx("div",{className:"w-3 h-3 bg-red-500 rounded-full mr-3 animate-pulse"}),e.jsx("p",{className:"text-gray-700",children:"Resource not found"})]}),e.jsxs(a.div,{className:"flex items-center",whileHover:{x:5},children:[e.jsx("div",{className:"w-3 h-3 bg-green-500 rounded-full mr-3"}),e.jsx("p",{className:"text-gray-700",children:"Server connection: Active"})]}),e.jsx(a.div,{className:"mt-6",variants:ne,children:e.jsx(F,{to:"/",children:e.jsxs(a.button,{className:"w-full py-2.5 bg-[#D4B062] hover:bg-magazine-navy text-white font-medium rounded-lg transition-all duration-300 shadow hover:shadow-lg flex items-center justify-center",variants:we,whileHover:"whileHover",whileTap:"whileTap",children:[e.jsx(Nt,{className:"h-5 w-5 mr-2"}),"Return to Homepage"]})})})]})]})]})})})}),e.jsx(a.section,{id:"solutions",initial:"hidden",whileInView:"visible",viewport:{once:!0,margin:"-100px"},variants:H,className:"py-16 bg-[#FFFEF9]",children:e.jsxs("div",{className:"container mx-auto px-4 md:px-6",children:[e.jsx(a.h2,{variants:z,className:"text-3xl font-bold mb-12 text-center text-magazine-navy border-b-2 border-[#D4B062] pb-2 inline-block mx-auto",children:"What Happened?"}),e.jsx("div",{className:"max-w-4xl mx-auto mb-16",children:e.jsxs(a.div,{variants:P,className:"bg-white p-6 rounded-xl shadow-md border border-gray-100",children:[e.jsx("p",{className:"text-gray-600 mb-6 leading-relaxed",children:"The page you're looking for might have been removed, had its name changed, or is temporarily unavailable. This could be due to:"}),e.jsx("div",{className:"space-y-4 pl-4",children:["A mistyped URL","An outdated link from another website","A page that has been moved during a website redesign","A deleted or unpublished page"].map((s,i)=>e.jsxs(a.div,{className:"flex items-start",custom:i,variants:Qt,children:[e.jsx("div",{className:"mr-3 mt-1 text-[#D4B062]",children:"•"}),e.jsx("p",{className:"text-gray-700",children:s})]},i))})]})}),e.jsx(a.h2,{variants:z,className:"text-3xl font-bold mb-12 text-center text-magazine-navy",children:"What You Can Do"}),e.jsx("div",{className:"max-w-3xl mx-auto",children:e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:[{icon:e.jsx(ut,{className:"h-6 w-6"}),title:"Go Back",description:"Return to the previous page you were viewing.",action:()=>window.history.back(),actionText:"Previous Page"},{icon:e.jsx(Nt,{className:"h-6 w-6"}),title:"Homepage",description:"Visit our homepage to start fresh and find what you need.",link:"/",actionText:"Back to Home"}].map((s,i)=>e.jsx(a.div,{custom:i,variants:Jt,whileHover:"hover",className:"bg-white rounded-xl shadow-md overflow-hidden border border-gray-100",children:e.jsxs("div",{className:"p-6",children:[e.jsxs("div",{className:"flex items-center gap-4 mb-5",children:[e.jsx("div",{className:"bg-[#D4B062] p-3 rounded-full border-2 border-[#D4B062] text-white",children:s.icon}),e.jsx("h3",{className:"font-bold text-xl text-magazine-navy",children:s.title})]}),e.jsx("p",{className:"text-gray-600 mb-6 leading-relaxed",children:s.description}),s.action?e.jsx(a.button,{onClick:s.action,className:"inline-flex items-center bg-[#D4B062] hover:bg-magazine-navy text-white px-4 py-2 rounded-lg transition-colors font-medium",variants:we,whileHover:"whileHover",whileTap:"whileTap",children:s.actionText}):e.jsx(F,{to:s.link||"/",children:e.jsx(a.button,{className:"inline-flex items-center bg-[#D4B062] hover:bg-magazine-navy text-white px-4 py-2 rounded-lg transition-colors font-medium",variants:we,whileHover:"whileHover",whileTap:"whileTap",children:s.actionText})})]})},i))})})]})})]}),e.jsx(M,{})]}),Oi=()=>{const[s,i]=c.useState([]),[r,o]=c.useState([]),[t,l]=c.useState(""),[d,h]=c.useState(null),[w,k]=c.useState([]),[m,u]=c.useState(!1),[x,f]=c.useState(!0),[v,L]=c.useState(null),g=c.useCallback(async()=>{f(!0),L(null);try{let y=[],D=1,B=!0;for(;B;){const q=await kt.get(`https://api.github.com/orgs/sugarlabs/repos?per_page=100&page=${D}&sort=updated&direction=desc`);q.data.length===0?B=!1:(y=[...y,...q.data],D++)}i(y),o(y)}catch(y){console.error("Error fetching repositories:",y),L("Failed to load repositories. Please try again later.")}finally{f(!1)}},[]),j=c.useCallback(async y=>{u(!0),L(null);try{let D=[],B=1,q=!0;for(;q;){const X=await kt.get(`https://api.github.com/repos/sugarlabs/${y}/contributors?per_page=100&page=${B}`);X.data.length===0?q=!1:(D=[...D,...X.data],B++)}k(D)}catch(D){console.error("Error fetching contributors:",D),L("Failed to load contributors. Please try again later.")}finally{u(!1)}},[]);c.useEffect(()=>{g()},[g]),c.useEffect(()=>{const y=s.filter(D=>D.name.toLowerCase().includes(t.toLowerCase())||D.description&&D.description.toLowerCase().includes(t.toLowerCase()));o(y)},[t,s]),c.useEffect(()=>{if(!d){k([]);return}j(d)},[d,j]);const I=c.useCallback(y=>{h(y)},[]),S=c.useCallback(y=>new Date(y).toLocaleDateString(),[]),N=c.useMemo(()=>x?e.jsx("div",{className:"flex items-center justify-center h-40",children:e.jsx("div",{className:"animate-spin rounded-full h-10 w-10 border-b-2 border-[#D4B062]"})}):v?e.jsx("div",{className:"text-red-500 text-center py-10",children:v}):s.length===0?e.jsx("p",{className:"text-gray-500 text-center py-10",children:"No repositories found"}):r.length===0?e.jsx("p",{className:"text-gray-500 text-center py-10",children:"No repositories match your search"}):e.jsx("div",{className:"space-y-3 max-h-[65vh] overflow-y-auto pr-1 -mx-2 px-2",children:e.jsx(Y,{children:r.map(y=>e.jsxs(a.div,{whileHover:"hover",onClick:()=>I(y.name),className:`p-4 rounded-lg cursor-pointer transition duration-300 border-l-4 ${d===y.name?"bg-[#D4B062]/10 border-[#D4B062]":"hover:bg-gray-50 border-transparent hover:border-gray-200"}`,children:[e.jsx("h3",{className:"font-medium text-lg text-gray-800 break-words",children:y.name}),e.jsx("p",{className:"text-sm text-gray-600 line-clamp-2 mt-1",children:y.description||"No description"}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-3 text-xs text-gray-500",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(ws,{className:"h-3.5 w-3.5 text-[#D4B062]"})," ",y.stargazers_count]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(vs,{className:"h-3.5 w-3.5 text-[#D4B062]"})," ",y.forks_count]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(ht,{className:"h-3.5 w-3.5 text-[#D4B062]"})," ",S(y.updated_at)]})]})]},y.id))})}),[x,v,s,r,d,I,S]),C=c.useMemo(()=>d?m?e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx("div",{className:"animate-spin rounded-full h-10 w-10 border-b-2 border-[#D4B062]"})}):v?e.jsx("div",{className:"text-red-500 text-center py-10",children:v}):w.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center h-64 text-center",children:[e.jsx(Ue,{className:"h-16 w-16 text-gray-300 mb-4"}),e.jsx("p",{className:"text-gray-500",children:"No contributors found for this repository"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-sm text-gray-500 mb-4",children:["Showing all ",w.length," contributors"]}),e.jsx("div",{className:"max-h-[65vh] overflow-y-auto pr-1",children:e.jsx(a.div,{variants:H,className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",children:w.map(y=>e.jsxs(a.a,{whileHover:"hover",href:y.html_url,target:"_blank",rel:"noopener noreferrer",className:"group flex flex-col items-center p-5 bg-gray-50 rounded-lg transition duration-300 hover:bg-[#D4B062]/5 hover:shadow-md border border-gray-100",children:[e.jsxs("div",{className:"relative mb-3",children:[e.jsx("img",{src:y.avatar_url,alt:`${y.login}'s avatar`,className:"w-16 h-16 rounded-full object-cover border-2 border-white shadow-sm",onError:D=>{D.target.src="https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png"}}),e.jsx("div",{className:"absolute -bottom-1 -right-4 bg-[#D4B062] text-xs text-white font-bold rounded-full w-9 h-6 flex items-center justify-center",children:y.contributions>500?"500+":y.contributions})]}),e.jsx("h3",{className:"font-medium text-gray-800 text-center break-words w-full",children:y.login}),e.jsxs("div",{className:"mt-2 flex items-center text-xs text-[#D4B062] opacity-0 group-hover:opacity-100 transition-opacity",children:["View Profile ",e.jsx(gt,{className:"ml-1 h-3 w-3"})]})]},y.id))})})]}):e.jsxs("div",{className:"flex flex-col items-center justify-center h-full min-h-[400px] text-center py-12",children:[e.jsx(Ue,{className:"h-16 w-16 text-gray-300 mb-4"}),e.jsx("p",{className:"text-gray-500 max-w-xs",children:"Select a repository from the list to view its contributors"})]}),[d,m,v,w]);return e.jsxs(e.Fragment,{children:[e.jsx(A,{}),e.jsxs("div",{className:"min-h-screen flex flex-col font-sans bg-[#FFFEF9]",children:[e.jsxs(a.section,{initial:"hidden",animate:"visible",variants:P,className:"relative py-16 sm:py-20 overflow-hidden bg-gradient-to-b from-black via-gray-800 to-gray-600",children:[e.jsxs("div",{className:"absolute inset-0 z-0 overflow-hidden",children:[e.jsx("div",{className:"absolute inset-0 opacity-10"}),e.jsx("div",{className:"absolute inset-0",style:{backgroundImage:"radial-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1px)",backgroundSize:"20px 20px"}})]}),e.jsx("div",{className:"container mx-auto px-4 md:px-6",children:e.jsxs("div",{className:"flex flex-col items-center text-center z-10 relative",children:[e.jsxs(a.h1,{className:"font-black text-4xl sm:text-5xl md:text-6xl mb-4 sm:mb-6 text-white",initial:{opacity:0,y:-20},animate:{opacity:1,y:0},transition:{duration:.8},children:["Sugar Labs ",e.jsx("span",{className:"text-[#D4B062]",children:"Developers"})]}),e.jsx(a.div,{className:"w-16 sm:w-24 h-1 bg-[#D4B062] mb-4 sm:mb-6 rounded-full",initial:{width:0},animate:{width:96},transition:{duration:.8,delay:.3}}),e.jsx(a.p,{className:"text-base sm:text-lg md:text-xl mb-8 sm:mb-10 text-gray-300 max-w-2xl leading-relaxed px-4",initial:{opacity:0},animate:{opacity:1},transition:{duration:.8,delay:.5},children:"Explore Sugar Labs repositories and their contributors. Browse our open source projects and discover the developers behind them."})]})})]}),e.jsxs("div",{className:"container mx-auto px-4 py-12",children:[e.jsxs(a.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.3},className:"max-w-md mx-auto mb-8 relative",children:[e.jsxs("div",{className:"relative",children:[e.jsx("input",{type:"text",placeholder:"Search repositories...",value:t,onChange:y=>l(y.target.value),className:"w-full px-4 py-3 pl-12 border border-gray-200 rounded-full focus:outline-none focus:ring-2 focus:ring-[#D4B062] shadow-sm bg-white text-gray-700"}),e.jsx(Fe,{className:"absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400 h-5 w-5"})]}),e.jsxs("p",{className:"text-sm text-gray-500 mt-2 text-center",children:["Showing ",r.length," repositories."]})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-12 gap-8",children:[e.jsxs(a.div,{initial:"hidden",animate:"visible",variants:H,className:"lg:col-span-5 bg-white rounded-xl shadow-md p-6 overflow-hidden border border-gray-100",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx("div",{className:"bg-[#D4B062] p-3 rounded-full text-white",children:e.jsx(it,{className:"h-5 w-5"})}),e.jsx("h2",{className:"text-2xl font-bold text-gray-800",children:"Repositories"})]}),N]}),e.jsxs(a.div,{initial:"hidden",animate:"visible",variants:H,className:"lg:col-span-7 bg-white rounded-xl shadow-md p-6 overflow-hidden border border-gray-100",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx("div",{className:"bg-[#D4B062] p-3 rounded-full text-white",children:e.jsx(Ue,{className:"h-5 w-5"})}),e.jsx("h2",{className:"text-2xl font-bold text-gray-800",children:d?`Contributors for ${d}`:"Select a repository"})]}),C]})]})]})]}),e.jsx(M,{})]})},et=ys([...Ss,{path:"/",element:e.jsx(Ua,{})},{path:"/about-us",element:e.jsx(er,{})},{path:"/leadership",element:e.jsx(or,{})},{path:"/contact-us",element:e.jsx(nr,{})},{path:"/faqs",element:e.jsx(xr,{})},{path:"/news",element:e.jsx(Dt,{})},{path:"/news/:category",element:e.jsx(Dt,{})},{path:"/news/:category/:slug",element:e.jsx(Wr,{})},{path:"/authors/:slug",element:e.jsx($r,{})},{path:"/tags/:tag",element:e.jsx(qr,{})},{path:"/more",element:e.jsx(Bt,{})},{path:"/more/:slug",element:e.jsx(Bt,{})},{path:"/try-sugar",element:e.jsx(pr,{})},{path:"/join-development",element:e.jsx(yr,{})},{path:"/volunteer",element:e.jsx(kr,{})},{path:"/donate",element:e.jsx(_r,{})},{path:"/products",element:e.jsx(Tr,{})},{path:"/turtleblocks",element:e.jsx(ei,{})},{path:"/sugarizer",element:e.jsx(ri,{})},{path:"/bootablesoas",element:e.jsx(li,{})},{path:"/trisquel",element:e.jsx(ui,{})},{path:"/raspberry",element:e.jsx(pi,{})},{path:"/musicblocks",element:e.jsx(Li,{})},{path:"/flathub",element:e.jsx(Mi,{})},{path:"/contact-us/:matrix",element:e.jsx(Fi,{})},{path:"/profiles",element:e.jsx(Oi,{})},{path:"*",element:e.jsx(Bi,{})}]),Vi=()=>(c.useEffect(()=>{const s=et.subscribe(()=>{window.scrollTo(0,0)});return(()=>{const r=sessionStorage.getItem("gh_redirect");r&&(console.log("Restoring route:",r),sessionStorage.removeItem("gh_redirect"),setTimeout(()=>{et.navigate(r)},10))})(),()=>s()},[]),e.jsx("div",{className:"min-h-screen flex flex-col",children:e.jsx(js,{router:et})}));function Vt(s){s.preventDefault(),s.stopPropagation();const i=s.currentTarget,r=i.getAttribute("data-code");if(!r){console.error("No code content found to copy");return}zi(r,i)}async function zi(s,i){try{await navigator.clipboard.writeText(s),zt(i)}catch{const r=document.createElement("textarea");r.value=s,r.style.cssText="position:fixed;left:-999999px;top:-999999px;opacity:0;",document.body.appendChild(r),r.select();const o=document.execCommand("copy");document.body.removeChild(r),o&&zt(i)}}function zt(s){const i=s.nextElementSibling;i?.classList.contains("copy-success-message")&&(i.classList.remove("hidden"),setTimeout(()=>i.classList.add("hidden"),2e3))}function tt(){document.querySelectorAll(".copy-code-btn").forEach(s=>{s instanceof HTMLElement&&(s.removeEventListener("click",Vt),s.addEventListener("click",Vt))})}if(typeof window<"u"){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",tt):tt();let s;document.addEventListener("click",()=>{clearTimeout(s),s=window.setTimeout(tt,100)})}Ns.createRoot(document.getElementById("root")).render(e.jsx(ks.StrictMode,{children:e.jsx(Vi,{})})); diff --git a/assets/index-vc2PfLu3.css b/assets/index-vc2PfLu3.css new file mode 100644 index 00000000..03c5f25c --- /dev/null +++ b/assets/index-vc2PfLu3.css @@ -0,0 +1 @@ +/*! tailwindcss v4.1.11 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-pan-x:initial;--tw-pan-y:initial;--tw-pinch-zoom:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}}@font-face{font-family:Caveat;src:url(../fonts/Caveat-Regular.ttf)}@font-face{font-family:Roboto;src:url(../fonts/Roboto-Regular.ttf)}@font-face{font-family:Pacifico;src:url(../fonts/Pacifico-Regular.ttf)}@font-face{font-family:AnonymousPro;src:url(../fonts/AnonymousPro-Regular.ttf)}@font-face{font-family:Inter;src:url(../fonts/Inter_28pt-Regular.ttf)}@font-face{font-family:Oswald;src:url(../fonts/Oswald-Regular.ttf)}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-serif:ui-serif,Georgia,Cambria,"Times New Roman",Times,serif;--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-800:oklch(44.4% .177 26.899);--color-orange-100:oklch(95.4% .038 75.164);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-300:oklch(83.7% .128 66.29);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-700:oklch(55.3% .195 38.402);--color-orange-800:oklch(47% .157 37.304);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-950:oklch(27.9% .077 45.635);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-300:oklch(90.5% .182 98.111);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-700:oklch(55.4% .135 66.442);--color-yellow-800:oklch(47.6% .114 61.907);--color-green-50:oklch(98.2% .018 155.826);--color-green-100:oklch(96.2% .044 156.743);--color-green-200:oklch(92.5% .084 155.995);--color-green-300:oklch(87.1% .15 154.449);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-green-800:oklch(44.8% .119 151.328);--color-green-950:oklch(26.6% .065 152.934);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-emerald-800:oklch(43.2% .095 166.913);--color-emerald-900:oklch(37.8% .077 168.94);--color-teal-400:oklch(77.7% .152 181.912);--color-cyan-100:oklch(95.6% .045 203.388);--color-cyan-300:oklch(86.5% .127 207.078);--color-cyan-600:oklch(60.9% .126 221.723);--color-cyan-700:oklch(52% .105 223.128);--color-cyan-800:oklch(45% .085 224.283);--color-cyan-950:oklch(30.2% .056 229.695);--color-sky-200:oklch(90.1% .058 230.902);--color-sky-700:oklch(50% .134 242.749);--color-sky-800:oklch(44.3% .11 240.79);--color-sky-900:oklch(39.1% .09 240.876);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-blue-950:oklch(28.2% .091 267.935);--color-indigo-100:oklch(93% .034 272.788);--color-indigo-200:oklch(87% .065 274.039);--color-indigo-400:oklch(67.3% .182 276.935);--color-indigo-600:oklch(51.1% .262 276.966);--color-indigo-700:oklch(45.7% .24 277.023);--color-indigo-800:oklch(39.8% .195 277.366);--color-indigo-900:oklch(35.9% .144 278.697);--color-purple-50:oklch(97.7% .014 308.299);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-200:oklch(90.2% .063 306.703);--color-purple-300:oklch(82.7% .119 306.383);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-700:oklch(49.6% .265 301.924);--color-purple-800:oklch(43.8% .218 303.724);--color-purple-900:oklch(38.1% .176 304.987);--color-purple-950:oklch(29.1% .149 302.717);--color-fuchsia-200:oklch(90.3% .076 319.62);--color-fuchsia-700:oklch(51.8% .253 323.949);--color-fuchsia-800:oklch(45.2% .211 324.591);--color-fuchsia-900:oklch(40.1% .17 325.612);--color-pink-100:oklch(94.8% .028 342.258);--color-pink-500:oklch(65.6% .241 354.308);--color-pink-600:oklch(59.2% .249 .584);--color-pink-700:oklch(52.5% .223 3.958);--color-pink-900:oklch(40.8% .153 2.432);--color-rose-400:oklch(71.2% .194 13.428);--color-rose-500:oklch(64.5% .246 16.439);--color-rose-600:oklch(58.6% .253 17.585);--color-rose-700:oklch(51.4% .222 16.935);--color-slate-50:oklch(98.4% .003 247.858);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-gray-950:oklch(13% .028 261.692);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5/2.25);--text-5xl:3rem;--text-5xl--line-height:1;--text-6xl:3.75rem;--text-6xl--line-height:1;--text-7xl:4.5rem;--text-7xl--line-height:1;--text-8xl:6rem;--text-8xl--line-height:1;--text-9xl:8rem;--text-9xl--line-height:1;--font-weight-extralight:200;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-weight-black:900;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--radius-2xl:1rem;--radius-3xl:1.5rem;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--animate-bounce:bounce 1s infinite;--blur-sm:8px;--blur-md:12px;--blur-xl:24px;--blur-2xl:40px;--blur-3xl:64px;--aspect-video:16/9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-Caveat:"Caveat",sans-serif;--font-Roboto:"Roboto",sans-serif;--font-Pacifico:"Pacifico",sans-serif;--font-AnonymousPro:"AnonymousPro",sans-serif;--font-Inter:"Inter",sans-serif;--font-Oswald:"Oswald",sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab,red,red)){*{outline-color:color-mix(in oklab,var(--ring)50%,transparent)}}body{background-color:var(--background);color:var(--foreground)}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.inset-x-0{inset-inline:calc(var(--spacing)*0)}.inset-y-0{inset-block:calc(var(--spacing)*0)}.-top-1{top:calc(var(--spacing)*-1)}.-top-4{top:calc(var(--spacing)*-4)}.-top-6{top:calc(var(--spacing)*-6)}.-top-8{top:calc(var(--spacing)*-8)}.top-0{top:calc(var(--spacing)*0)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing)*2)}.top-4{top:calc(var(--spacing)*4)}.top-5{top:calc(var(--spacing)*5)}.top-6{top:calc(var(--spacing)*6)}.top-8{top:calc(var(--spacing)*8)}.top-10{top:calc(var(--spacing)*10)}.top-\[10vh\]{top:10vh}.top-\[28vh\]{top:28vh}.top-\[60vh\]{top:60vh}.top-\[65vh\]{top:65vh}.-right-1{right:calc(var(--spacing)*-1)}.-right-4{right:calc(var(--spacing)*-4)}.-right-5{right:calc(var(--spacing)*-5)}.-right-8{right:calc(var(--spacing)*-8)}.right-0{right:calc(var(--spacing)*0)}.right-1{right:calc(var(--spacing)*1)}.right-2{right:calc(var(--spacing)*2)}.right-4{right:calc(var(--spacing)*4)}.right-5{right:calc(var(--spacing)*5)}.right-6{right:calc(var(--spacing)*6)}.right-8{right:calc(var(--spacing)*8)}.right-10{right:calc(var(--spacing)*10)}.right-\[5vw\]{right:5vw}.right-\[10vw\]{right:10vw}.-bottom-1{bottom:calc(var(--spacing)*-1)}.-bottom-2{bottom:calc(var(--spacing)*-2)}.-bottom-6{bottom:calc(var(--spacing)*-6)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-1{bottom:calc(var(--spacing)*1)}.bottom-2{bottom:calc(var(--spacing)*2)}.bottom-5{bottom:calc(var(--spacing)*5)}.bottom-6{bottom:calc(var(--spacing)*6)}.bottom-8{bottom:calc(var(--spacing)*8)}.bottom-10{bottom:calc(var(--spacing)*10)}.left-0{left:calc(var(--spacing)*0)}.left-1{left:calc(var(--spacing)*1)}.left-1\/2{left:50%}.left-1\/3{left:33.3333%}.left-1\/4{left:25%}.left-2{left:calc(var(--spacing)*2)}.left-3{left:calc(var(--spacing)*3)}.left-4{left:calc(var(--spacing)*4)}.left-5{left:calc(var(--spacing)*5)}.left-6{left:calc(var(--spacing)*6)}.left-10{left:calc(var(--spacing)*10)}.left-\[5vw\]{left:5vw}.isolate{isolation:isolate}.-z-10{z-index:-10}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.z-\[-1\]{z-index:-1}.order-1{order:1}.order-2{order:2}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.-m-2{margin:calc(var(--spacing)*-2)}.-mx-2{margin-inline:calc(var(--spacing)*-2)}.-mx-3{margin-inline:calc(var(--spacing)*-3)}.-mx-4{margin-inline:calc(var(--spacing)*-4)}.mx-2{margin-inline:calc(var(--spacing)*2)}.mx-auto{margin-inline:auto}.my-3{margin-block:calc(var(--spacing)*3)}.my-4{margin-block:calc(var(--spacing)*4)}.my-5{margin-block:calc(var(--spacing)*5)}.my-6{margin-block:calc(var(--spacing)*6)}.my-8{margin-block:calc(var(--spacing)*8)}.my-10{margin-block:calc(var(--spacing)*10)}.my-12{margin-block:calc(var(--spacing)*12)}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-10{margin-top:calc(var(--spacing)*10)}.mt-12{margin-top:calc(var(--spacing)*12)}.mt-14{margin-top:calc(var(--spacing)*14)}.mt-16{margin-top:calc(var(--spacing)*16)}.mt-20{margin-top:calc(var(--spacing)*20)}.mt-auto{margin-top:auto}.mr-0{margin-right:calc(var(--spacing)*0)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-3{margin-right:calc(var(--spacing)*3)}.mr-4{margin-right:calc(var(--spacing)*4)}.-mb-4{margin-bottom:calc(var(--spacing)*-4)}.mb-0{margin-bottom:calc(var(--spacing)*0)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-5{margin-bottom:calc(var(--spacing)*5)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.mb-9{margin-bottom:calc(var(--spacing)*9)}.mb-10{margin-bottom:calc(var(--spacing)*10)}.mb-12{margin-bottom:calc(var(--spacing)*12)}.mb-16{margin-bottom:calc(var(--spacing)*16)}.mb-20{margin-bottom:calc(var(--spacing)*20)}.-ml-2{margin-left:calc(var(--spacing)*-2)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-3{margin-left:calc(var(--spacing)*3)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-video{aspect-ratio:var(--aspect-video)}.h-0{height:calc(var(--spacing)*0)}.h-0\.5{height:calc(var(--spacing)*.5)}.h-1{height:calc(var(--spacing)*1)}.h-2{height:calc(var(--spacing)*2)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-16{height:calc(var(--spacing)*16)}.h-20{height:calc(var(--spacing)*20)}.h-24{height:calc(var(--spacing)*24)}.h-32{height:calc(var(--spacing)*32)}.h-36{height:calc(var(--spacing)*36)}.h-40{height:calc(var(--spacing)*40)}.h-48{height:calc(var(--spacing)*48)}.h-56{height:calc(var(--spacing)*56)}.h-64{height:calc(var(--spacing)*64)}.h-\[280px\]{height:280px}.h-\[350px\]{height:350px}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.max-h-28{max-height:calc(var(--spacing)*28)}.max-h-80{max-height:calc(var(--spacing)*80)}.max-h-\[65vh\]{max-height:65vh}.max-h-\[90vh\]{max-height:90vh}.max-h-full{max-height:100%}.min-h-\[50vh\]{min-height:50vh}.min-h-\[250px\]{min-height:250px}.min-h-\[400px\]{min-height:400px}.min-h-screen{min-height:100vh}.w-0{width:calc(var(--spacing)*0)}.w-0\.5{width:calc(var(--spacing)*.5)}.w-1{width:calc(var(--spacing)*1)}.w-1\.5{width:calc(var(--spacing)*1.5)}.w-1\/2{width:50%}.w-1\/3{width:33.3333%}.w-1\/4{width:25%}.w-2{width:calc(var(--spacing)*2)}.w-2\/3{width:66.6667%}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-3\/4{width:75%}.w-3\/7{width:42.8571%}.w-4{width:calc(var(--spacing)*4)}.w-4\/5{width:80%}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-12{width:calc(var(--spacing)*12)}.w-16{width:calc(var(--spacing)*16)}.w-20{width:calc(var(--spacing)*20)}.w-24{width:calc(var(--spacing)*24)}.w-32{width:calc(var(--spacing)*32)}.w-36{width:calc(var(--spacing)*36)}.w-48{width:calc(var(--spacing)*48)}.w-56{width:calc(var(--spacing)*56)}.w-64{width:calc(var(--spacing)*64)}.w-80{width:calc(var(--spacing)*80)}.w-\[1px\]{width:1px}.w-\[60\%\]{width:60%}.w-\[80\%\]{width:80%}.w-\[90\%\]{width:90%}.w-\[350px\]{width:350px}.w-\[400px\]{width:400px}.w-\[clamp\(40px\,9vw\,16px\)\]{width:clamp(40px,9vw,16px)}.w-\[clamp\(80px\,9vw\,160px\)\]{width:clamp(80px,9vw,160px)}.w-\[clamp\(90px\,10vw\,170px\)\]{width:clamp(90px,10vw,170px)}.w-\[clamp\(100px\,10vw\,150px\)\]{width:clamp(100px,10vw,150px)}.w-\[clamp\(100px\,10vw\,180px\)\]{width:clamp(100px,10vw,180px)}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[90\%\]{max-width:90%}.max-w-\[180px\]{max-width:180px}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-full{min-width:100%}.flex-1{flex:1}.flex-1\/3{flex:33.3333%}.flex-1\/4{flex:25%}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.flex-grow,.grow{flex-grow:1}.origin-left{transform-origin:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\.5{--tw-translate-y:calc(var(--spacing)*-1.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-2{--tw-translate-y:calc(var(--spacing)*-2);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-1\.5{--tw-translate-y:calc(var(--spacing)*1.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\[-4px\]{--tw-translate-y:-4px;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\[4px\]{--tw-translate-y:4px;translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-98{--tw-scale-x:98%;--tw-scale-y:98%;--tw-scale-z:98%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-x-0{--tw-scale-x:0%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-x-100{--tw-scale-x:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-x-\[-1\]{--tw-scale-x:-1;scale:var(--tw-scale-x)var(--tw-scale-y)}.-rotate-45{rotate:-45deg}.rotate-45{rotate:45deg}.rotate-180{rotate:180deg}.-skew-x-6{--tw-skew-x:skewX( -6deg );transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-bounce{animation:var(--animate-bounce)}.animate-marquee{animation:marquee var(--duration)infinite linear}.animate-marquee-vertical{animation:marquee-vertical var(--duration)linear infinite}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.touch-pan-x{--tw-pan-x:pan-x;touch-action:var(--tw-pan-x,)var(--tw-pan-y,)var(--tw-pinch-zoom,)}.touch-manipulation{touch-action:manipulation}.resize{resize:both}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-around{justify-content:space-around}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.\[gap\:var\(--gap\)\]{gap:var(--gap)}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-5{gap:calc(var(--spacing)*5)}.gap-6{gap:calc(var(--spacing)*6)}.gap-8{gap:calc(var(--spacing)*8)}.gap-10{gap:calc(var(--spacing)*10)}.gap-12{gap:calc(var(--spacing)*12)}.gap-16{gap:calc(var(--spacing)*16)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-12>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*12)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*12)*calc(1 - var(--tw-space-y-reverse)))}.gap-x-6{column-gap:calc(var(--spacing)*6)}:where(.space-x-1>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*1)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-3>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*3)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*4)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-x-reverse)))}.gap-y-3{row-gap:calc(var(--spacing)*3)}.gap-y-8{row-gap:calc(var(--spacing)*8)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-gray-200>:not(:last-child)){border-color:var(--color-gray-200)}.self-end{align-self:flex-end}.self-start{align-self:flex-start}.justify-self-center{justify-self:center}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-3xl{border-radius:var(--radius-3xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.rounded-l-full{border-top-left-radius:3.40282e38px;border-bottom-left-radius:3.40282e38px}.rounded-r-2xl{border-top-right-radius:var(--radius-2xl);border-bottom-right-radius:var(--radius-2xl)}.rounded-r-full{border-top-right-radius:3.40282e38px;border-bottom-right-radius:3.40282e38px}.rounded-r-lg{border-top-right-radius:var(--radius);border-bottom-right-radius:var(--radius)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-4{border-style:var(--tw-border-style);border-width:4px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-t-4{border-top-style:var(--tw-border-style);border-top-width:4px}.border-t-8{border-top-style:var(--tw-border-style);border-top-width:8px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-r-2{border-right-style:var(--tw-border-style);border-right-width:2px}.border-r-8{border-right-style:var(--tw-border-style);border-right-width:8px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-b-4{border-bottom-style:var(--tw-border-style);border-bottom-width:4px}.border-b-8{border-bottom-style:var(--tw-border-style);border-bottom-width:8px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-3{border-left-style:var(--tw-border-style);border-left-width:3px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-l-8{border-left-style:var(--tw-border-style);border-left-width:8px}.border-none{--tw-border-style:none;border-style:none}.border-\[\#D4B062\]{border-color:#d4b062}.border-\[\#D4B062\]\/30{border-color:#d4b0624d}.border-amber-200{border-color:var(--color-amber-200)}.border-amber-300{border-color:var(--color-amber-300)}.border-blue-100{border-color:var(--color-blue-100)}.border-blue-200{border-color:var(--color-blue-200)}.border-blue-300{border-color:var(--color-blue-300)}.border-blue-400{border-color:var(--color-blue-400)}.border-blue-500{border-color:var(--color-blue-500)}.border-blue-600{border-color:var(--color-blue-600)}.border-cyan-300{border-color:var(--color-cyan-300)}.border-gray-100{border-color:var(--color-gray-100)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-400{border-color:var(--color-gray-400)}.border-gray-500{border-color:var(--color-gray-500)}.border-gray-700\/50{border-color:#36415380}@supports (color:color-mix(in lab,red,red)){.border-gray-700\/50{border-color:color-mix(in oklab,var(--color-gray-700)50%,transparent)}}.border-gray-800{border-color:var(--color-gray-800)}.border-gray-900{border-color:var(--color-gray-900)}.border-gray-950{border-color:var(--color-gray-950)}.border-gray-950\/\[\.1\]{border-color:#0307121a}@supports (color:color-mix(in lab,red,red)){.border-gray-950\/\[\.1\]{border-color:color-mix(in oklab,var(--color-gray-950)10%,transparent)}}.border-green-200{border-color:var(--color-green-200)}.border-green-300{border-color:var(--color-green-300)}.border-indigo-700{border-color:var(--color-indigo-700)}.border-purple-200{border-color:var(--color-purple-200)}.border-purple-300{border-color:var(--color-purple-300)}.border-red-200{border-color:var(--color-red-200)}.border-red-300{border-color:var(--color-red-300)}.border-red-400{border-color:var(--color-red-400)}.border-red-500{border-color:var(--color-red-500)}.border-slate-100{border-color:var(--color-slate-100)}.border-slate-200{border-color:var(--color-slate-200)}.border-transparent{border-color:#0000}.border-white{border-color:var(--color-white)}.border-white\/20{border-color:#fff3}@supports (color:color-mix(in lab,red,red)){.border-white\/20{border-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.border-white\/50{border-color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.border-white\/50{border-color:color-mix(in oklab,var(--color-white)50%,transparent)}}.border-white\/60{border-color:#fff9}@supports (color:color-mix(in lab,red,red)){.border-white\/60{border-color:color-mix(in oklab,var(--color-white)60%,transparent)}}.border-yellow-200{border-color:var(--color-yellow-200)}.border-r-white{border-right-color:var(--color-white)}.border-l-white{border-left-color:var(--color-white)}.bg-\[\#144EEC\]{background-color:#144eec}.bg-\[\#975555\]{background-color:#975555}.bg-\[\#975555\]\/30{background-color:#9755554d}.bg-\[\#D4B062\]{background-color:#d4b062}.bg-\[\#D4B062\]\/10{background-color:#d4b0621a}.bg-\[\#D4B062\]\/30{background-color:#d4b0624d}.bg-\[\#F6DEC9\]{background-color:#f6dec9}.bg-\[\#FFFEF9\]{background-color:#fffef9}.bg-\[\#fbd04d\]{background-color:#fbd04d}.bg-amber-50{background-color:var(--color-amber-50)}.bg-black{background-color:var(--color-black)}.bg-black\/30{background-color:#0000004d}@supports (color:color-mix(in lab,red,red)){.bg-black\/30{background-color:color-mix(in oklab,var(--color-black)30%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black)60%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-200{background-color:var(--color-blue-200)}.bg-blue-300{background-color:var(--color-blue-300)}.bg-blue-400{background-color:var(--color-blue-400)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-cyan-100{background-color:var(--color-cyan-100)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-50\/80{background-color:#f9fafbcc}@supports (color:color-mix(in lab,red,red)){.bg-gray-50\/80{background-color:color-mix(in oklab,var(--color-gray-50)80%,transparent)}}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-300{background-color:var(--color-gray-300)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-gray-600{background-color:var(--color-gray-600)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-gray-800\/30{background-color:#1e29394d}@supports (color:color-mix(in lab,red,red)){.bg-gray-800\/30{background-color:color-mix(in oklab,var(--color-gray-800)30%,transparent)}}.bg-gray-800\/50{background-color:#1e293980}@supports (color:color-mix(in lab,red,red)){.bg-gray-800\/50{background-color:color-mix(in oklab,var(--color-gray-800)50%,transparent)}}.bg-gray-900{background-color:var(--color-gray-900)}.bg-gray-950\/\[\.01\]{background-color:#03071203}@supports (color:color-mix(in lab,red,red)){.bg-gray-950\/\[\.01\]{background-color:color-mix(in oklab,var(--color-gray-950)1%,transparent)}}.bg-green-50{background-color:var(--color-green-50)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-200{background-color:var(--color-green-200)}.bg-green-500{background-color:var(--color-green-500)}.bg-green-600{background-color:var(--color-green-600)}.bg-indigo-600{background-color:var(--color-indigo-600)}.bg-orange-100{background-color:var(--color-orange-100)}.bg-orange-200{background-color:var(--color-orange-200)}.bg-orange-300{background-color:var(--color-orange-300)}.bg-orange-500\/70{background-color:#fe6e00b3}@supports (color:color-mix(in lab,red,red)){.bg-orange-500\/70{background-color:color-mix(in oklab,var(--color-orange-500)70%,transparent)}}.bg-pink-100{background-color:var(--color-pink-100)}.bg-pink-500{background-color:var(--color-pink-500)}.bg-purple-50{background-color:var(--color-purple-50)}.bg-purple-500{background-color:var(--color-purple-500)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-700{background-color:var(--color-red-700)}.bg-rose-400{background-color:var(--color-rose-400)}.bg-rose-600{background-color:var(--color-rose-600)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-200{background-color:var(--color-slate-200)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.bg-white\/10{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.bg-white\/40{background-color:#fff6}@supports (color:color-mix(in lab,red,red)){.bg-white\/40{background-color:color-mix(in oklab,var(--color-white)40%,transparent)}}.bg-white\/80{background-color:#fffc}@supports (color:color-mix(in lab,red,red)){.bg-white\/80{background-color:color-mix(in oklab,var(--color-white)80%,transparent)}}.bg-white\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.bg-white\/90{background-color:color-mix(in oklab,var(--color-white)90%,transparent)}}.bg-yellow-50{background-color:var(--color-yellow-50)}.bg-yellow-200{background-color:var(--color-yellow-200)}.bg-yellow-300{background-color:var(--color-yellow-300)}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-gradient-to-b{--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-l{--tw-gradient-position:to left in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-tr{--tw-gradient-position:to top right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-\[\#F5DDC8\]{--tw-gradient-from:#f5ddc8;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-amber-100{--tw-gradient-from:var(--color-amber-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-amber-300{--tw-gradient-from:var(--color-amber-300);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-amber-600{--tw-gradient-from:var(--color-amber-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-background{--tw-gradient-from:var(--background);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-black{--tw-gradient-from:var(--color-black);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-black\/20{--tw-gradient-from:#0003}@supports (color:color-mix(in lab,red,red)){.from-black\/20{--tw-gradient-from:color-mix(in oklab,var(--color-black)20%,transparent)}}.from-black\/20{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-black\/30{--tw-gradient-from:#0000004d}@supports (color:color-mix(in lab,red,red)){.from-black\/30{--tw-gradient-from:color-mix(in oklab,var(--color-black)30%,transparent)}}.from-black\/30{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-black\/70{--tw-gradient-from:#000000b3}@supports (color:color-mix(in lab,red,red)){.from-black\/70{--tw-gradient-from:color-mix(in oklab,var(--color-black)70%,transparent)}}.from-black\/70{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-black\/90{--tw-gradient-from:#000000e6}@supports (color:color-mix(in lab,red,red)){.from-black\/90{--tw-gradient-from:color-mix(in oklab,var(--color-black)90%,transparent)}}.from-black\/90{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-50{--tw-gradient-from:var(--color-blue-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-100{--tw-gradient-from:var(--color-blue-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-500{--tw-gradient-from:var(--color-blue-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-600{--tw-gradient-from:var(--color-blue-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-600\/5{--tw-gradient-from:#155dfc0d}@supports (color:color-mix(in lab,red,red)){.from-blue-600\/5{--tw-gradient-from:color-mix(in oklab,var(--color-blue-600)5%,transparent)}}.from-blue-600\/5{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-700{--tw-gradient-from:var(--color-blue-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-900{--tw-gradient-from:var(--color-blue-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-cyan-100{--tw-gradient-from:var(--color-cyan-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-cyan-600{--tw-gradient-from:var(--color-cyan-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-cyan-700{--tw-gradient-from:var(--color-cyan-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-emerald-300{--tw-gradient-from:var(--color-emerald-300);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-gray-400{--tw-gradient-from:var(--color-gray-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-gray-800{--tw-gradient-from:var(--color-gray-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-gray-900{--tw-gradient-from:var(--color-gray-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-green-50{--tw-gradient-from:var(--color-green-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-green-100{--tw-gradient-from:var(--color-green-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-green-600{--tw-gradient-from:var(--color-green-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-green-600\/20{--tw-gradient-from:#00a54433}@supports (color:color-mix(in lab,red,red)){.from-green-600\/20{--tw-gradient-from:color-mix(in oklab,var(--color-green-600)20%,transparent)}}.from-green-600\/20{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-green-700{--tw-gradient-from:var(--color-green-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-indigo-100{--tw-gradient-from:var(--color-indigo-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-indigo-400{--tw-gradient-from:var(--color-indigo-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-indigo-700{--tw-gradient-from:var(--color-indigo-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-pink-600{--tw-gradient-from:var(--color-pink-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-purple-100{--tw-gradient-from:var(--color-purple-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-purple-600{--tw-gradient-from:var(--color-purple-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-purple-700{--tw-gradient-from:var(--color-purple-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-red-50{--tw-gradient-from:var(--color-red-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-red-500{--tw-gradient-from:var(--color-red-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-red-500\/10{--tw-gradient-from:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.from-red-500\/10{--tw-gradient-from:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.from-red-500\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-red-600{--tw-gradient-from:var(--color-red-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-slate-50{--tw-gradient-from:var(--color-slate-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-slate-900\/30{--tw-gradient-from:#0f172b4d}@supports (color:color-mix(in lab,red,red)){.from-slate-900\/30{--tw-gradient-from:color-mix(in oklab,var(--color-slate-900)30%,transparent)}}.from-slate-900\/30{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-slate-900\/80{--tw-gradient-from:#0f172bcc}@supports (color:color-mix(in lab,red,red)){.from-slate-900\/80{--tw-gradient-from:color-mix(in oklab,var(--color-slate-900)80%,transparent)}}.from-slate-900\/80{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-white{--tw-gradient-from:var(--color-white);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-yellow-400{--tw-gradient-from:var(--color-yellow-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-yellow-600{--tw-gradient-from:var(--color-yellow-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.via-black\/50{--tw-gradient-via:#00000080}@supports (color:color-mix(in lab,red,red)){.via-black\/50{--tw-gradient-via:color-mix(in oklab,var(--color-black)50%,transparent)}}.via-black\/50{--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-blue-700{--tw-gradient-via:var(--color-blue-700);--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-gray-800{--tw-gradient-via:var(--color-gray-800);--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-purple-50{--tw-gradient-via:var(--color-purple-50);--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-purple-100{--tw-gradient-via:var(--color-purple-100);--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-purple-500{--tw-gradient-via:var(--color-purple-500);--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-slate-800{--tw-gradient-via:var(--color-slate-800);--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-teal-400{--tw-gradient-via:var(--color-teal-400);--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-transparent{--tw-gradient-via:transparent;--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-white{--tw-gradient-via:var(--color-white);--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-white\/50{--tw-gradient-via:#ffffff80}@supports (color:color-mix(in lab,red,red)){.via-white\/50{--tw-gradient-via:color-mix(in oklab,var(--color-white)50%,transparent)}}.via-white\/50{--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-yellow-500{--tw-gradient-via:var(--color-yellow-500);--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-\[\#F5DDC8\]{--tw-gradient-to:#f5ddc8;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-blue-500{--tw-gradient-to:var(--color-blue-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-blue-700{--tw-gradient-to:var(--color-blue-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-blue-800{--tw-gradient-to:var(--color-blue-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-blue-900{--tw-gradient-to:var(--color-blue-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-cyan-300{--tw-gradient-to:var(--color-cyan-300);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-emerald-200{--tw-gradient-to:var(--color-emerald-200);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-emerald-700{--tw-gradient-to:var(--color-emerald-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-emerald-800{--tw-gradient-to:var(--color-emerald-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-fuchsia-200{--tw-gradient-to:var(--color-fuchsia-200);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-fuchsia-700{--tw-gradient-to:var(--color-fuchsia-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-fuchsia-800{--tw-gradient-to:var(--color-fuchsia-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-gray-400{--tw-gradient-to:var(--color-gray-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-gray-600{--tw-gradient-to:var(--color-gray-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-gray-900{--tw-gradient-to:var(--color-gray-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-gray-950{--tw-gradient-to:var(--color-gray-950);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-green-50{--tw-gradient-to:var(--color-green-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-green-100{--tw-gradient-to:var(--color-green-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-green-400{--tw-gradient-to:var(--color-green-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-green-500{--tw-gradient-to:var(--color-green-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-green-600{--tw-gradient-to:var(--color-green-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-green-700{--tw-gradient-to:var(--color-green-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-indigo-200{--tw-gradient-to:var(--color-indigo-200);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-indigo-700{--tw-gradient-to:var(--color-indigo-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-indigo-800{--tw-gradient-to:var(--color-indigo-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-orange-200{--tw-gradient-to:var(--color-orange-200);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-orange-500{--tw-gradient-to:var(--color-orange-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-orange-500\/10{--tw-gradient-to:#fe6e001a}@supports (color:color-mix(in lab,red,red)){.to-orange-500\/10{--tw-gradient-to:color-mix(in oklab,var(--color-orange-500)10%,transparent)}}.to-orange-500\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-orange-700{--tw-gradient-to:var(--color-orange-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-pink-100{--tw-gradient-to:var(--color-pink-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-pink-500{--tw-gradient-to:var(--color-pink-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-purple-100{--tw-gradient-to:var(--color-purple-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-red-50{--tw-gradient-to:var(--color-red-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-red-100{--tw-gradient-to:var(--color-red-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-red-600{--tw-gradient-to:var(--color-red-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-red-600\/5{--tw-gradient-to:#e400140d}@supports (color:color-mix(in lab,red,red)){.to-red-600\/5{--tw-gradient-to:color-mix(in oklab,var(--color-red-600)5%,transparent)}}.to-red-600\/5{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-red-700{--tw-gradient-to:var(--color-red-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-rose-400{--tw-gradient-to:var(--color-rose-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-rose-700{--tw-gradient-to:var(--color-rose-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-sky-200{--tw-gradient-to:var(--color-sky-200);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-sky-700{--tw-gradient-to:var(--color-sky-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-sky-800{--tw-gradient-to:var(--color-sky-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-slate-50{--tw-gradient-to:var(--color-slate-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-slate-500{--tw-gradient-to:var(--color-slate-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-slate-900{--tw-gradient-to:var(--color-slate-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-teal-400{--tw-gradient-to:var(--color-teal-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-white{--tw-gradient-to:var(--color-white);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-yellow-400{--tw-gradient-to:var(--color-yellow-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-yellow-700{--tw-gradient-to:var(--color-yellow-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.bg-auto{background-size:auto}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.fill-current{fill:currentColor}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.object-center{object-position:center}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-2\.5{padding:calc(var(--spacing)*2.5)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.p-6{padding:calc(var(--spacing)*6)}.p-7{padding:calc(var(--spacing)*7)}.p-8{padding:calc(var(--spacing)*8)}.p-10{padding:calc(var(--spacing)*10)}.p-12{padding:calc(var(--spacing)*12)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-3\.5{padding-inline:calc(var(--spacing)*3.5)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-6{padding-inline:calc(var(--spacing)*6)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-5{padding-block:calc(var(--spacing)*5)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.py-10{padding-block:calc(var(--spacing)*10)}.py-12{padding-block:calc(var(--spacing)*12)}.py-16{padding-block:calc(var(--spacing)*16)}.py-20{padding-block:calc(var(--spacing)*20)}.py-24{padding-block:calc(var(--spacing)*24)}.py-32{padding-block:calc(var(--spacing)*32)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pt-8{padding-top:calc(var(--spacing)*8)}.pt-12{padding-top:calc(var(--spacing)*12)}.pr-0{padding-right:calc(var(--spacing)*0)}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-4{padding-right:calc(var(--spacing)*4)}.pr-5{padding-right:calc(var(--spacing)*5)}.pr-8{padding-right:calc(var(--spacing)*8)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pb-6{padding-bottom:calc(var(--spacing)*6)}.pb-10{padding-bottom:calc(var(--spacing)*10)}.pl-1{padding-left:calc(var(--spacing)*1)}.pl-4{padding-left:calc(var(--spacing)*4)}.pl-5{padding-left:calc(var(--spacing)*5)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-8{padding-left:calc(var(--spacing)*8)}.pl-10{padding-left:calc(var(--spacing)*10)}.pl-12{padding-left:calc(var(--spacing)*12)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-AnonymousPro{font-family:var(--font-AnonymousPro)}.font-Caveat{font-family:var(--font-Caveat)}.font-Inter{font-family:var(--font-Inter)}.font-Oswald{font-family:var(--font-Oswald)}.font-Pacifico{font-family:var(--font-Pacifico)}.font-Roboto{font-family:var(--font-Roboto)}.font-\[Caveat\]{font-family:Caveat}.font-\[Inter\]{font-family:Inter}.font-\[Oswald\]{font-family:Oswald}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.text-8xl{font-size:var(--text-8xl);line-height:var(--tw-leading,var(--text-8xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-extralight{--tw-font-weight:var(--font-weight-extralight);font-weight:var(--font-weight-extralight)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.text-\[\#68A6F7\]{color:#68a6f7}.text-\[\#436EA6\]{color:#436ea6}.text-\[\#975555\]{color:#975555}.text-\[\#AB486A\]{color:#ab486a}.text-\[\#D4B062\]{color:#d4b062}.text-\[\#FEC613\]{color:#fec613}.text-amber-100{color:var(--color-amber-100)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-amber-950{color:var(--color-amber-950)}.text-black{color:var(--color-black)}.text-blue-200{color:var(--color-blue-200)}.text-blue-500{color:var(--color-blue-500)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-blue-900{color:var(--color-blue-900)}.text-blue-950{color:var(--color-blue-950)}.text-cyan-700{color:var(--color-cyan-700)}.text-cyan-950{color:var(--color-cyan-950)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-100{color:var(--color-gray-100)}.text-gray-200{color:var(--color-gray-200)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-500{color:var(--color-green-500)}.text-green-600{color:var(--color-green-600)}.text-green-800{color:var(--color-green-800)}.text-green-950{color:var(--color-green-950)}.text-pink-600{color:var(--color-pink-600)}.text-pink-700{color:var(--color-pink-700)}.text-purple-600{color:var(--color-purple-600)}.text-purple-700{color:var(--color-purple-700)}.text-purple-800{color:var(--color-purple-800)}.text-purple-950{color:var(--color-purple-950)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-red-800{color:var(--color-red-800)}.text-rose-500{color:var(--color-rose-500)}.text-slate-100{color:var(--color-slate-100)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-transparent{color:#0000}.text-white{color:var(--color-white)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-800{color:var(--color-yellow-800)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.not-italic{font-style:normal}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.decoration-dotted{text-decoration-style:dotted}.opacity-0{opacity:0}.opacity-5{opacity:.05}.opacity-10{opacity:.1}.opacity-15{opacity:.15}.opacity-20{opacity:.2}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-90{opacity:.9}.mix-blend-overlay{mix-blend-mode:overlay}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[rgba\(13\,_38\,_76\,_0\.19\)_0px_9px_20px\]{--tw-shadow-color:#0d264c30}@supports (color:color-mix(in lab,red,red)){.shadow-\[rgba\(13\,_38\,_76\,_0\.19\)_0px_9px_20px\]{--tw-shadow-color:color-mix(in oklab,#0d264c30 0px 9px 20px var(--tw-shadow-alpha),transparent)}}.ring-black{--tw-ring-color:var(--color-black)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur-2xl{--tw-blur:blur(var(--blur-2xl));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.blur-xl{--tw-blur:blur(var(--blur-xl));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.brightness-0{--tw-brightness:brightness(0%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-md{--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,visibility,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-none{transition-property:none}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.duration-700{--tw-duration:.7s;transition-duration:.7s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-all{-webkit-user-select:all;user-select:all}.select-none{-webkit-user-select:none;user-select:none}.\[--duration\:20s\]{--duration:20s}.\[--duration\:40s\]{--duration:40s}.\[--gap\:1rem\]{--gap:1rem}.\[animation-direction\:reverse\]{animation-direction:reverse}.\[perspective\:300px\]{perspective:300px}.duration-200{animation-duration:.2s}.duration-300{animation-duration:.3s}.duration-500{animation-duration:.5s}.duration-700{animation-duration:.7s}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{animation-timing-function:cubic-bezier(0,0,.2,1)}.fade-in{--tw-enter-opacity:0}.fade-out{--tw-exit-opacity:0}.paused{animation-play-state:paused}.running{animation-play-state:running}.zoom-out{--tw-exit-scale:0}@media (hover:hover){.group-hover\:mr-2:is(:where(.group):hover *){margin-right:calc(var(--spacing)*2)}.group-hover\:w-2:is(:where(.group):hover *){width:calc(var(--spacing)*2)}.group-hover\:translate-x-1:is(:where(.group):hover *){--tw-translate-x:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.group-hover\:scale-100:is(:where(.group):hover *){--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.group-hover\:scale-105:is(:where(.group):hover *){--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.group-hover\:scale-110:is(:where(.group):hover *){--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}.group-hover\:scale-x-100:is(:where(.group):hover *){--tw-scale-x:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.group-hover\:scale-\[1\.02\]:is(:where(.group):hover *){scale:1.02}.group-hover\:rotate-1:is(:where(.group):hover *){rotate:1deg}.group-hover\:bg-red-200:is(:where(.group):hover *){background-color:var(--color-red-200)}.group-hover\:bg-white\/20:is(:where(.group):hover *){background-color:#fff3}@supports (color:color-mix(in lab,red,red)){.group-hover\:bg-white\/20:is(:where(.group):hover *){background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.group-hover\:text-blue-600:is(:where(.group):hover *){color:var(--color-blue-600)}.group-hover\:text-blue-700:is(:where(.group):hover *){color:var(--color-blue-700)}.group-hover\:text-gray-200:is(:where(.group):hover *){color:var(--color-gray-200)}.group-hover\:text-red-700:is(:where(.group):hover *){color:var(--color-red-700)}.group-hover\:opacity-10:is(:where(.group):hover *){opacity:.1}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\:shadow-md:is(:where(.group):hover *){--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.group-hover\:shadow-blue-500\/10:is(:where(.group):hover *){--tw-shadow-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.group-hover\:shadow-blue-500\/10:is(:where(.group):hover *){--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-blue-500)10%,transparent)var(--tw-shadow-alpha),transparent)}}.group-hover\:\[animation-play-state\:paused\]:is(:where(.group):hover *){animation-play-state:paused}}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:inset-0:before{content:var(--tw-content);inset:calc(var(--spacing)*0)}.before\:translate-x-\[-150\%\]:before{content:var(--tw-content);--tw-translate-x:-150%;translate:var(--tw-translate-x)var(--tw-translate-y)}.before\:skew-x-\[45deg\]:before{content:var(--tw-content);--tw-skew-x:skewX(45deg);transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.before\:rounded-xl:before{content:var(--tw-content);border-radius:calc(var(--radius) + 4px)}.before\:bg-gray-400\/20:before{content:var(--tw-content);background-color:#99a1af33}@supports (color:color-mix(in lab,red,red)){.before\:bg-gray-400\/20:before{background-color:color-mix(in oklab,var(--color-gray-400)20%,transparent)}}.before\:bg-white\/20:before{content:var(--tw-content);background-color:#fff3}@supports (color:color-mix(in lab,red,red)){.before\:bg-white\/20:before{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.before\:bg-gradient-to-r:before{content:var(--tw-content);--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.before\:from-blue-500\/20:before{content:var(--tw-content);--tw-gradient-from:#3080ff33}@supports (color:color-mix(in lab,red,red)){.before\:from-blue-500\/20:before{--tw-gradient-from:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.before\:from-blue-500\/20:before{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.before\:to-purple-500\/20:before{content:var(--tw-content);--tw-gradient-to:#ac4bff33}@supports (color:color-mix(in lab,red,red)){.before\:to-purple-500\/20:before{--tw-gradient-to:color-mix(in oklab,var(--color-purple-500)20%,transparent)}}.before\:to-purple-500\/20:before{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.before\:opacity-0:before{content:var(--tw-content);opacity:0}.before\:transition-opacity:before{content:var(--tw-content);transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.before\:transition-transform:before{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.before\:duration-300:before{content:var(--tw-content);--tw-duration:.3s;transition-duration:.3s}.before\:duration-700:before{content:var(--tw-content);--tw-duration:.7s;transition-duration:.7s}.before\:duration-300:before{content:var(--tw-content);animation-duration:.3s}.before\:duration-700:before{content:var(--tw-content);animation-duration:.7s}.last\:border-r-0:last-child{border-right-style:var(--tw-border-style);border-right-width:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media (hover:hover){.hover\:-translate-y-1:hover{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.hover\:translate-y-\[-4px\]:hover{--tw-translate-y:-4px;translate:var(--tw-translate-x)var(--tw-translate-y)}.hover\:scale-102:hover{--tw-scale-x:102%;--tw-scale-y:102%;--tw-scale-z:102%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:scale-110:hover{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:scale-\[1\.01\]:hover{scale:1.01}.hover\:scale-\[1\.02\]:hover{scale:1.02}.hover\:transform-none:hover{transform:none}.hover\:cursor-pointer:hover{cursor:pointer}.hover\:border-blue-300:hover{border-color:var(--color-blue-300)}.hover\:border-gray-200:hover{border-color:var(--color-gray-200)}.hover\:bg-\[\#D4B062\]\/5:hover{background-color:#d4b0620d}.hover\:bg-blue-50:hover{background-color:var(--color-blue-50)}.hover\:bg-blue-100:hover{background-color:var(--color-blue-100)}.hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-100\/80:hover{background-color:#f3f4f6cc}@supports (color:color-mix(in lab,red,red)){.hover\:bg-gray-100\/80:hover{background-color:color-mix(in oklab,var(--color-gray-100)80%,transparent)}}.hover\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\:bg-gray-300:hover{background-color:var(--color-gray-300)}.hover\:bg-gray-700:hover{background-color:var(--color-gray-700)}.hover\:bg-gray-900:hover{background-color:var(--color-gray-900)}.hover\:bg-gray-950\/\[\.05\]:hover{background-color:#0307120d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-gray-950\/\[\.05\]:hover{background-color:color-mix(in oklab,var(--color-gray-950)5%,transparent)}}.hover\:bg-green-700:hover{background-color:var(--color-green-700)}.hover\:bg-indigo-700:hover{background-color:var(--color-indigo-700)}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:bg-white:hover{background-color:var(--color-white)}.hover\:bg-white\/30:hover{background-color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/30:hover{background-color:color-mix(in oklab,var(--color-white)30%,transparent)}}.hover\:bg-yellow-500:hover{background-color:var(--color-yellow-500)}.hover\:bg-gradient-to-r:hover{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.hover\:from-amber-700:hover{--tw-gradient-from:var(--color-amber-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:from-blue-100:hover{--tw-gradient-from:var(--color-blue-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:from-blue-700:hover{--tw-gradient-from:var(--color-blue-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:from-blue-800:hover{--tw-gradient-from:var(--color-blue-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:from-cyan-800:hover{--tw-gradient-from:var(--color-cyan-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:from-green-800:hover{--tw-gradient-from:var(--color-green-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:from-purple-800:hover{--tw-gradient-from:var(--color-purple-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:to-blue-800:hover{--tw-gradient-to:var(--color-blue-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:to-emerald-900:hover{--tw-gradient-to:var(--color-emerald-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:to-fuchsia-900:hover{--tw-gradient-to:var(--color-fuchsia-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:to-green-100:hover{--tw-gradient-to:var(--color-green-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:to-green-600:hover{--tw-gradient-to:var(--color-green-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:to-green-700:hover{--tw-gradient-to:var(--color-green-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:to-indigo-900:hover{--tw-gradient-to:var(--color-indigo-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:to-orange-800:hover{--tw-gradient-to:var(--color-orange-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:to-sky-900:hover{--tw-gradient-to:var(--color-sky-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:text-black:hover{color:var(--color-black)}.hover\:text-blue-600:hover{color:var(--color-blue-600)}.hover\:text-blue-700:hover{color:var(--color-blue-700)}.hover\:text-blue-800:hover{color:var(--color-blue-800)}.hover\:text-gray-300:hover{color:var(--color-gray-300)}.hover\:text-green-700:hover{color:var(--color-green-700)}.hover\:text-red-500:hover{color:var(--color-red-500)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:text-white:hover{color:var(--color-white)}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-2xl:hover{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-xl:hover{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-\[rgba\(13\,_38\,_76\,_0\.25\)_0px_12px_28px\]:hover{--tw-shadow-color:#0d264c40}@supports (color:color-mix(in lab,red,red)){.hover\:shadow-\[rgba\(13\,_38\,_76\,_0\.25\)_0px_12px_28px\]:hover{--tw-shadow-color:color-mix(in oklab,#0d264c40 0px 12px 28px var(--tw-shadow-alpha),transparent)}}.hover\:shadow-blue-500\/10:hover{--tw-shadow-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.hover\:shadow-blue-500\/10:hover{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-blue-500)10%,transparent)var(--tw-shadow-alpha),transparent)}}.hover\:shadow-gray-800\/30:hover{--tw-shadow-color:#1e29394d}@supports (color:color-mix(in lab,red,red)){.hover\:shadow-gray-800\/30:hover{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-gray-800)30%,transparent)var(--tw-shadow-alpha),transparent)}}.hover\:before\:translate-x-\[150\%\]:hover:before{content:var(--tw-content);--tw-translate-x:150%;translate:var(--tw-translate-x)var(--tw-translate-y)}.hover\:before\:opacity-100:hover:before{content:var(--tw-content);opacity:1}}.focus\:border-transparent:focus{border-color:#0000}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-\[\#D4B062\]:focus{--tw-ring-color:#d4b062}.focus\:ring-blue-400:focus{--tw-ring-color:var(--color-blue-400)}.focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\:ring-white:focus{--tw-ring-color:var(--color-white)}.focus\:ring-white\/50:focus{--tw-ring-color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.focus\:ring-white\/50:focus{--tw-ring-color:color-mix(in oklab,var(--color-white)50%,transparent)}}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x)var(--tw-scale-y)}@media not all and (min-width:1040px){.max-\[1040px\]\:hidden{display:none}}@media not all and (min-width:400px){.max-\[400px\]\:hidden{display:none}}@media (min-width:40rem){.sm\:top-10{top:calc(var(--spacing)*10)}.sm\:top-\[65vh\]{top:65vh}.sm\:right-10{right:calc(var(--spacing)*10)}.sm\:right-\[15vw\]{right:15vw}.sm\:right-\[50vw\]{right:50vw}.sm\:bottom-2{bottom:calc(var(--spacing)*2)}.sm\:bottom-10{bottom:calc(var(--spacing)*10)}.sm\:left-6{left:calc(var(--spacing)*6)}.sm\:left-10{left:calc(var(--spacing)*10)}.sm\:left-\[30vw\]{left:30vw}.sm\:left-\[35vw\]{left:35vw}.sm\:col-span-2{grid-column:span 2/span 2}.sm\:-mx-2{margin-inline:calc(var(--spacing)*-2)}.sm\:-mx-5{margin-inline:calc(var(--spacing)*-5)}.sm\:my-16{margin-block:calc(var(--spacing)*16)}.sm\:mt-0{margin-top:calc(var(--spacing)*0)}.sm\:mt-1{margin-top:calc(var(--spacing)*1)}.sm\:mt-2{margin-top:calc(var(--spacing)*2)}.sm\:mt-5{margin-top:calc(var(--spacing)*5)}.sm\:mt-6{margin-top:calc(var(--spacing)*6)}.sm\:mt-8{margin-top:calc(var(--spacing)*8)}.sm\:mt-10{margin-top:calc(var(--spacing)*10)}.sm\:mt-12{margin-top:calc(var(--spacing)*12)}.sm\:mt-14{margin-top:calc(var(--spacing)*14)}.sm\:-mb-5{margin-bottom:calc(var(--spacing)*-5)}.sm\:mb-2{margin-bottom:calc(var(--spacing)*2)}.sm\:mb-3{margin-bottom:calc(var(--spacing)*3)}.sm\:mb-4{margin-bottom:calc(var(--spacing)*4)}.sm\:mb-6{margin-bottom:calc(var(--spacing)*6)}.sm\:mb-8{margin-bottom:calc(var(--spacing)*8)}.sm\:mb-9{margin-bottom:calc(var(--spacing)*9)}.sm\:mb-10{margin-bottom:calc(var(--spacing)*10)}.sm\:mb-12{margin-bottom:calc(var(--spacing)*12)}.sm\:mb-16{margin-bottom:calc(var(--spacing)*16)}.sm\:ml-2{margin-left:calc(var(--spacing)*2)}.sm\:ml-3\.5{margin-left:calc(var(--spacing)*3.5)}.sm\:line-clamp-none{-webkit-line-clamp:unset;-webkit-box-orient:horizontal;display:block;overflow:visible}.sm\:flex{display:flex}.sm\:inline{display:inline}.sm\:h-1{height:calc(var(--spacing)*1)}.sm\:h-1\.5{height:calc(var(--spacing)*1.5)}.sm\:h-2\.5{height:calc(var(--spacing)*2.5)}.sm\:h-4{height:calc(var(--spacing)*4)}.sm\:h-5{height:calc(var(--spacing)*5)}.sm\:h-6{height:calc(var(--spacing)*6)}.sm\:h-8{height:calc(var(--spacing)*8)}.sm\:h-10{height:calc(var(--spacing)*10)}.sm\:h-12{height:calc(var(--spacing)*12)}.sm\:h-14{height:calc(var(--spacing)*14)}.sm\:h-20{height:calc(var(--spacing)*20)}.sm\:h-24{height:calc(var(--spacing)*24)}.sm\:h-28{height:calc(var(--spacing)*28)}.sm\:h-32{height:calc(var(--spacing)*32)}.sm\:h-40{height:calc(var(--spacing)*40)}.sm\:h-48{height:calc(var(--spacing)*48)}.sm\:h-56{height:calc(var(--spacing)*56)}.sm\:h-64{height:calc(var(--spacing)*64)}.sm\:h-96{height:calc(var(--spacing)*96)}.sm\:h-\[400px\]{height:400px}.sm\:h-full{height:100%}.sm\:w-1\/4{width:25%}.sm\:w-2\.5{width:calc(var(--spacing)*2.5)}.sm\:w-3\/4{width:75%}.sm\:w-4{width:calc(var(--spacing)*4)}.sm\:w-5{width:calc(var(--spacing)*5)}.sm\:w-6{width:calc(var(--spacing)*6)}.sm\:w-8{width:calc(var(--spacing)*8)}.sm\:w-12{width:calc(var(--spacing)*12)}.sm\:w-14{width:calc(var(--spacing)*14)}.sm\:w-20{width:calc(var(--spacing)*20)}.sm\:w-24{width:calc(var(--spacing)*24)}.sm\:w-28{width:calc(var(--spacing)*28)}.sm\:w-32{width:calc(var(--spacing)*32)}.sm\:w-48{width:calc(var(--spacing)*48)}.sm\:w-96{width:calc(var(--spacing)*96)}.sm\:w-\[80\%\]{width:80%}.sm\:w-auto{width:auto}.sm\:max-w-\[220px\]{max-width:220px}.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:max-w-sm{max-width:var(--container-sm)}.sm\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:items-start{align-items:flex-start}.sm\:justify-start{justify-content:flex-start}.sm\:gap-3{gap:calc(var(--spacing)*3)}.sm\:gap-4{gap:calc(var(--spacing)*4)}.sm\:gap-6{gap:calc(var(--spacing)*6)}.sm\:gap-8{gap:calc(var(--spacing)*8)}.sm\:gap-10{gap:calc(var(--spacing)*10)}:where(.sm\:space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.sm\:space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.sm\:space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.sm\:space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.sm\:space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}:where(.sm\:space-y-16>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*16)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*16)*calc(1 - var(--tw-space-y-reverse)))}:where(.sm\:space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}.sm\:gap-y-0{row-gap:calc(var(--spacing)*0)}.sm\:self-auto{align-self:auto}.sm\:rounded-2xl{border-radius:var(--radius-2xl)}.sm\:rounded-3xl{border-radius:var(--radius-3xl)}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:rounded-xl{border-radius:calc(var(--radius) + 4px)}.sm\:p-0{padding:calc(var(--spacing)*0)}.sm\:p-2\.5{padding:calc(var(--spacing)*2.5)}.sm\:p-3{padding:calc(var(--spacing)*3)}.sm\:p-4{padding:calc(var(--spacing)*4)}.sm\:p-5{padding:calc(var(--spacing)*5)}.sm\:p-6{padding:calc(var(--spacing)*6)}.sm\:p-8{padding:calc(var(--spacing)*8)}.sm\:px-3{padding-inline:calc(var(--spacing)*3)}.sm\:px-4{padding-inline:calc(var(--spacing)*4)}.sm\:px-5{padding-inline:calc(var(--spacing)*5)}.sm\:px-6{padding-inline:calc(var(--spacing)*6)}.sm\:px-8{padding-inline:calc(var(--spacing)*8)}.sm\:py-2{padding-block:calc(var(--spacing)*2)}.sm\:py-2\.5{padding-block:calc(var(--spacing)*2.5)}.sm\:py-3{padding-block:calc(var(--spacing)*3)}.sm\:py-4{padding-block:calc(var(--spacing)*4)}.sm\:py-8{padding-block:calc(var(--spacing)*8)}.sm\:py-10{padding-block:calc(var(--spacing)*10)}.sm\:py-16{padding-block:calc(var(--spacing)*16)}.sm\:py-20{padding-block:calc(var(--spacing)*20)}.sm\:pt-3{padding-top:calc(var(--spacing)*3)}.sm\:pt-6{padding-top:calc(var(--spacing)*6)}.sm\:pt-12{padding-top:calc(var(--spacing)*12)}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}.sm\:text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.sm\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.sm\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.sm\:text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.sm\:text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.sm\:text-7xl{font-size:var(--text-7xl);line-height:var(--tw-leading,var(--text-7xl--line-height))}.sm\:text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.sm\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.sm\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.sm\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.sm\:text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.sm\:leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.sm\:shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.sm\:shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.sm\:shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.sm\:blur-2xl{--tw-blur:blur(var(--blur-2xl));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.sm\:blur-3xl{--tw-blur:blur(var(--blur-3xl));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}}@media (min-width:48rem){.md\:top-\[15vh\]{top:15vh}.md\:left-12{left:calc(var(--spacing)*12)}.md\:left-\[35vw\]{left:35vw}.md\:order-1{order:1}.md\:order-2{order:2}.md\:-mx-6{margin-inline:calc(var(--spacing)*-6)}.md\:mt-0{margin-top:calc(var(--spacing)*0)}.md\:mt-6{margin-top:calc(var(--spacing)*6)}.md\:mt-16{margin-top:calc(var(--spacing)*16)}.md\:-mb-6{margin-bottom:calc(var(--spacing)*-6)}.md\:mb-0{margin-bottom:calc(var(--spacing)*0)}.md\:mb-2{margin-bottom:calc(var(--spacing)*2)}.md\:mb-6{margin-bottom:calc(var(--spacing)*6)}.md\:mb-10{margin-bottom:calc(var(--spacing)*10)}.md\:mb-16{margin-bottom:calc(var(--spacing)*16)}.md\:mb-24{margin-bottom:calc(var(--spacing)*24)}.md\:ml-6{margin-left:calc(var(--spacing)*6)}.md\:block{display:block}.md\:flex{display:flex}.md\:grid{display:grid}.md\:hidden{display:none}.md\:h-6{height:calc(var(--spacing)*6)}.md\:h-12{height:calc(var(--spacing)*12)}.md\:h-20{height:calc(var(--spacing)*20)}.md\:h-24{height:calc(var(--spacing)*24)}.md\:h-48{height:calc(var(--spacing)*48)}.md\:h-64{height:calc(var(--spacing)*64)}.md\:h-\[400px\]{height:400px}.md\:h-\[500px\]{height:500px}.md\:w-1\/2{width:50%}.md\:w-1\/4{width:25%}.md\:w-3\/4{width:75%}.md\:w-4\/5{width:80%}.md\:w-6{width:calc(var(--spacing)*6)}.md\:w-10{width:calc(var(--spacing)*10)}.md\:w-12{width:calc(var(--spacing)*12)}.md\:w-24{width:calc(var(--spacing)*24)}.md\:w-\[70\%\]{width:70%}.md\:w-\[400px\]{width:400px}.md\:max-w-3xl{max-width:var(--container-3xl)}.md\:max-w-lg{max-width:var(--container-lg)}.md\:max-w-xs{max-width:var(--container-xs)}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:flex-row-reverse{flex-direction:row-reverse}.md\:items-center{align-items:center}.md\:items-start{align-items:flex-start}.md\:justify-between{justify-content:space-between}.md\:justify-end{justify-content:flex-end}.md\:gap-4{gap:calc(var(--spacing)*4)}.md\:gap-6{gap:calc(var(--spacing)*6)}.md\:gap-8{gap:calc(var(--spacing)*8)}.md\:gap-10{gap:calc(var(--spacing)*10)}.md\:gap-16{gap:calc(var(--spacing)*16)}:where(.md\:space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*0)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*0)*calc(1 - var(--tw-space-y-reverse)))}:where(.md\:space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.md\:space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.md\:space-y-10>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*10)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*10)*calc(1 - var(--tw-space-y-reverse)))}:where(.md\:space-y-16>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*16)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*16)*calc(1 - var(--tw-space-y-reverse)))}:where(.md\:space-y-20>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*20)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*20)*calc(1 - var(--tw-space-y-reverse)))}:where(.md\:space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*4)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-x-reverse)))}.md\:rounded-3xl{border-radius:var(--radius-3xl)}.md\:p-6{padding:calc(var(--spacing)*6)}.md\:p-8{padding:calc(var(--spacing)*8)}.md\:px-4{padding-inline:calc(var(--spacing)*4)}.md\:px-5{padding-inline:calc(var(--spacing)*5)}.md\:px-6{padding-inline:calc(var(--spacing)*6)}.md\:px-8{padding-inline:calc(var(--spacing)*8)}.md\:px-10{padding-inline:calc(var(--spacing)*10)}.md\:px-12{padding-inline:calc(var(--spacing)*12)}.md\:py-3{padding-block:calc(var(--spacing)*3)}.md\:py-12{padding-block:calc(var(--spacing)*12)}.md\:py-15{padding-block:calc(var(--spacing)*15)}.md\:py-20{padding-block:calc(var(--spacing)*20)}.md\:py-24{padding-block:calc(var(--spacing)*24)}.md\:py-28{padding-block:calc(var(--spacing)*28)}.md\:pt-2{padding-top:calc(var(--spacing)*2)}.md\:pt-16{padding-top:calc(var(--spacing)*16)}.md\:pt-20{padding-top:calc(var(--spacing)*20)}.md\:pr-8{padding-right:calc(var(--spacing)*8)}.md\:pr-12{padding-right:calc(var(--spacing)*12)}.md\:pb-2{padding-bottom:calc(var(--spacing)*2)}.md\:text-left{text-align:left}.md\:text-right{text-align:right}.md\:text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.md\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.md\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.md\:text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.md\:text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.md\:text-7xl{font-size:var(--text-7xl);line-height:var(--tw-leading,var(--text-7xl--line-height))}.md\:text-8xl{font-size:var(--text-8xl);line-height:var(--tw-leading,var(--text-8xl--line-height))}.md\:text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.md\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.md\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.md\:text-\[5rem\]{font-size:5rem}.md\:text-\[10rem\]{font-size:10rem}}@media (min-width:64rem){.lg\:order-1{order:1}.lg\:order-2{order:2}.lg\:col-span-3{grid-column:span 3/span 3}.lg\:col-span-5{grid-column:span 5/span 5}.lg\:col-span-6{grid-column:span 6/span 6}.lg\:col-span-7{grid-column:span 7/span 7}.lg\:mb-0{margin-bottom:calc(var(--spacing)*0)}.lg\:mb-8{margin-bottom:calc(var(--spacing)*8)}.lg\:block{display:block}.lg\:h-16{height:calc(var(--spacing)*16)}.lg\:h-32{height:calc(var(--spacing)*32)}.lg\:h-96{height:calc(var(--spacing)*96)}.lg\:h-\[600px\]{height:600px}.lg\:w-1\/2{width:50%}.lg\:w-16{width:calc(var(--spacing)*16)}.lg\:w-32{width:calc(var(--spacing)*32)}.lg\:w-\[60\%\]{width:60%}.lg\:w-\[500px\]{width:500px}.lg\:w-auto{width:auto}.lg\:max-w-2xl{max-width:var(--container-2xl)}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:gap-4{gap:calc(var(--spacing)*4)}.lg\:gap-8{gap:calc(var(--spacing)*8)}.lg\:gap-12{gap:calc(var(--spacing)*12)}.lg\:gap-20{gap:calc(var(--spacing)*20)}.lg\:gap-x-8{column-gap:calc(var(--spacing)*8)}:where(.lg\:space-x-8>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*8)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-x-reverse)))}.lg\:p-8{padding:calc(var(--spacing)*8)}.lg\:p-10{padding:calc(var(--spacing)*10)}.lg\:p-12{padding:calc(var(--spacing)*12)}.lg\:px-3{padding-inline:calc(var(--spacing)*3)}.lg\:px-6{padding-inline:calc(var(--spacing)*6)}.lg\:px-8{padding-inline:calc(var(--spacing)*8)}.lg\:px-16{padding-inline:calc(var(--spacing)*16)}.lg\:py-2\.5{padding-block:calc(var(--spacing)*2.5)}.lg\:py-16{padding-block:calc(var(--spacing)*16)}.lg\:pl-8{padding-left:calc(var(--spacing)*8)}.lg\:pl-20{padding-left:calc(var(--spacing)*20)}.lg\:text-left{text-align:left}.lg\:text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.lg\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.lg\:text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.lg\:text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.lg\:text-7xl{font-size:var(--text-7xl);line-height:var(--tw-leading,var(--text-7xl--line-height))}.lg\:text-8xl{font-size:var(--text-8xl);line-height:var(--tw-leading,var(--text-8xl--line-height))}.lg\:text-9xl{font-size:var(--text-9xl);line-height:var(--tw-leading,var(--text-9xl--line-height))}.lg\:text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.lg\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.lg\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}}@media (min-width:80rem){.xl\:order-1{order:1}.xl\:order-2{order:2}.xl\:col-span-3{grid-column:span 3/span 3}.xl\:h-\[700px\]{height:700px}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:text-7xl{font-size:var(--text-7xl);line-height:var(--tw-leading,var(--text-7xl--line-height))}}.dark\:border-gray-50:is(.dark *){border-color:var(--color-gray-50)}.dark\:border-gray-50\/\[\.1\]:is(.dark *){border-color:#f9fafb1a}@supports (color:color-mix(in lab,red,red)){.dark\:border-gray-50\/\[\.1\]:is(.dark *){border-color:color-mix(in oklab,var(--color-gray-50)10%,transparent)}}.dark\:border-gray-700:is(.dark *){border-color:var(--color-gray-700)}.dark\:bg-gray-50\/\[\.10\]:is(.dark *){background-color:#f9fafb1a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-50\/\[\.10\]:is(.dark *){background-color:color-mix(in oklab,var(--color-gray-50)10%,transparent)}}.dark\:bg-gray-900:is(.dark *){background-color:var(--color-gray-900)}.dark\:from-indigo-900\/20:is(.dark *){--tw-gradient-from:#312c8533}@supports (color:color-mix(in lab,red,red)){.dark\:from-indigo-900\/20:is(.dark *){--tw-gradient-from:color-mix(in oklab,var(--color-indigo-900)20%,transparent)}}.dark\:from-indigo-900\/20:is(.dark *){--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.dark\:via-purple-900\/20:is(.dark *){--tw-gradient-via:#59168b33}@supports (color:color-mix(in lab,red,red)){.dark\:via-purple-900\/20:is(.dark *){--tw-gradient-via:color-mix(in oklab,var(--color-purple-900)20%,transparent)}}.dark\:via-purple-900\/20:is(.dark *){--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.dark\:to-pink-900\/20:is(.dark *){--tw-gradient-to:#86104333}@supports (color:color-mix(in lab,red,red)){.dark\:to-pink-900\/20:is(.dark *){--tw-gradient-to:color-mix(in oklab,var(--color-pink-900)20%,transparent)}}.dark\:to-pink-900\/20:is(.dark *){--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.dark\:text-\[\#975555\]:is(.dark *){color:#975555}.dark\:text-blue-600:is(.dark *){color:var(--color-blue-600)}.dark\:text-emerald-400:is(.dark *){color:var(--color-emerald-400)}.dark\:text-gray-300:is(.dark *){color:var(--color-gray-300)}.dark\:text-gray-400:is(.dark *){color:var(--color-gray-400)}.dark\:text-rose-400:is(.dark *){color:var(--color-rose-400)}.dark\:text-slate-200:is(.dark *){color:var(--color-slate-200)}.dark\:text-white:is(.dark *){color:var(--color-white)}.dark\:text-white\/40:is(.dark *){color:#fff6}@supports (color:color-mix(in lab,red,red)){.dark\:text-white\/40:is(.dark *){color:color-mix(in oklab,var(--color-white)40%,transparent)}}.dark\:opacity-20:is(.dark *){opacity:.2}.dark\:opacity-30:is(.dark *){opacity:.3}.dark\:opacity-40:is(.dark *){opacity:.4}.dark\:opacity-80:is(.dark *){opacity:.8}@media (hover:hover){.dark\:hover\:bg-gray-50\/\[\.15\]:is(.dark *):hover{background-color:#f9fafb26}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-gray-50\/\[\.15\]:is(.dark *):hover{background-color:color-mix(in oklab,var(--color-gray-50)15%,transparent)}}}}:root{--background:oklch(100% 0 0);--foreground:oklch(14.1% .005 285.823);--card:oklch(100% 0 0);--card-foreground:oklch(14.1% .005 285.823);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.1% .005 285.823);--primary:oklch(21% .006 285.885);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(96.7% .001 286.375);--secondary-foreground:oklch(21% .006 285.885);--muted:oklch(96.7% .001 286.375);--muted-foreground:oklch(55.2% .016 285.938);--accent:oklch(96.7% .001 286.375);--accent-foreground:oklch(21% .006 285.885);--destructive:oklch(57.7% .245 27.325);--destructive-foreground:oklch(57.7% .245 27.325);--border:oklch(92% .004 286.32);--input:oklch(92% .004 286.32);--ring:oklch(87.1% .006 286.286);--chart-1:oklch(64.6% .222 41.116);--chart-2:oklch(60% .118 184.704);--chart-3:oklch(39.8% .07 227.392);--chart-4:oklch(82.8% .189 84.429);--chart-5:oklch(76.9% .188 70.08);--radius:.625rem;--sidebar:oklch(98.5% 0 0);--sidebar-foreground:oklch(14.1% .005 285.823);--sidebar-primary:oklch(21% .006 285.885);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(96.7% .001 286.375);--sidebar-accent-foreground:oklch(21% .006 285.885);--sidebar-border:oklch(92% .004 286.32);--sidebar-ring:oklch(87.1% .006 286.286)}.dark{--background:oklch(14.1% .005 285.823);--foreground:oklch(98.5% 0 0);--card:oklch(14.1% .005 285.823);--card-foreground:oklch(98.5% 0 0);--popover:oklch(14.1% .005 285.823);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(98.5% 0 0);--primary-foreground:oklch(21% .006 285.885);--secondary:oklch(27.4% .006 286.033);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(27.4% .006 286.033);--muted-foreground:oklch(70.5% .015 286.067);--accent:oklch(27.4% .006 286.033);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(39.6% .141 25.723);--destructive-foreground:oklch(63.7% .237 25.331);--border:oklch(27.4% .006 286.033);--input:oklch(27.4% .006 286.033);--ring:oklch(44.2% .017 285.786);--chart-1:oklch(48.8% .243 264.376);--chart-2:oklch(69.6% .17 162.48);--chart-3:oklch(76.9% .188 70.08);--chart-4:oklch(62.7% .265 303.9);--chart-5:oklch(64.5% .246 16.439);--sidebar:oklch(21% .006 285.885);--sidebar-foreground:oklch(98.5% 0 0);--sidebar-primary:oklch(48.8% .243 264.376);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(27.4% .006 286.033);--sidebar-accent-foreground:oklch(98.5% 0 0);--sidebar-border:oklch(27.4% .006 286.033);--sidebar-ring:oklch(44.2% .017 285.786)}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-pan-x{syntax:"*";inherits:false}@property --tw-pan-y{syntax:"*";inherits:false}@property --tw-pinch-zoom{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}@keyframes marquee{0%{transform:translate(0)}to{transform:translate(calc(-100% - var(--gap)))}}@keyframes marquee-vertical{0%{transform:translateY(0)}to{transform:translateY(calc(-100% - var(--gap)))}} diff --git a/assets/mdfiles-Dv9bnDYr.js b/assets/mdfiles-Dv9bnDYr.js new file mode 100644 index 00000000..d1aa84ac --- /dev/null +++ b/assets/mdfiles-Dv9bnDYr.js @@ -0,0 +1,14852 @@ +const e=`--- +name: "Aditya Kumar Singh" +slug: "aditya-singh" +title: "GSoC'25 Contributor" +organization: "SugarLabs" +description: "GSoC'25 Contributor at SugarLabs" +avatar: "https://avatars.githubusercontent.com/u/128071145?v=4" + +--- + + +<!--markdownlint-disable--> + +# About Aditya Kumar Singh + +Hi! I'm Aditya Kumar Singh, a passionate software developer and open-source enthusiast from India, I'm currently pursuing my Bachelor's in Information Technology. I'm excited to be working with Sugar Labs as a GSoC 2025 contributor, where I'm enhancing the 3D Human Body and Stickman Animation Activities for Sugarizer. + +## Experience + +- **GSoC 2025 Contributor at Sugar Labs** + Working on Sugarizer Human Activity Pack enhancing the 3D Human Body Activity with anatomical layer toggling, Doctor Mode, and multiplayer support, and building a Stickman Animator with AI-based pose estimation. + +## Current Projects + +- **3D Human Body Activity (Sugarizer)** + A fully interactive anatomical learning tool using Three.js, localized UI, and collaborative learning features. + +- **Stickman Animation Activity (Sugarizer)** + A creative animation tool where users can build motion sequences using a skeletal system, with onion skinning, AI-based pose estimation, and video export. + + +## Connect with Me + +- **GitHub**: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) +- **Email**: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) +- **LinkedIn**: [Aditya Kumar Singh](https://linkedin.com/in/adityakrsingh26) +- **Website**: [aditya-singh.me](https://aditya-singh.me) +- **Discord**: [praise_dark_lord](https://discord.com/users/praise_dark_lord) +`,Ct=Object.freeze(Object.defineProperty({__proto__:null,default:e},Symbol.toStringTag,{value:"Module"})),n=`---\r +name: "Aman Chadha"\r +slug: "aman-chadha"\r +title: "DMP'25 Contributor"\r +organization: "SugarLabs"\r +description: "DMP'25 Contributor at SugarLabs"\r +avatar: "https://avatars.githubusercontent.com/u/79802170?v=4"\r +---\r +\r +<!--markdownlint-disable-->\r +\r +# About Aman Chadha\r +\r +I am a DMP 2025 contributor working with Sugar Labs on enhancing Music Blocks' internationalization system using AI-supported translation. I'm passionate about building intelligent systems, developer tools, and creative educational platforms that empower users across languages.\r +\r +## Experience\r +\r +- Contributor at Sugar Labs (DMP '25)\r +\r +## Current Projects\r +\r +- **JS Internationalization with AI Translation Support**: \r + Integrating a modern i18n workflow in Music Blocks and enhancing it with AI-powered fallback translations, context-aware retrieval, and part-of-speech–informed RAG models.\r +\r +## Connect with Me\r +\r +- **GitHub**: [@ac-mmi](https://github.com/ac-mmi)\r +- **Email**: [aman.chadha.mmi@gmail.com](mailto:aman.chadha.mmi@gmail.com)\r +\r +`,Mt=Object.freeze(Object.defineProperty({__proto__:null,default:n},Symbol.toStringTag,{value:"Module"})),t=`--- +name: "Aman Naik" +slug: "amannaik247" +title: "DMP'25 Contributor" +organization: "SugarLabs" +description: "DMP'25 Contributor at SugarLabs" +avatar: "https://avatars.githubusercontent.com/u/168978808?v=4" +--- + +<!--markdownlint-disable--> + +# About Aman Naik + +I’m someone who loves building smart tools that make life a little easier—whether it’s a chatbot that talks like Lord Krishna or a system that helps forecast real-time prices. I’ve explored everything from AI and machine learning to satellite data and creative writing prompts. I enjoy blending tech with storytelling, finding joy in both solving real problems and crafting meaningful experiences. For me, coding isn’t just logic, it’s a way to create things that connect with people. + +## Experience + +- DMP'25 contributor for SugarLabs +- Active Open Source Contributor + +## Current Projects + +Adding an AI-assistant to the Write Activity + +## Connect with Me + +- **GitHub**: [@amannaik247](https://github.com/amannaik247) +- **Email**: [amancodes247@gmail.com](mailto:your.email@example.com) +- **LinkedIn**: [Aman Naik](https://linkedin.com/in/aman-naik)`,xt=Object.freeze(Object.defineProperty({__proto__:null,default:t},Symbol.toStringTag,{value:"Module"})),a=`--- +name: "Anvita Prasad" +slug: "anvita-prasad" +title: "DMP'25 Contributor" +organization: "SugarLabs" +description: "DMP'25 Contributor at SugarLabs" +avatar: "https://avatars.githubusercontent.com/u/147875261?s=400&u=e784808241accea1d4c664bba0ce7bd6ca000662&v=4" +--- + +<!--markdownlint-disable--> + +# About Anvita Prasad + +Anvita is a DMP 2025 contributor at SugarLabs, working on improving synth and sample features in Music Blocks. A second-year Computer Science student at IIIT Kancheepuram and passionate open-source contributor, she strives to create meaningful and impactful experiences that bridge technology and creativity. + +## Experience + +- **DMP 2025**: Improving synth and sample features in Music Blocks +- **Sugar Labs Member**: Active contributor to Sugar's developer tooling and educational platforms +- **Music Theory**: Completed Grade 4 in Trinity music theory + +## Current Projects + +- Improving Synth and Sample Features in Music Blocks +- Music Blocks Developer + +## Connect with Me + +- **GitHub**: [@AnvitaPrasad](https://github.com/AnvitaPrasad) +- **Email**: [anvita.prasad1@gmail.com](mailto:anvita.prasad1@gmail.com) +- **LinkedIn**: [Anvita Prasad](https://www.linkedin.com/in/anvita-prasad) +- **Website**: [anvitaprasad.netlify.app](https://anvitaprasad.netlify.app/) `,Gt=Object.freeze(Object.defineProperty({__proto__:null,default:a},Symbol.toStringTag,{value:"Module"})),o=`--- +name: "Bishoy Wadea" +slug: "bishoy-wadea" +title: "GSoC'25 Contributor" +organization: "SugarLabs" +description: "GSoC'25 Contributor at SugarLabs" +avatar: "https://avatars.githubusercontent.com/u/108888519?s=400&u=084aa7be2ae3aedd1cf38175557820a49b7efa93&v=4" +--- + +<!--markdownlint-disable--> + +# About Bishoy Wadea + +I am **Bishoy Wadea**, a Google Summer of Code 2025 contributor with Sugar Labs, developing a suite of math games to make learning more engaging and interactive. With prior experience at Microsoft and currently an R&D engineer at Siemens, I am passionate about building open-source tools that make complex ideas fun and approachable for learners. + +## Experience + +- **GSoC 2025**: Developing interactive math games for Sugar Labs. +- **R&D Backend Engineer Intern – Siemens**: Contributing to backend systems with a focus on performance, reliability, and scalability. +- **Microsoft Summer Engineering Program**: Built and optimized a 7TB data pipeline. + +## Current Projects + +- Developing 10 interactive math games for Sugar Labs. + + +## Connect with Me + +- **GitHub**: [@bishoywadea](https://github.com/Bishoywadea) +- **Email**: [bishoyw.fathy@gmail.com](mailto:bishoyw.fathy@gmail.com) +- **LinkedIn**: [Bishoy Wadea](https://www.linkedin.com/in/bishoy-wadea-27b016250/)`,_t=Object.freeze(Object.defineProperty({__proto__:null,default:o},Symbol.toStringTag,{value:"Module"})),i=`--- +name: "Diwangshu Kakoty" +slug: "diwangshu-kakoty" +title: "GSoC'25 Contributor" +organization: "SugarLabs" +description: "Member and GSoC'25 Contributor at SugarLabs" +avatar: "https://avatars.githubusercontent.com/u/142284646?s=400&u=81be7e66ba1d554e6928fe267d68af5e2a90e359&v=4" +--- + +<!--markdownlint-disable--> + +# About Diwangshu Kakoty + +Hi, I'm Diwangshu - a B.Tech student and lifelong learner in computer science. I'm a dedicated contributor, community member, and a 2025 Google Summer of Code intern with SugarLabs, where I’m working on the project "AI Tools for Reflection." My passion lies in creativity and building meaningful solutions that benefit society, and I see coding as my way to bring those ideas to life. + + +## Experience + +- **GSoC 2025**: AI Tools for Reflection Learning +- **SugarLabs Member**: Active contributor to various projects +- C, JS and Python development + +## Current Projects + +- AI Tools for Reflection Learning +- Music Blocks 3 development + + +## Connect with Me + +- **GitHub**: [@Commanderk3](https://github.com/Commanderk3) +- **Email**: [diwangshukakoty@gmail.com](mailto:diwangshukakoty@gmail.com) +- **LinkedIn**: [Diwangshu Kakoty](https://www.linkedin.com/in/diwangshu-kakoty/) +- **Twitter**: [@redCoder101](https://twitter.com/redCoder101) +- **Discord**: [commanderk3](https://discord.com/users/commanderk3)`,Et=Object.freeze(Object.defineProperty({__proto__:null,default:i},Symbol.toStringTag,{value:"Module"})),r=`--- +name: "Elwin Li" +slug: "elwin-li" +title: "GSoC'25 Contributor" +organization: "SugarLabs" +description: "GSoC'25 Contributor at SugarLabs" +avatar: "https://i.ibb.co/rGyw3WZM/Untitled-design-1.png" +--- + +<!--markdownlint-disable--> + +# About Elwin Li + +Elwin is a Google Summer of Code 2025 contributor for Sugarlabs, working on bridging the gap between text-based coding and block coding in MusicBlocks. + +## Experience + +- **GSoC 2025**: Enhancing the JSeditor through adding code to block conversion, and fully functional debugger + +## Current Projects + +- [Code to Block conversion](https://github.com/sugarlabs/musicblocks/pull/4707) (Completed) +- Debugger (WIP) +- Syntax highlighting (WIP) + +## Connect with Me + +- **GitHub**: [@ebeetles](https://github.com/ebeetles) +- **Gmail**: [elwin.s.li@gmail.com](mailto:elwin.s.li@gmail.com) +- **LinkedIn**: [Elwin Li](https://www.linkedin.com/in/elwinsli/) + +`,Dt=Object.freeze(Object.defineProperty({__proto__:null,default:r},Symbol.toStringTag,{value:"Module"})),s=`--- +name: "Harshit Verma" +slug: "harshit-verma" +title: "Member and DMP'25 Contributor" +organization: "Sugar Labs" +description: "Member and DMP'25 Contributor at Sugar Labs" +avatar: "https://avatars.githubusercontent.com/u/169194753?v=4" +--- + +<!--markdownlint-disable--> + +# About Harshit Verma + +I'm Harshit Verma, a Computer Science Engineering student with a passion for technology, problem-solving, and building innovative software solutions. +I'm currently exploring various areas of computer science, including software development, AI/ML, and system design. I enjoy turning ideas into code and continuously learning new tools and technologies to sharpen my skills. Whether it's contributing to open-source, building personal projects, or debugging complex systems, I'm always up for a challenge that helps me grow as a developer. + +## Experience + +- **DMP 2025**: LLM-Powered Debugger for Pippy +- **SugarLabs Member**: Member and Contributor to various projects +- **Hactoberfest 2024:** Contributed to Open-Source projects + +## Current Projects + +- LLM-Powered Debugger for Pippy +- Music Blocks Developer +- Sugar Labs website development + +## Connect with Me + +- **GitHub**: [@therealharshit](https://github.com/therealharshit) +- **Email**: [therealharshit014@gmail.com](mailto:therealharshit014@gmail.com) +- **LinkedIn**: [Harshit Verma](https://linkedin.com/in/therealharshit) +`,jt=Object.freeze(Object.defineProperty({__proto__:null,default:s},Symbol.toStringTag,{value:"Module"})),l=`--- +name: "Justin Charles" +slug: "justin-charles" +title: "Member and DMP'25 Contributor" +organization: "Sugar Labs" +description: "Member and DMP'25 Contributor at Sugar Labs" +avatar: https://avatars.githubusercontent.com/u/143245796?s=400&u=56426d9e56b5d8ee545ba6b753e300d90e994eaa&v=4 +--- + +<!--markdownlint-disable--> + +# About Justin Charles + +I'm Justin Charles, an enthusiastic Computer Science student passionate about open-source, creative coding, and building impactful developer tools. +As a contributor at Sugar Labs and a participant in DMP 2025, I’m focused on improving the developer experience through intelligent tooling and user-centric design. I thrive on collaborative environments and believe in writing clean, maintainable code that scales. + +## Experience + +- **DMP 2025**: Enhancing Debugger Capabilities for Pippy using LLMs +- **Sugar Labs Member**: Active contributor to Sugar's developer tooling and educational platforms +- **Open Source Contributor**: Regular participant in Hacktoberfest and community-led initiatives + +## Current Projects + +- MusicBlocks-v4 Masonry Module +- Music Blocks Developer + +## Connect with Me + +- GitHub: [@justin212407](https://github.com/justin212407) +- Gmail: [charlesjustin2124@gmail.com](mailto:charlesjustin2124@gmail.com) +- LinkedIn: [Justin Charles](https://www.linkedin.com/in/justin-c-663840297/) +`,Wt=Object.freeze(Object.defineProperty({__proto__:null,default:l},Symbol.toStringTag,{value:"Module"})),d=`--- +name: "Krish Pandya" +slug: "krish-pandya" +title: "Maintainer and GSoC'25 Contributor" +organization: "SugarLabs" +description: "GSoC'25 Contributor at SugarLabs working on GTK4 migration" +avatar: "https://avatars.githubusercontent.com/u/135974627?s=400&u=d8834bf3a691f090819069974b42cf936a93b0e7&v=4" +--- + +<!--markdownlint-disable--> + +# About Krish Pandya + +I'm Krish, aka MostlyK, a B.Tech student in Electronics and Communication Engineering at IIITH. While my degree might say ECE, I've completely fallen down the open source rabbit hole. I believe in doing things right the first time, even if it takes longer, and I approach problems by understanding the "why" behind changes, not just the "what." + +## Experience + +- Systems engineering and graphics programming +- Open source development and contribution +- C/Python development +- Linux and System Adminstration + +## Current Projects + +- **GSoC 2025**: GTK4 migration for Sugar Labs desktop environment +- Modular architecture and newer build system design for Sugar +- Sugar-AI and it's implementation along with other fun stuff. + +## Connect with Me + +- **GitHub**: [@mostlykiguess](https://github.com/mostlykiguess) +- **Email**: [krishpandya93@gmail.com](mailto:krishpandya93@gmail.com) +- **LinkedIn**: [Krish Pandya](https://www.linkedin.com/in/krish-pandya-020aaa261/) +- **Mastodon**: [@mostlyk](https://mastodon.social/@mostlyk) +`,Ot=Object.freeze(Object.defineProperty({__proto__:null,default:d},Symbol.toStringTag,{value:"Module"})),c=`--- +name: "Mebin Thattil" +slug: "mebin-thattil" +title: "GSoC'25 Contributor" +organization: "SugarLabs" +description: "GSoC'25 Contributor at SugarLabs" +avatar: "https://mebin.shop/mebin-380.png" +--- + +<!--markdownlint-disable--> + +# About Mebin Thattil + +Hey, I'm Mebin 👋🏻! I'm a first year student at PES University, Bangalore, India, currently pursuing a BTech in Computer Science. I’ve had a deep passion for tech ever since I was 10, when I first learned in a CS class that you could write a couple of lines of code and build a (barely functional) website. That simple idea sparked something in me, and over the years, my love for computer science has only grown—especially while building a bunch of cool things along the way. + +I'm going to spend my summer working on the [Speak Activity](https://github.com/sugarlabs/speak). I will be refactoring the chatbot in the speak activity to use Gen-AI. + +About a month ago, I launched my personal portfolio website: [mebin.in](https://mebin.in/). It runs on an 8-year-old Raspberry Pi sitting at home 🤩, so apologies in advance if the site is occasionally slow or down (power cuts are a real pain). I ocassionally write blogs there. + +I'm also building a Bluesky client in the Nim programming language. I'm a strong advocate for education in technology. In the past, I built a web application aimed at connecting students in rural areas with those in urban areas to help foster a free and open peer-to-peer learning ecosystem. + +## Connect with Me + +- **GitHub**: [@mebinthattil](https://github.com/mebinthattil) +- **Website**: [mebin.in](https://mebin.in/) +- **Email**: [mail@mebin.in](mailto:mail@mebin.in) +- **LinkedIn**: [Mebin Thattil](https://www.linkedin.com/in/mebin-thattil/) +`,Bt=Object.freeze(Object.defineProperty({__proto__:null,default:c},Symbol.toStringTag,{value:"Module"})),u=`--- +name: "Muhammad Haroon" +slug: "muhammad-haroon" +title: "Member & SSoC'25 Contributor" +organization: "Sugar Labs" +description: "Member & SSoC'25 Contributor at Sugar Labs" +avatar: "/assets/Developers/Muhammad Haroon/muhammadharoon.jpg" +--- + +<!--markdownlint-disable--> + +# About Muhammad Haroon + +Hi, I’m Muhammad Haroon, a final year student at NED University Karachi, Pakistan, pursuing a degree in Computer Information & Systems Engineering. + +I have been actively contributing to Sugar Labs for a long time not just in code, but also in documentation and by assisting new contributors. + +This summer, I’ve been selected for Sugar Summer of Code (SSoC) 2025. This is the first time Sugar Labs is running this program, and I’m proud to be a pilot candidate. I’ll be working on Generative AI Instrument Sample Generation for Music Blocks, which will give students endless options for sound samples. + +## Experience + +- **SSoC 2025**: Generative AI Instrument Sample Generation for Music Blocks +- **Sugar Labs Member**: Active contributor to various projects + +## Current Projects + +- Generative AI Instrument Sample Generation for Music Blocks +- Sugar Labs website development + +## Connect with Me + +- **GitHub**: [@haroon10725](https://github.com/haroon10725) +- **Email**: [haroongondal347@gmail.com](mailto:haroongondal347@gmail.com) +- **LinkedIn**: [Muhammad Haroon](https://www.linkedin.com/in/muhammad-haroon-7003b923b/)`,Rt=Object.freeze(Object.defineProperty({__proto__:null,default:u},Symbol.toStringTag,{value:"Module"})),h=`--- +name: "Nikhil Bhatt" +slug: "nikhil-bhatt" +title: "GSoC'25 Contributor" +organisation: "Sugarlabs" +description: "GSoc'25 Contributor, learning through code" +avatar: "https://avatars.githubusercontent.com/u/154296996?s=400&u=985121a969ea993a325f2690d74a0712f0599309&v=4" +--- + +<!--markdownlint-disable--> + +# About Nikhil Bhatt +Nikhil Bhatt is a Google Summer of Code 2025 contributor and full stack product developer with a strong focus on building impactful, scalable tools. + +## Experience + +- **GSoC 2025**: Music Blocks v3 Backend Development + +## Current Projects + +- Git backend for Musicblocks + + +## Connect with Me + +- **GitHub**: [BeNikk](https://github.com/BeNikk) +- **Email**: [bhattnik442@gmail.com](mailto:bhattnik442@gmail.com) +- **LinkedIn**: [Nikhil bhatt](https://www.linkedin.com/in/nikhil-bhatt-3b37a0255/) +- **Twitter**: [Nikhil](https://twitter.com/Be_Nikkk) +`,zt=Object.freeze(Object.defineProperty({__proto__:null,default:h},Symbol.toStringTag,{value:"Module"})),g=`--- +name: "Om Santosh Suneri" +slug: "om-santosh-suneri" +title: "GSoC'25 Contributor" +organization: "SugarLabs" +description: "Maintainer and GSoC'25 Contributor at SugarLabs" +avatar: "https://avatars.githubusercontent.com/u/142336291?s=400&u=6f66e785309c44a70de1f634e768c60a47de3c1c&v=4" +--- + +<!--markdownlint-disable--> + +# About Om Santosh Suneri + +Suneri is a passionate open-source contributor and a Google Summer of Code 2025 contributor with SugarLabs. He is currently developing the AI-powered Debugger for Music Blocks, a project he originally conceptualized during one of SugarLabs’ biweekly community meetings. This innovative tool aims to assist learners and educators by automatically detecting and explaining errors in Music Blocks projects using LLMs and vector-based retrieval techniques. With a strong interest in the intersection of educational tools and artificial intelligence, Suneri is dedicated to building solutions that make learning to code more accessible and engaging for users of all ages. + +## Experience + +- **GSoC 2025**: AI-powered Debugger for Music Blocks +- **SugarLabs Maintainer**: Active contributor to various projects + +## Current Projects + +- AI-powered Debugger for Music Blocks +- SugarLabs website development +- Music Blocks Developer + + +## Connect with Me + +- **GitHub**: [@omsuneri](https://github.com/omsuneri) +- **Gmail**: [omsuneri@gmail.com](mailto:omsuneri@gmail.com) +- **LinkedIn**: [Om Santosh Suneri](https://www.linkedin.com/in/om-santosh-suneri-736767166/) +- **Twitter**: [@suneri_om](https://x.com/suneri_om) +`,Ut=Object.freeze(Object.defineProperty({__proto__:null,default:g},Symbol.toStringTag,{value:"Module"})),m=`--- +name: "Safwan Sayeed" +slug: "safwan-sayeed" +title: "Maintainer and GSoC'25 Contributor" +organization: "SugarLabs" +description: "Maintainer and GSoC'25 Contributor at SugarLabs" +avatar: "https://avatars.githubusercontent.com/u/111475221?s=400&u=084aa7be2ae3aedd1cf38175557820a49b7efa93&v=4" +--- + +<!--markdownlint-disable--> + +# About Safwan Sayeed + +Safwan is a dedicated maintainer and Google Summer of Code 2025 contributor at SugarLabs, working primarily on the Music Blocks 4 Program Engine development. With a passion for educational technology and open-source development, Safwan contributes to making programming more accessible to learners worldwide. + +## Experience + +- **GSoC 2025**: Music Blocks 4 Program Engine development +- **SugarLabs Maintainer**: Active contributor to various projects + +## Current Projects + +- Music Blocks 4 Program Engine +- SugarLabs website development + + +## Connect with Me + +- **GitHub**: [@sa-fw-an](https://github.com/sa-fw-an) +- **Email**: [isafwansayeed@gmail.com](mailto:isafwansayeed@gmail.com) +- **LinkedIn**: [Safwan Sayeed](https://linkedin.com/in/safwan-sayeed-6a3a482a9) +- **Twitter**: [@safwan_say](https://x.com/safwan_say) +- **Website**: [www.safwansayeed.live](https://safwansayeed.live)`,Ft=Object.freeze(Object.defineProperty({__proto__:null,default:m},Symbol.toStringTag,{value:"Module"})),p=`--- +name: "Saumya Shahi" +slug: "saumya-shahi" +title: "GSoC'25 Contributor" +organization: "SugarLabs" +description: "GSoC'25 Contributor at SugarLabs" +avatar: "https://avatars.githubusercontent.com/u/147405306?v=4" +--- + +<!--markdownlint-disable--> + +# About Saumya Shahi + +Saumya is a GSoC 2025 contributor at SugarLabs, currently working on the Masonry Module for Music Blocks. A second-year Computer Science student at IIIT Kottayam with a specialization in Cybersecurity, Saumya is passionate about building intuitive and impactful user experiences. + +Beyond open source, Saumya actively explores quantum computing and cryptographic systems, and has contributed to research in quantum cryptanalysis under DRDO CQC. + +## Experience + +- **GSoC 2025**: Developing the Masonry Module for Music Blocks, a visual programming environment. +- **Quantum Cryptanalysis Research Intern**: DRDO CQC at NITK, working on cipher distinguishers using quantum algorithms + +## Current Projects + +- Music Blocks Masonry Module +- Quantum Feistel cryptanalysis + +## Connect with Me + +- **GitHub**: [@saumyashahi](https://github.com/saumyashahi) +- **Email**: [saumya23bcy18@iiitkottayam.ac.in](mailto:saumya23bcy18@iiitkottayam.ac.in) +- **LinkedIn**: [Saumya Shahi](https://linkedin.com/in/saumya-shahi) +`,Nt=Object.freeze(Object.defineProperty({__proto__:null,default:p},Symbol.toStringTag,{value:"Module"})),b=`--- +name: "Shubham Singh" +slug: "shubham-singh" +title: "Maintainer and GSoC'25 Contributor" +organization: "SugarLabs" +description: "Maintainer and GSoC'25 Contributor at SugarLabs" +avatar: "https://avatars.githubusercontent.com/u/174003514?s=400&u=e43600ba24f563f3799388137119ae119c74ffac&v=4" +--- + +<!--markdownlint-disable--> + +# About Shubham + +Shubham Singh is a passionate developer, open-source contributor, and Google Summer of Code 2025 contributor at SugarLabs. As a core contributor, he brings together creativity and functionality, optimizing both the user experience and technical performance of projects. Shubham is currently working on enhancing educational tools, with a focus on accessibility, interactivity, and meaningful design—empowering learners globally through open-source innovation. + + +## Experience + +- **GSoC 2025**: Music Blocks v3 color sensor development +- **SugarLabs Maintainer**: Active contributor to various projects + +## Current Projects + +- Music Blocks v3 Development of Color Sensor. +- SugarLabs website development + + +## Connect with Me + +- **GitHub**: [@FirePheonix](https://github.com/FirePheonix) +- **Email**: [shubhsoch@gmail.com](mailto:shubhsoch@gmail.com) +- **LinkedIn**: [Shubham Singh](https://www.linkedin.com/in/shubham-singh-8a5643198/) +- **Twitter**: [@shubhamm069](https://x.com/shubhamm069) +- **Website**: +- **Discord**: [ctrlaltresett](https://discord.com/users/Shubham#0418)`,qt=Object.freeze(Object.defineProperty({__proto__:null,default:b},Symbol.toStringTag,{value:"Module"})),f=`--- +title: "New foundation focused on taking the Sugar user interface to the next level of usability and utility" +category: "PRESS RELEASE" +date: "2008-05-15" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +Cambridge, Mass., May 15, 2008 — Sugar Labs Foundation is being established to further extend Sugar, the highly acclaimed open-source “learn learning” software platform originally developed for the One Laptop per Child (OLPC) XO laptop. Sugar is the core of the XO laptop’s human-computer interface; it provides a fun, easy-to-use, social experience that promotes sharing and learning. + +Sugar Labs will focus on providing a software ecosystem that enhances learning on the XO laptop as well as other laptops distributed by companies such as the ASUS Eee PC. Consistent with OLPC’s mission to provide opportunities for learning, an independent Sugar Labs Foundation can deliver learning software to other hardware vendors and, consequently, reach more children. + +Sugar Labs will take a proven learning concept to the next level of refinement, stability, and cohesiveness, and will be a unifying catalyst for free and open-source learning systems across multiple distribution and hardware platforms. The Labs will support a community of developers focused on learning, as well as support for the learners themselves. The Sugar platform has already been bundled with the most recent releases of the Ubuntu and Fedora GNU/Linux distributions. + +Walter Bender, former president of software and content at OLPC, is helping launch Sugar Labs, working closely with developers and community members from around the world who have played lead roles in developing the Sugar user interface (UI). Prior to OLPC, Bender was executive director and a founding member of the Media Lab at MIT. He has participated in much pioneering research in electronic publishing and personalized, interactive multimedia. + +In order to provide a rich learning experience to as many of the world’s children as possible, it is critical not just to provide computers to children, but also to ensure that the software maximizes their potential for engaging in learning activities: exploration, expression, and collaboration. By being independent of any specific hardware platform and by remaining dedicated to the principles of free and open-source software, Sugar Labs ensures that others can develop diverse interfaces and applications from which governments and schools can choose. An independent Sugar Labs ensures that the community can continue the development of a highly innovative interface that is already engaging children in learning in more than two dozen countries worldwide. + +“This is a very exciting time in the development of software for children’s education,” said Walter Bender. “In the first generation of the Sugar UI, the free and open-source community has demonstrated an exceptional ability to create a platform that enables children to explore the world, share their discoveries, and express themselves. As a separate foundation, we will be able to advance Sugar’s development even further and make it available on multiple distributions and hardware platforms.” + +Many of the core Sugar developers are participating in the launch, including Marco Pesenti Gritti, Bert Freudenberg, Simon Schampijer, Bernardo Innocenti, Aaron Kaplan, Christoph Derndorfer, and Tomeu Vizoso. + +Bert Freudenberg, one of the developers of the Etoys activity, commented, “Expanding Sugar to more hardware platforms gives a great boost to all developers of educational software. Sugar is the first system specifically aimed at helping children to learn while supporting a rich variety of contributed applications. As third-party developers, my colleagues at Viewpoints Research Institute look forward to a great relationship with Sugar Labs.” + +Tomeu Vizoso added, “Sugar has been brought to maturity by OLPC and a relatively small team of community supporters. The time has come to unlock Sugar’s potential as a global education project; the creation of Sugar Labs is the next step — expanding upon a project where people from all around the world can contribute to improving education, with the assurance that their efforts will be of benefit to everyone.” +`,Ht=Object.freeze(Object.defineProperty({__proto__:null,default:f},Symbol.toStringTag,{value:"Module"})),y=`--- +title: "Sugar Labs joins the Software Freedom Conservancy" +category: "PRESS RELEASE" +date: "2008-12-09" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +Boston, MA, December 9, 2008 — Sugar Labs today announced its membership in the Software Freedom Conservancy, an organization of free and open-source software projects. Sugar Labs supports the free and open-source desktop environment, Sugar, originally created for the One Laptop per Child Project (OLPC). The Sugar community now has an active global developer base that is focused on engaging young children in learning through computing and the Internet. As a member of the Conservancy, the Sugar community will work to accelerate the adoption of the Sugar learning platform and strengthen the project by attracting new industry members and community contributors. + +In May 2008, the Sugar project became independent of OLPC, making Sugar available to a wider community of developers and users. Subsequently, Sugar has been ported to Debian, Ubuntu, and other GNU/Linux distributions. Sugar can now run on almost any computer hardware. In October 2008, Sugar Labs released Sugar Version 0.82, which features enhanced usability and stability. In November, Sugar announced the availability of the pre-alpha version of “Sugar on a Stick,” a LiveUSB image of Sugar that gives children access to Sugar on any computer using just a USB key. Joining the Conservancy is an important milestone in the path toward making Sugar available to children everywhere. + +Founded in March 2006, the Conservancy allows developers of its member projects to unite under a common organization that provides much-needed administrative services. This structure spares each software project the burden of starting and maintaining its own independent non-profit organization. Sugar Labs has joined as the Conservancy’s fifteenth member project. +`,Kt=Object.freeze(Object.defineProperty({__proto__:null,default:y},Symbol.toStringTag,{value:"Module"})),w=`--- +title: "La Asociación sin fines de lucro Sugar Labs Anuncia su Nueva Versión de la Plataforma de Aprendizaje Sugar para Niños que Funciona en Notebooks y PCs" +category: "PRESS RELEASE" +date: "2009-03-16" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +[PDF](/assets/post-assets/press/SugarLabsPR_es_20090316.pdf) + +Cambridge, MA, March 16, 2009: Sugar Labs™ anuncia que la versión 0.84 de la Plataforma de Aprendizaje de Sugar para la XO-1 de OLPC, las PCs de aula y los notebooks ya se encuentra disponible. Diseñada desde un principio para los niños, el entorno Sugar es usado aproximadamente por un millón de estudiantes, cuyas edades fluctúan entre los 5 y 12 años, en aproximadamente 40 países durante todos los días del calendario escolar. Esta versión mejorada se caracteriza por poseer nuevas Actividades colaborativas. Asimismo, y en respuesta a la retroalimentación brindada por los docentes, posee la capacidad para detener y reanudar las Actividades con facilidad, lo cual permite ahorrar tiempo en el aula. + +Walter Bender, Director Ejecutivo de Sugar Labs, comentó lo siguiente: “Nos encontramos muy emocionados con este lanzamiento que funciona en un mayor número de PCs que antes y posee Actividades nuevas y únicas para que los niños investiguen juntos, tales como la Actividad Mapa Mental, una herramienta de pensamiento crítico que se usa para crear diagramas que representan conceptos e ideas que se encuentran relacionados y dispuestos alrededor de una palabra clave o de una idea central y la Actividad Portafolio, una herramienta de evaluación que brinda mayor facilitad para que tanto los docentes como los padres de familia revisen el progreso que realiza el niño.” + +Igualmente, el Diario Sugar, que proporciona un back up automático y el historial del trabajo de los estudiantes, posee nuevas características a fin de permitirles tomar apuntes o hacer comentarios respecto a su trabajo, así como volver a visitar y revisar proyectos anteriores. Por su parte, la nueva Actividad Infoslicer (Selecciona y Corta Información) permite a los docentes seleccionar el contenido de páginas Web con facilidad y rapidez para editarlo, organizarlo y distribuirlo como material pedagógico. De igual modo, para los estudiantes mayores que tienen curiosidad por saber cómo funcionan las computadoras, la función Vista de Código es actualmente general para todas las Actividades. + +La Plataforma de Aprendizaje Sugar es un software libre y de código abierto y se encuentra disponible para ser descargado en www.sugarlabs.org. Sugar, la interfaz originaria de la XO-1 de OLPC de uso diario en todo el mundo, ha sido traducida a 26 idiomas y tiene 50 idiomas más en proceso de traducción. El apoyo comunitario se encuentra disponible en línea las 24 horas al día/7 días a la semana. Sugar se encuentra disponible en las principales distribuciones GNU/Linux, las últimas computadoras con virtualización Apple Macintosh™ y las PCs Windows™ ejecutadas vía un Live CD de GNU/Linux que no modifica el disco duro. Igualmente, en el tercer trimestre del 2009, se ha programado el lanzamiento de Sugar en formato de tarjeta de memoria (memoria flash) extraíble, una versión de Live USB diseñada para simplificar el uso de Sugar en el aula. + +La plataforma de aprendizaje de Sugar forma parte de la colección permanente del Museo de Arte Moderno de Nueva York. Asimismo, en los International Design Excellence Awards ’08 (Premios Internacionales a la Excelencia en Diseño 2008) le fue otorgada una medalla de plata. Su innovador enfoque “centrado en el aprendizaje” ha recibido elogios por parte de los docentes a nivel mundial. Las Actividades de Sugar, exclusivas de la plataforma, permiten a los alumnos estudiar y crear juntos. Los estudiantes aprenden tanto del docente como de otros alumnos. + +El Sr. Bender comentó lo siguiente: “Sugar 0.84 representa un paso importante a medida que se trabaja para lograr la versión 1.0 de Sugar en formato de tarjeta de memoria extraíble que simplificará, en gran medida, la evaluación y el uso de Sugar en el aula. Asimismo, este formato de tarjeta de memoria extraíble hace posible que Sugar se ejecute a partir de un simple formato de memoria USB en casi cualquier computadora actual desde las notebooks (computadora portátil) hasta las desktops (computadora personal), así como en la mayoría de PCs más antiguas, sin interferir con las instalaciones de software preexistente.” + +“A medida que nos aproximamos al millón de niños “aprendiendo a aprender” con Sugar en la XO-1 de OLPC, solicitamos voluntarios que se unan a nosotros — un reto para los programadores, diseñadores, traductores e implementadores”, refirió el Sr. Bender. “Necesitamos especialmente probadores de software que nos ayuden a hacer de Sugar en formato de tarjeta de memoria extraíble una sólida solución que se encuentre disponible dondequiera que exista una computadora.” +`,Vt=Object.freeze(Object.defineProperty({__proto__:null,default:w},Symbol.toStringTag,{value:"Module"})),v=`--- +title: "Sugar Labs, organisation à but non lucratif, annonce la sortie de la nouvelle version de la plateforme d’apprentissage pour enfants Sugar pour PC et netbooks" +category: "PRESS RELEASE" +date: "2009-03-16" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + + +[PDF](/assets/post-assets/press/SugarLabsPR_fr_20090316.pdf) + +Cambridge, MA, le 16 mars 2009: Sugar Labs™ annonce la sortie de la version 0.84 de sa plateforme d’apprentissage Sugar destinée au XO-1 du projet One Laptop Per Child, aux micro-ordinateurs des établissements scolaires, et aux ordinateurs netbook. Conçu pour enfants de A à Z, l’environnement Sugar est utilisé par près d’un million d’élèves de 5 à 12 ans dans plus de 40 pays, tous les jours. Cette nouvelle version contient de nouvelles Activités Sugar à faire à plusieurs en travail collaboratif et, à la demande des professeurs, prévoit la possibilité d’interrompre et de reprendre facilement les Activités, pour gagner du temps en classe. + +Walter Bender, Directeur Exécutif de Sugar Labs, a dit: "Cette nouvelle version est compatible avec beaucoup plus de PC qu’auparavant, et contient de nouvelles Activités que les enfants adoreront découvrir ensemble, comme l’Activité Mindmap, un outil qui développe l’esprit critique et permet de créér des diagrammes représentant des mots et des idées à partir d’un mot-clé central, et l’Activité Portfolio, un outil d’évaluation permettant aux professeurs et aux parents d’établir très simplement les progrès réalisés par l’enfant. Le Journal Sugar, qui fournit une sauvegarde automatique et un historique du travail de l’élève, comporte de nouvelles fonctionnalités permettant aux élèves d’annoter plus facilement leurs travaux, et de reprendre ou réviser des projets déjà réalisés. La nouvelle activité Infoslicer permet aux professeurs de sélectionner rapidement et facilement du contenu pris sur internet, de le modifier et de le remettre en forme pour le redistribuer comme documents pédagogiques. Et pour les élèves plus grands qui veulent savoir comment marchent les ordinateurs, la fonction View Source (voir code source) a été généralisée à toutes les Activités.” + +La plateforme d’apprentissage Sugar est un logiciel libre. Elle peut être téléchargée sur le site www.sugarlabs.org. Interface d’origine du projet One Laptop Per Child déjà utilisé quotidiennement dans le monde entier, Sugar a déjà été traduite dans 26 langues et 50 autres doivent suivre. Un soutien technique de la communauté est disponible en ligne 24h/24, 7 jours/7. Sugar est disponible sur toutes les grandes distributions GNU/Linux, les ordinateurs Apple Macintosh™ récents avec virtualisation, et pour PC sous Windows™ via un liveCD GNU/Linux, qui ne touche pas au disque dur. Sugar on a Stick, une version liveUSB censée simplifier l’utilisation de Sugar en classe, doit sortir au 3e trimestre 2009. + +La plateforme d’apprentissage Sugar fait partie de la collection permanente du Musée d’Art Moderne de New York, et a reçu la médaille d’argent au Palmarès 2008 de l’excellence du design international (International Design Excellence Awards). Son approche innovante, centrée sur l’apprentissage, a été saluée par les enseignants du monde entier. Les Activités Sugar, disponibles exclusivement sur cette plateforme, permettent aux élèves d’étudier et de créér ensemble: les étudiants apprennent du professeur mais aussi les uns des autres. + +Selon M. Bender, “Sugar 0.84 est une étape importante vers la version 1.0 de Sugar on a Stick, qui va considérablement simplifier l’évaluation et l’utilisation de Sugar en classe. Avec Sugar on a Stick, on pourra lancer Sugar à partir d’une simple clé USB sur la plupart des ordinateurs récents, des netbooks aux ordinateurs de bureau, et aussi sur la plupart des vieux PC, sans perturber les logiciels déjà installés.” + +“Alors que nous nous approchons du millionième enfant “apprenant à apprendre” avec Sugar sur le XO-1 de One Laptop per Child, nous appelons de nouveau bénévoles à venir nous aider à relever ce défi éducatif: développeurs, concepteurs, traducteurs, et déployeurs”, a déclaré M. Bender. “Nous avons notamment besoin de testeurs pour nous aider à faire de Sugar on a Stick une solution robuste qui fonctionnera avec n’importe quel ordinateur.” +`,Jt=Object.freeze(Object.defineProperty({__proto__:null,default:v},Symbol.toStringTag,{value:"Module"})),k=`--- +title: "Sugar Labs Nonprofit Announces New Version of Sugar Learning Platform for Children, Runs on Netbooks and PCs" +category: "PRESS RELEASE" +date: "2009-03-16" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +[PDF](/assets/post-assets/press/SugarLabsPR_en_20090316.pdf) + +Cambridge, MA, March 16, 2009: Sugar Labs™ announces the availability of version 0.84 of the Sugar Learning Platform for the One Laptop Per Child XO-1, classroom PCs, and netbook computers. Designed from the ground up for children, the Sugar computer environment is used by almost one-million students aged 5 to 12 in over 40 countries every school day. This improved version features new collaborative Sugar Activities and, in response to teacher feedback, the ability to easily suspend and resume Activities, saving time in the classroom. + +Walter Bender, Executive Director of Sugar Labs, commented: “We’re excited about this release, which runs on more PCs than before and has great new Activities for kids to explore together such as a Mindmap Activity, a critical-thinking tool used to create diagrams representing words and ideas around a central keyword, and a Portfolio Activity, an assessment tool that makes it even simpler for teachers and parents to review a child’s progress. The Sugar Journal, which provides automatic backup and history of students’ work, has new features to make it easier for students to annotate their work and to revisit and revise past projects. The new Infoslicer Activity enables teachers to quickly and easily select web-based content to edit, package, and distribute as teaching materials. And for older students curious about how computers work, the View Source function is now universal to all Activities.” + +The Sugar Learning Platform is free open-source software; it is available for download at www.sugarlabs.org. The native interface of the One Laptop Per Child project’s XO-1 in daily use around the globe, Sugar has been translated into 26 languages with 50 more languages underway. 24/7 community support is available online. Sugar is available on major GNU/Linux distributions, recent Apple Macintosh™ computers with virtualization, and Windows™ PCs via a GNU/Linux liveCD, which doesn’t touch the hard disk. Sugar on a Stick, a liveUSB version designed to simplify classroom use of Sugar, is scheduled for release in Q3 2009. + +The Sugar Learning Platform is part of the permanent collection of the Museum of Modern Art in New York and was awarded a silver medal in the International Design Excellence Awards ’08. Its innovative “learning-centric” approach has earned praise from educators worldwide. Sugar Activities, unique to the platform, allow students to study and create together; students learn both from the teacher and from each other. + +Mr. Bender commented, “Sugar 0.84 is an important step as we work toward version 1.0 of Sugar on a Stick, which will greatly simplify evaluation and use of Sugar in the classroom. Sugar on a Stick will start Sugar from a simple USB memory stick on nearly any recent computer from netbooks to desktops, and most older PCs as well, without interfering with pre-existing software installations.” + +“As we approach the one-millionth child ‘learning to learn’ with Sugar on the OLPC XO-1, we call for volunteers to join us—a challenge to educate for developers, designers, translators, and deployers,” Mr. Bender said. “In particular, we need testers to help us make Sugar on a Stick a robust solution available anywhere there is a computer.” +`,Xt=Object.freeze(Object.defineProperty({__proto__:null,default:k},Symbol.toStringTag,{value:"Module"})),S=`--- +title: "Sugar Labs kündigt neue Version von Sugar an—die Lernplattform für Kinder läuft auf Netbooks und PCs" +category: "PRESS RELEASE" +date: "2009-03-16" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +[PDF](/assets/post-assets/press/SugarLabsPR_de_20090316.pdf) + +Cambridge, MA, 16. März, 2009: Sugar Labs™ hat die Version 0.84 der Lernplattform Sugar freigegeben. Die Software ist auf dem XO-1 von One Laptop Per Child, PCs und Netbooks einsetzbar. Die speziell für Kinder entwickelte Plattform wird von fast einer Million Schülern im Alter von 5 bis 12 Jahren in über 40 Ländern täglich im Schulunterricht eingesetzt. + +Walter Bender, Geschäftsführer von Sugar Labs, sagt hierzu: “Wir sind gespannt auf die neue Version, die auf mehr PCs läuft als zuvor und neue, interessante Activities zum gemeinsamen Erkunden beinhaltet. Zum Beispiel die Mindmap Activity, ein Werkzeug zum Erstellen von Diagrammen, die Beziehungen zwischen einem Schlüsselwort und diesem zugeordneten Begriffen aufzeigen. Oder die Portfolio Activity, ein Bewertungswerkzeug, das es Lehrern und Eltern einfacher macht, den Fortschritt eines Kindes zu beurteilen. Das Journal, eine Art Tagebuch, das dem Schüler die chronologische Aufzeichnung seiner Aktivitäten bereitstellt, wurde erweitert. Der Schüler hat es nun leichter seine Arbeiten zu kommentieren und seine Projekte zu überarbeiten. Die neue Infoslicer Activity ermöglicht es Lehrern, schnell und einfach web-basierte Inhalte zu editieren, zusammenzustellen und als Lehrmaterial bereitzustellen. Schüler, die an der Funktionsweise eines Computers interessiert sind, können die View Source Funktion nutzen um tiefere Einblicke zu erhalten. Außerdem wurde in der Entwicklung der Software auf Verbesserungsvorschläge von Lehrern eingegangen. So ist es nun einfacher, vorangegangene Activities fortzuführen, wodurch im Unterricht Zeit eingespart werden kann. + +Die Lernplattform Sugar ist Open Source Software und kann von www.sugarlabs.org heruntergeladen werden. Sugar wurde in 26 Sprachen übersetzt und 50 weitere Übersetzungen sind in Bearbeitung. Die Sugar-Gemeinschaft ist Online immer für Fragen und Anregungen offen. Die Plattform ist erhältlich in allen größeren Linux-Distributionen. Sugar kann als Live-System unter Windows™ von einem CD-Image gestartet werden und kann auf Apple Macintosh™ Computern virtualisiert ausgeführt werden. Sugar on a Stick, ein Live-System, das von USB-Speichermedien gestartet wird, und den Einsatz in Computerlaboren erleichtern soll, wird voraussichtlich im dritten Quartal von 2009 erscheinen. + +Die Lernplattform Sugar ist Teil der ständigen Ausstellung des Museum of Modern Art in New York. 2008 erhielt sie die Silber-Medaille des International Design Excellence Awards in der Kategorie Interactive Product Experiences. Ihr innovativer lernorientierter Ansatz erhielt weltweites Lob von Pädagogen. Sugar Activities, die einmalig für diese Plattform sind, ermöglichen es den Schülern gemeinsam zu lernen und kreativ zu werden, Schüler können sowohl von ihrem Lehrer als auch voneinander lernen. + +Bender fügt hinzu: “Sugar 0.84 ist ein wichtiger Schritt im Hinblick auf die Version 1.0 von Sugar on a Stick, die die Evaluation und die Anwendung von Sugar im Unterricht vereinfachen wird. Sugar on a Stick lädt Sugar von einem USB-Speichermedium auf nahezu jedem gängigen Computer, ob Netbook oder Desktop PC, ohne dabei mit der bereits installierten Software in Konflikt zu geraten.” + +“Weil bald das millionste Kind mit Sugar auf dem OLPC XO-1 ‘lernt zu lernen’ laden wir alle Freiwilligen dazu ein, mitzumachen—eine Herausforderung für Entwickler, Pädagogen, Designer, Übersetzer und Anwender,” sagt Bender. “Vor allem brauchen wir Software-Tester, die uns helfen aus Sugar on a Stick eine Alternative zu vorhandener Software auf allen verfügbaren Computern zu machen.” +`,$t=Object.freeze(Object.defineProperty({__proto__:null,default:S},Symbol.toStringTag,{value:"Module"})),I=`--- +title: "Sugar Labs Announces Beta‑1 of Sugar on a Stick, LiveUSB Version of Sugar Learning Platform for Children" +category: "PRESS RELEASE" +date: "2009-04-22" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +[PDF](/assets/post-assets/press/SugarLabsPR_en_20090422.pdf) + +Cambridge, MA, April 22, 2009: Sugar Labs™ announces the availability for testing of Sugar on a Stick Beta‑1. This version of the free open-source Sugar Learning Platform, available at [www.sugarlabs.org](http://www.sugarlabs.org) for loading on any 1 Gb or greater USB stick, is designed to facilitate exploration of the award-winning Sugar interface beyond its original platform, the One Laptop per Child XO‑1, to such varied hardware as aging PCs and recent Macs to the latest netbooks. + +Teachers and parents interested in trying Sugar with children can download the Sugar on a Stick beta‑1 file from the Sugar Labs website and load it onto a USB stick by following the instructions at [wiki.sugarlabs.org/go/Sugar_on_a_Stick](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick). + +Walter Bender, Executive Director of Sugar Labs, said: “Sugar is perfectly suited for children in the classroom with its simple, colorful interface, built-in collaboration, and open architecture. Sugar on a Stick lets you start a computer with Sugar and store a child’s data on the stick without touching the host computer’s hard disk. Sugar’s Activities such as Write, a shared word processor, and the recently announced InfoSlicer Activity, which enables teachers to easily collect and package web-based content for the classroom, benefit fully from Sugar’s collaboration features.” + +Caroline Meeks of Solution Grove ([www.solutiongrove.com](http://www.solutiongrove.com)), the Sugar on a Stick project manager, commented: “We’re counting on teachers to help us improve Sugar on a Stick as we work towards our Version‑1 release scheduled for Q3 2009. We just presented Sugar on a Stick at the FOSS VT conference (<http://www.ncose.org/node/47>) where it generated great interest, and our real-world tests at local sites with varied aging PCs have been very encouraging.” + +Sugar testers are invited to send bug information and constructive criticism to [feedback@sugarlabs.org](mailto:feedback@sugarlabs.org). “We won’t be able to reply to every message,” continued Ms. Meeks, “but we will read every one in order to make Sugar on a Stick a reliable learning tool in budget-stretched classrooms by the fall.” +`,Yt=Object.freeze(Object.defineProperty({__proto__:null,default:I},Symbol.toStringTag,{value:"Module"})),A=`--- +title: "Sugar Labs annonce la bêta-1 de Sugar on a Stick, version LiveUSB de Sugar, la plate-forme d’apprentissage pour enfants" +category: "PRESS RELEASE" +date: "2009-04-22" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + + +[PDF](/assets/post-assets/press/SugarLabsPR_fr_20090422.pdf) + +Cambridge, MA, April 22, 2009: Sugar Labs™ annonce la disponibilité pour tests de la version Bêta-1 de Sugar on a Stick. Cette version du logiciel libre Sugar Learning Platform, disponible sur www.sugarlabs.org pour téléchargement dans n’importe quelle clef USB de 1 Go ou plus, a été conçue pour permettre d’explorer la célèbre interface Sugar au-delà de sa plate-forme d’origine, le XO-1 de One Laptop per Child, sur toutes sortes d’ordinateurs, des PCs anciens aux Macintosh récents en passant par les nouveaux netbooks. + +Les enseignants et parents qui veulent essayer Sugar avec des enfants peuvent télécharger le fichier bêta-1 de Sugar on a Stick sur le site web de Sugar Labs et le charger sur une clef USB en suivant les instructions sur [wiki.sugarlabs.org/go/Sugar_on_a_Stick](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick). + +Walter Bender, le directeur exécutif de Sugar Labs, a dit : “Sugar est parfaitement adapté aux élèves avec son interface simple et vivante, pensée pour le travail en commun, et avec son architecture ouverte. Sugar on a Stick vous permet de démarrer un ordinateur avec Sugar et de stocker les données de l’enfant dans la clef sans toucher au disque dur de l’ordinateur hôte. Les Activités de Sugar telles que Write, un traitement de texte partagé, et l’Activité InfoSlicer annoncé récemment, qui permet aux enseignants de collectionner et réunir facilement des contenus du web pour la classe, bénéficient pleinement des caractéristiques collaboratives de Sugar.” + +Caroline Meeks de Solution Grove ([www.solutiongrove.com](http://www.solutiongrove.com)), gestionnaire du projet Sugar on a Stick, a commenté : “Nous comptons sur les enseignants pour nous aider à améliorer Sugar on a Stick tandis que nous continuons à travailler sur la Version-1 prévue pour le troisième trimestre 2009. Nous venons de présenter Sugar on a Stick à la conférence FOSS VT (<http://www.ncose.org/node/47>) où il a suscité beaucoup d’intérêt, et nos tests sur le terrain avec des PCs variés et anciens ont été très encourageants.” + +Les testeurs de Sugar sont invités à envoyer des informations sur tout bogue et autres critiques constructives à l’adresse suivante : [feedback@sugarlabs.org](mailto:feedback@sugarlabs.org). “Nous ne pourrons pas répondre à chaque message,” a continué Mme Meeks, “mais nous allons lire chacun afin de rendre Sugar on a Stick un outil fiable dans les classes qui manquent de ressources d’ici la rentrée.” +`,Qt=Object.freeze(Object.defineProperty({__proto__:null,default:A},Symbol.toStringTag,{value:"Module"})),L=`--- +title: "Sugar Labs Announces Immediate Availability of Sugar on a Stick; Learning Platform Runs on Any PC or Netbook In The Classroom" +category: "PRESS RELEASE" +date: "2009-06-24" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +LinuxTag, Berlin, June 24, 2009: Sugar Labs™, nonprofit provider of the Sugar Learning Platform to over one-million children worldwide, announces the immediate availability of Sugar on a Stick v1 Strawberry. Available free for download at [www.sugarlabs.org](http://www.sugarlabs.org), Sugar on a Stick can be loaded onto an ordinary 1GB USB flash drive and used to reboot any PC or netbook directly into the award-winning Sugar environment. It runs on recent Macs with a helper CD and in Windows using virtualization. Sugar on a Stick is designed to work with a School Server that can provide content distribution, homework collection, backup services, Moodle integration, and filtered access to the Internet. Today’s Strawberry release is meant for classroom testing; [feedback](mailto:feedback@sugarlabs.org) will be incorporated into the next version, available towards the end of 2009. + +“One year after its founding, Sugar Labs is delivering on its education promise for its second million learners,” commented Walter Bender, founder and executive director. “Sugar is preferred because it is a superior learning experience for young children: engaging while being affordable. Sugar on a Stick is a great way to try Sugar without touching your computer’s hard disk. It is also well suited to slower, older PCs and low-powered netbooks. There is a version for the OLPC XO-1 and it will ship with the newer XO-1.5 laptops in the fall.” + +Sugar on a Stick provides a coherent and consistent computing experience. It reduces costs by providing flexibility in hardware choices, allowing schools to keep their existing investment in hardware. Learners can benefit from the increased household ownership of computers; by bringing Sugar on a Stick home, every student has a consistent, comparable computing environment that parents can share in as well. It also provides off-line access to applications and content as not every learner has Internet access at home. + +As part of an ongoing effort to make Sugar on a Stick classroom-ready, Sugar Labs has been awarded a $20,000 grant from the Gould Charitable Foundation to implement Sugar at the Gardner Pilot Academy, a public elementary school located in one of the most culturally and linguistically diverse sections of Boston, Massachusetts. + +Learning Activities are at the heart of Sugar. Sugar on a Stick includes 40 Activities to interest young learners such as Read, Write, Paint, and Etoys. Hundreds more Activities are available free for download at the [Sugar Activity Library](http://activities.sugarlabs.org). Most “Sugarized” Activities have student collaboration built-in; students and teachers work, play, and learn on the same Activities together. The Sugar Learning Platform is open, so by leveraging the work of other open source projects, existing software for children can be integrated; for example, the acclaimed GCompris suite of 100 Activities developed over the past five years by Bruno Coudoin was recently added to Sugar, including Activities such as Chess, Geography, and Sudoku. Teachers and parents interested in Sugar’s Activities and its modern interface for children can watch short videos on the recently opened [Sugar Labs Dailymotion channel](http://www.dailymotion.com/sugarlabs). + +Visitors to LinuxTag are welcome to speak with Sugar Labs contributors at booth 7.2a 110a. +`,Zt=Object.freeze(Object.defineProperty({__proto__:null,default:L},Symbol.toStringTag,{value:"Module"})),T=`--- +title: "Sugar Labs annonce la disponibilité immédiate de « Sugar on a Stick », une plate-forme d’apprentissage qui fonctionne sur n’importe quel PC ou netbook dans la salle de classe" +category: "PRESS RELEASE" +date: "2009-06-24" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + + +LinuxTag, Berlin, 24 Juin 2009: Sugar Labs™, fournisseur à but non-lucratif de la plate-forme pédagogique Sugar à plus d’un million d’enfants dans le monde, annonce la disponibilité immédiate de « Sugar on a Stick v1 Strawberry » (« Bâtonnet de Sucre v1 Fraise »). Logiciel libre disponible en téléchargement gratuit sur [www.sugarlabs.org](http://www.sugarlabs.org), Sugar on a Stick peut être chargé sur une clef USB 1Gb ordinaire et utilisée pour rebooter n’importe quel PC ou netbook dans l’environnement Sugar. Celui-ci tourne sur les Macs récents avec un CD de support et dans Windows en utilisant la virtualisation. Sugar on a Stick est conçu pour marcher avec un serveur d’école qui peut dispenser des contenus, des collections de devoirs à la maison, des services de sauvegarde, l’intégration de Moodle, et un filtrage de l’accès à internet. La version « Fraise » d’aujourd’hui est destinée à être testée dans la salle de classe ; les [retours d’expérience](mailto:feedback@sugarlabs.org) seront intégrés dans la prochaine version, disponible vers la fin 2009. + +« Un an après sa fondation, Sugar Labs tient ses promesses pédagogiques pour son second million d’apprenants », commente Walter Bender, fondateur et directeur exécutif. « Sugar est choisi parce qu’il permet une expérience d’apprentissage supérieure pour les jeunes enfants qui l’explorent, tout en étant abordable. Sugar on a Stick est une formidable manière de tester Sugar sans toucher au disque dur de votre ordinateur. C’est aussi bien adapté aux ordinateurs plus lents, aux vieux PCs et aux netbooks peu puissants. Il y a une version pour le XO-1 d’OLPC et cela sera expédié avec les nouveaux XO-1.5 à partir de l’automne. » + +Sugar on a Stick fournit une expérience informatique cohérente et conforme. Il réduit les coûts en rendant souple les choix des matériels, permettant aux écoles de conserver leur investissement existant en matériel. Les apprenants peuvent bénéficier du taux grandissant des ordinateurs familials ; en rentrant à la maison avec Sugar on a Stick, chaque étudiant possède son environnement habituel que les parents peuvent partager aussi. Il fournit aussi un accès différé aux applications et contenus, utile pour des apprenants dépourvus d’un accès Internet à la maison. + +L’effort pour rendre Sugar on a Stick prêt pour la salle de classe continue ; Sugar Labs a décerné une subvention de $20.000 de la Gould Charitable Foundation pour implémenter Sugar au Gardner Pilot Academy, une école primaire publique située dans un quartier populaire et multiculturel de Boston dans l’état de Massachusetts. + +Les Activités pour apprendre sont au cœur de Sugar. Sugar on a Stick est fourni avec 40 Activités intéressantes pour des jeunes apprenants tels que Lire, Écrire, Dessiner, et EToys. Des centaines d’autres Activités sont disponibles gratuitement sur la [Bibliothèque d’Activités Sugar](http://activities.sugarlabs.org). La plupart d’activités « sucrées » offrent la collaboration en natif ; les étudiants et enseignants travaillent, jouent, et apprennent ensemble sur les mêmes Activités. La plate-forme d’apprentissage Sugar est ouverte et bénéficie des travaux d’autres projets ; des logiciels existants peuvent être intégrés. Par exemple, plus de 100 activités tels que Échecs, Géographie, et Sudoku de la suite acclamée GCompris développée depuis cinq ans par Bruno Coudoin ont été ajoutés récemment à Sugar. Des enseignants et parents qui s’intéressent aux activités de Sugar et à son interface moderne pour enfants peuvent visionner de courtes vidéos sur le nouveau canal [Dailymotion de Sugar Labs](http://www.dailymotion.com/sugarlabs). + +Les visiteurs à LinuxTag sont invités à dialoguer avec des contributeurs de Sugar Labs au stand 7.2a 110a. +`,ea=Object.freeze(Object.defineProperty({__proto__:null,default:T},Symbol.toStringTag,{value:"Module"})),P=`--- +title: "Sugar Labs annuncia l’immediata disponibilità di Sugar on a Stick; La Piattaforma di Apprendimento in grado di funzionare su qualsiasi PC o Netbook disponibile in classe" +category: "PRESS RELEASE" +date: "2009-06-24" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +Berlino, 24 Giugno, 2009: Sugar Labs, la realtà no-profit che ha sviluppato la Piattaforma di Apprendimento Sugar (Sugar Learning Platform) utilizzata da più di un milione di bambini nel mondo intero, annuncia l’immediata disponibilità di "Sugar on a Stick" v1 Strawberry. Disponibile in forma libera e gratuita dal sito [www.sugarlabs.org](http://www.sugarlabs.org), Sugar on a Stick può essere caricato su una normale chiavetta USB da almeno 1Gb e utilizzandola per avviare direttamente il sistema Sugar in qualunque PC o netbook. Può essere utilizzato anche sui più recenti sistemi Mac con l’ausilio di un CD di avvio, e all’interno di sistemi Windows attraverso la virtualizzazione. “Sugar on a Stick” è stato progettato per l’utilizzo insieme ad uno School Server che fornisce distribuzione di contenuti, raccolta di elaborati, servizi di backup, integrazione con la piattaforma Moodle, e accesso protetto ad Internet. La versione odierna di “Sugar on a Stick” v1 Strawberry è pensata per la sperimentazione in classe ([feedback](mailto:feedback@sugarlabs.org)); la prossima versione sarà rilasciata entro la fine del 2009. + +"Ad un anno dalla fondazione, Sugar Labs sta rilasciando quanto promesso per il suo secondo milione di studenti" commenta Walter Bender, fondatore e direttore esecutivo. "Sugar viene preferito perché offre grandi opportunità educative ai giovani allievi: attraente e di facile approccio. Sugar on a Stick è un modo eccezionalmente semplice per provare Sugar senza dover installare nulla sul proprio computer. Si tratta inoltre di una soluzione ottima per computer vecchi, lenti o per netbook non particolarmente potenti. Esiste una versione specifica per OLPC XO-1 e questa sarà la versione distribuita con i nuovi XO-1.5 laptop a partire dal prossimo autunno." + +Sugar on a Stick fornisce un ambiente coerente e consistente per le attività. Permette una riduzione di costi offrendo adattabilità a molteplici soluzioni hardware, permettendo alle scuole di conservare e riutilizzare gli investimenti in hardware effettuati nel passato. Gli studenti potranno beneficiare della accresciuta possibilità di utilizzare anche a casa i propri strumenti didattici; portando a casa “Sugar on a Stick”, ogni studente ritroverà il proprio ambiente di lavoro scolastico abituale, anche utilizzando computer di famigliari. Permetterà inoltre ad ogni utilizzatore di continuare a utilizzare le proprie applicazioni e contenuti anche off-line, posto che non tutti possano disporre di connessioni ad internet a casa. + +Come supporto allo sforzo di rendere “Sugar on a Stick” pronto per l’utilizzo in classe, Sugar Labs ha ricevuto un sussidio di $20,000 da parte della Gould Charitable Foundation per rilasciare Sugar presso la Gardner Pilot Academy, una scuola elementare pubblica situata in una delle aree di Boston, Massachusetts, caratterizzata da una grande varietà culturale e linguistica. + +Le Attività di Apprendimento sono il cuore di Sugar. “Sugar on a Stick” include 40 attività preinstallate per catturare l’interesse dei giovani studenti, fra queste Leggi, Scrivi, Disegna, e l’ambiente Etoys. Altre centinaia di attività sono disponibili per essere liberamente scaricate dalla [Sugar Activity Library](http://activities.sugarlabs.org). La maggior parte delle attività "Sugarized" possiedono funzionalità di collaborazione native; gli studenti ed i docenti possono lavorare, giocare ed imparare tutti insieme condividendo le stesse attività. La “Sugar Learning Platform” è aperta, quindi approfittando del lavoro di altri progetti OpenSource, software didattico per bambini già esistente può essere integrato; per esempio, la famosa suite GCompris comprendente più di 100 attività didattiche e ludiche sviluppata nel corso degli scorsi cinque anni da Bruno Coudoin è stata recentemente integrata, comprendendo fra le altre Attività come Scacchi, Geografia e Sudoku. Docenti e genitori interessati a valutare le attività di Sugar e la sua innovativa interfaccia utente specificamente progettata per i bambini possono visionare i filmati disponibili sul canale recentemente attivato da [Sugar Labs su Dailymotion](http://www.dailymotion.com/sugarlabs). + +I partecipanti a LinuxTag sono caldamente invitati ad incontrare i collaboratori di Sugar Labs presso lo stand 7.2a 110a. +`,na=Object.freeze(Object.defineProperty({__proto__:null,default:P},Symbol.toStringTag,{value:"Module"})),C=`--- +title: "Sugar Labs anuncia la disponibilidad inmediata de Sugar On A Stick (Sugar en un pendrive). El plataforma de aprendizaje funciona en casi cualquier PC o portátil que hay en el aula." +category: "PRESS RELEASE" +date: "2009-06-24" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +LinuxTag, Berlín, 24 de junio de 2009: Sugar Labs™, proveedor sin fines de lucro de la plataforma de aprendizaje de Sugar a más de un millón de niños en todo el mundo, anuncia la disponibilidad inmediata de Sugar on a Stick (SoaS) v1 Strawberry (Fresa). Disponible para su descarga gratuita en [www.sugarlabs.org](www.sugarlabs.org), SoaS se puede cargar en una pendrive USB de 1 GB y se utiliza para reiniciar casi cualquier PC, o usar directamente en el portátil y entrar a Sugar, el ambiente premiado de aprendizaje. Funciona en los últimos equipos Mac con la ayuda de un CD y en Windows usando la virtualización. + +Sugar on a Stick está diseñado para trabajar con un servidor de colegio que puede proporcionar la distribución de contenidos, el recojo de tareas, los servicios de copia de seguridad, la integración de Moodle y la filtración del acceso a Internet. El Strawberry de hoy está listo para probarse en las escuelas. [Comentarios](mailto:feedback@sugarlabs.org) se incorporarán en la próxima versión, disponible a finales de 2009. + +"Un año después de su fundación, Sugar Labs está cumpliendo su promesa de educación para su segundo millón de estudiantes", comentó Walter Bender, fundador y director ejecutivo. "Sugar es preferido porque ofrece una excelente experiencia de aprendizaje para los niños pequeños: divertida y económica. Sugar on a Stick es una gran manera de probar Sugar sin tocar el disco duro de la computadora. También es muy adecuado para las computadoras más lentas, más antiguas y para las portátiles pequeñas de baja potencia. Existe una versión para la OLPC XO-1 y se suministrará con las nuevas computadoras portátiles XO-1.5 en el otoño." + +Sugar on a Stick ofrece una experiencia coherente y consistente. Reduce costos, proporcionando flexibilidad en opciones de tipos de computadoras, permitiendo que las escuelas mantengan sus inversiones existentes en sus aparatos. Para los que tienen computadora en casa, pueden llevar el Sugar on a Stick consigo. Cada estudiante tiene un ambiente de computación coherente y comparable que los padres pueden compartir también. Además, proporciona acceso fuera de línea a aplicaciones y contenido para los alumnos que no tienen acceso a Internet en casa. + +Como parte de un esfuerzo continuo para hacer Sugar on a Stick listo para las aulas, Sugar Labs ha recibido una subvención de 20.000 dólares de la Fundación de Beneficencia Gould para aplicar un proyecto piloto de Sugar en la Academia Gardner, una escuela primaria ubicada en una de las más cultural y lingüísticamente diversas secciones de Boston, Massachusetts. + +Actividades dirigidas al aprendizaje están en el corazón de Sugar. Sugar on a Stick incluye 40 actividades de interés para los jóvenes estudiantes tales como Leer, Escribir, Pintura y Etoys. Cientos de actividades están disponibles para su descarga gratuita en la [biblioteca de Actividades de Sugar](http://activities.sugarlabs.org). La mayoría de las actividades "Sugarized" han incorporado la colaboración de estudiantes. Los alumnos y profesores trabajan, juegan y aprenden juntos en las mismas actividades. + +La plataforma de aprendizaje de Sugar es abierta. Por lo tanto, Sugar utiliza el trabajo de otros proyectos de código abierto. El software existente para los niños se puede integrar a Sugar. Por ejemplo, el reconocido GCompris, junto con 100 actividades desarrolladas en los últimos cinco años por Bruno Coudoin, fueron añadidos recientemente a Sugar; incluye actividades como Ajedrez, Geografía y Sudoku. Los maestros y padres de familia interesados en las Actividades de Sugar y su interfaz moderna pueden ver videos cortos en el recientemente inaugurado canal de [Sugar Labs Dailymotion](http://www.dailymotion.com/sugarlabs). + +Los visitantes a LinuxTag son bienvenidos a hablar con los contribuyentes de Sugar Labs en el mostrador 7.2a 110a.`,ta=Object.freeze(Object.defineProperty({__proto__:null,default:C},Symbol.toStringTag,{value:"Module"})),M=`--- +title: "Sugar Labs gibt die Veröffentlichung von Sugar on a Stick bekannt; die Lernplattform läuft auf jedem PC oder Netbook im Klassenzimmer." +category: "PRESS RELEASE" +date: "2009-06-24" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +LinuxTag, Berlin, 24. Juni 2009: Sugar Labs™, gemeinnütziger Anbieter der Sugar-Lernplattform, die weltweit von über einer Million Kindern benutzt wird, gibt die Veröffentlichung von Sugar on a Stick v1 Strawberry bekannt. Frei zum Download auf [www.sugarlabs.org](www.sugarlabs.org) verfügbar, lässt sich Sugar on a Stick auf einen gewöhnlichen 1GB-USB-Stick laden, von dem aus ein PC oder Netbook direkt in die preisgekrönte Sugar-Umgebung gebootet werden kann. Es läuft auf neuen Macs mit einer Hilfs-CD und unter Windows mittels Virtualisierung. Sugar on a Stick ist für den Betrieb mit einem Schulserver ausgelegt, der die Verteilung von Materialien, das Einsammeln von Hausaufgaben, Datensicherung, Moodle-Anbindung und gefilterten Zugriff auf das Internet bieten kann. Die gegenwärtige Strawberry-Version ist zum Testen im Klassenzimmer gedacht. [Rückmeldungen](mailto:feedback@sugarlabs.org) werden in die nächste Version einfließen, die ende 2009 verfügbar sein wird. + +"Ein Jahr nach seiner Gründung arbeitet Sugar Labs an der Auslieferung seiner Bildungszusage an die zweite Million Lernender", so Walter Bender, Gründer und Geschäftsführer. "Sugar wird bevorzugt, weil es kleinen Kindern eine überragende Lernerfahrung bietet: faszinierend und doch erschwinglich. Sugar on a Stick stellt eine wunderbare Möglichkeit dar, Sugar auszuprobieren, ohne die Festplatte des Rechners zu verändern. Es eignet sich auch gut für langsamere, ältere Rechner oder schwachbrüstige Netbooks. Es gibt eine Version für den OLPC XO-1 und es wird auf den neueren XO-1.5-Laptops diesen Herbst zu finden sein." + +Sugar on a Stick bietet eine schlüssige und einheitliche Computererfahrung. Es mindert die Kosten durch hohe Flexibilität bei der Hardware-Auswahl, was es Schulen ermöglicht, bereits vorhandene Hardware weiterhin zu nutzen. Die Lernenden können von der zunehmenden Verbreitung von Rechnern in den Haushalten profitieren: Dadurch, dass sich Sugar on a Stick mit nach Hause nehmen lässt, steht jedem Schüler eine einheitliche, vergleichbare Computerumgebung zur Verfügung, die seine Eltern ebenso nutzen können. Auch ermöglicht es Offline-Zugang zu Anwendungen und Materialien, nachdem nicht jeder Lernende zu Hause über einen Internet-Zugang verfügt. + +Als Teil der andauernden Bemühungen, Sugar on a Stick für den Einsatz im Klassenzimmer bereit zu machen, wurde Sugar Labs ein 20.000$-Zuschuss der Gould Charitable Foundation zuerkannt, um Sugar an der Gardner Pilot Academy zu implementieren, einer öffentlichen Grundschule in einem der kulturell und sprachlich vielfältigsten Viertel Bostons in Massachusetts, USA. + +Lernaktivitäten bilden das Herzstück von Sugar. Sugar on a Stick umfasst 40 Aktivitäten, um das Interesse junger Lernender zu wecken, beispielsweise Lesen, Schreiben, Malen oder Etoys. Hunderte weiterer Aktivitäten stehen in der [Sugar-Aktivitätenbibliothek](http://activities.sugarlabs.org) zum freien Download bereit. Die meisten "ver-Sugar-ten" Aktivitäten ermöglichen die Zusammenarbeit von Schülern: Schüler und Lehrer arbeiten, spielen und lernen gemeinsam in denselben Aktivitäten. Die Sugar-Lernplattform ist offen, sodass durch Einsatz anderer Open-Source-Produkte vorhandene Software für Kinder integriert werden kann. So wurde etwa die gefeierte GCompris-Suite aus 100 Aktivitäten, die die letzten fünf Jahre über von Bruno Coudoin entwickelt wurde, erst kürzlich zu Sugar hinzugefügt, darunter Aktivitäten wie Schach, Geographie oder Sudoku. Lehrer und Eltern, die sich für Sugars Aktivitäten und sein modernes Interface für Kinder interessieren, finden im unlängst eröffneten [Sugar Labs Dailymotion-Kanal](http://www.dailymotion.com/sugarlabs) kurze Videos. + +Besucher des LinuxTages sind herzlich eingeladen, mit Beitragenden zu Sugar Labs am Stand 7.2a 110a zu sprechen. +`,aa=Object.freeze(Object.defineProperty({__proto__:null,default:M},Symbol.toStringTag,{value:"Module"})),x=`--- +title: "Sugar Labs kondigt aan dat Sugar on a Stick nu beschikbaar is; dit leerplatform draait op elke pc of netbook." +category: "PRESS RELEASE" +date: "2009-06-24" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +LinuxTag, Berlijn, 24 juni 2009: Sugar Labs™ is de non-profit organisatie die het Sugar Leerplatform levert aan meer dan één miljoen kinderen over de hele wereld. Zij kondigt aan dat nu Sugar on a Stick versie 1 beschikbaar is onder de naam **"Strawberry"**. Het is gratis op te halen bij [www.sugarlabs.org](http://www.sugarlabs.org) en te installeren op een 1 GB flash drive. Daarna kan Sugar direct worden opgestart op een PC of netbook. Het draait ook op recente Macs met een hulp-CD en in Windows met gebruik van virtualisatie. + +Sugar on a Stick is ontworpen in combinatie met een School Server, waarmee het volgende kan worden verzorgd: distributie van informatie/leerstof, huiswerk verzamelen, backups maken, integratie met Moodle en gefilterde toegang tot het internet. Deze "Strawberry"-versie is bedoeld om in de klas te testen; feedback zal in de volgende versie worden opgenomen en komt tegen het einde van 2009 beschikbaar. + +> "Eén jaar na oprichting maakt Sugar Labs haar beloften waar voor haar tweede miljoen studenten," zegt Walter Bender, oprichter en directeur. +> "Sugar heeft de voorkeur, want het is een superieure leeromgeving voor jonge kinderen: motiverend en betaalbaar. Sugar on a Stick is een geweldige manier om het uit te proberen zonder de harde schijf te veranderen. Het is ook geschikt voor oudere pc’s en langzamere netbooks. Er is een versie voor de OLPC XO-1 en het zal geleverd worden met de nieuwere XO-1.5 laptops in de herfst." + +Sugar on a Stick geeft een samenhangend en consistente werkomgeving. Het vermindert kosten doordat het op veel hardware kan worden geïnstalleerd, zodat scholen hun bestaande apparatuur kunnen blijven gebruiken. Het komt de leerlingen ten goede dat zij hun vertrouwde Sugar on a Stick-omgeving mee naar huis kunnen nemen en het ook kunnen delen met hun ouders. Het geeft ook offline toegang tot hun activiteiten en leerstof, daar niet iedere leerling thuis internet heeft. + +Als onderdeel van een voortdurende inspanning om Sugar on a Stick klaar te maken voor de klas, heeft Sugar Labs een donatie van **$20.000** ontvangen van de Gould Charitable Foundation om Sugar te installeren op de Gardner Pilot Academy, een openbare basisschool in een wijk van Boston, Massachusetts met één van de grootste verscheidenheid aan achtergronden qua cultuur en taal. + +Leeractiviteiten zijn het hart van Sugar. Sugar on a Stick bevat **veertig activiteiten** voor jonge leerlingen zoals lezen, schrijven, tekenen en eToys. Er zijn nog honderden andere activiteiten gratis op te halen bij de [Sugar Activiteiten Bibliotheek](http://activities.sugarlabs.org). De meeste van deze activiteiten hebben samenwerking ingebouwd: leerlingen en onderwijskrachten werken, spelen en leren samen. + +Het Sugar Leerplatform is open, dus andere bestaande open-sourceprojecten voor kinderen kunnen erin geïntegreerd worden. Zo is de bekende **GCompris-suite** van honderd activiteiten onlangs toegevoegd aan Sugar, met activiteiten als schaken, aardrijkskunde en sudoku. Dit project werd de afgelopen vijf jaar door **Bruno Coudoin** ontwikkeld. + +Leerkrachten en ouders die geïnteresseerd zijn in Sugar-activiteiten en de moderne interface voor kinderen kunnen korte video’s bekijken op het onlangs geopende [Sugar Labs Dailymotion-kanaal](http://www.dailymotion.com/sugarlabs). + +Bezoekers aan LinuxTag zijn welkom bij stand **7.2a 110a** om te komen praten met Sugar Labs-medewerkers.`,oa=Object.freeze(Object.defineProperty({__proto__:null,default:x},Symbol.toStringTag,{value:"Module"})),G=`--- +title: "Sugar Labs and Free Software Foundation Celebrate Software Freedom Day, Announce Joint Efforts to Promote the Sugar Learning Platform for Children Worldwide" +category: "PRESS RELEASE" +date: "2009-11-18" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +CAMBRIDGE, MA, September 18, 2009 — Sugar Labs, nonprofit provider of the Sugar Learning Platform for children, and the Free Software Foundation (FSF), which promotes computer users’ right to use, study, copy, modify, and redistribute computer programs, have announced joint efforts to collaborate and promote Sugar on the occasion of **Software Freedom Day**, September 19th. + +The FSF will host an event in Boston featuring Sugar Labs Executive Director **Walter Bender**, FSF president **Richard Stallman**, and other speakers. **Peter Brown**, FSF’s executive director, said: + +> “The Sugar Learning Platform is fast becoming an essential route to computer user freedom for children around the world. The international free software movement is getting behind Sugar, and we want to use Software Freedom Day as an opportunity to help draw community attention, developer resources, and external funders to the important work going on at Sugar Labs.” + +The FSF has upgraded its hosting services support of Sugar Labs to keep pace with its growth. As part of the ongoing relationship, **Bernardo Innocenti**, a member of the Sugar Labs Oversight Board, is working at the FSF offices. Mr. Innocenti stated: + +> “The FSF and Sugar Labs are pursuing distinct, but interdependent goals; Free (as in Freedom) Software is a fundamental part of globally accessible education, and good education enables critical thought, a pre-requisite for appreciating the value of Freedom.” + +Sugar is a global project. Translated into **25 languages**, it is used in classrooms in **40 countries** by over **1 million children** as part of the **One Laptop per Child (OLPC)** nonprofit program. Sugar’s simple interface, built-in collaboration, and automatic backup through each student’s Journal have been designed to interest young learners. + +The recently released **Sugar on a Stick (SoaS)** project brings Sugar to even more children, allowing young learners to keep a working copy of Sugar on a simple USB stick, ready to start up any PC or netbook with the child’s environment and data. Pilot projects in schools with Sugar on a Stick are underway in **Boston**, **Berlin**, and elsewhere. + +SoaS is **free software** available under the **General Public License (GPL)** and is available for download without charge at [sugarlabs.org](http://www.sugarlabs.org). + +According to Walter Bender: + +> “Sugar is running on over 99% of all of the OLPC-XO laptops around the world because governments prefer its quality, openness, built-in collaboration, and easy localization to indigenous languages. Teachers and students are exercising their freedom by modifying and improving Sugar and its Activities. With Sugar on a Stick, access to Sugar is even more widespread.” + +For example, **Uruguay** has distributed a Sugar-equipped OLPC laptop to every student in the country. [Alexandre Oliva of FSF’s sister organization Free Software Foundation Latin America](http://www.fsfla.org) said: + +> “I was amazed when I first saw Sugar in action in Peru two years ago; shortly thereafter, my daughter tasted Sugar and loved it. She’s going to elementary school next year, and I’m very happy she can now easily carry Sugar with her, and share it with her friends. Myself, I’m going to spread its freedom into as many schools as I can.” + +**Karsten Gerloff**, President of [Free Software Foundation Europe](http://fsfe.org), added: + +> “Education and Free Software are both all about sharing knowledge. Through projects like Sugar, young people around the world can discover the creativity that freedom makes possible. Together with the political backing that FSFE’s Edu-Team and others are building, Sugar puts Free Software in its rightful place in education.” + +Sugar Labs relies on the efforts of **software developers** who donate their skills to the project. Mr. Bender continued: + +> “We are looking for developers with experience in GNU/Linux, Python and/or Gtk+ for contributing to the Sugar shell and educational Activities for children. We also need testers, experienced packagers, and educators willing to contribute their ideas for Sugar in the classroom.”`,ia=Object.freeze(Object.defineProperty({__proto__:null,default:G},Symbol.toStringTag,{value:"Module"})),_=`--- +title: "L’association à but non lucratif Sugar Labs annonce la version 2 de “Sugar on a Stick” qui améliore la lecture de livres électroniques et transforme n’importe quelle clé USB en une plate-forme éducative pour les enfants ; partenariat avec Nexcopy, Inc." +category: "PRESS RELEASE" +date: "2009-12-08" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> +PARIS, le 8 décembre 2009 - **Netbook World Summit** - Sugar Labs® la communauté de volontaires développant la plate-forme éducative Sugar déjà diffusée à plus d’un million d’enfants dans le monde, annonce la sortie de **Sugar on a Stick v2 “Blueberry” (Myrtille)**. + +Disponible en téléchargement sur [http://www.sugarlabs.org][0], Sugar on a Stick peut s’installer sur toute clé USB de 1Go ou plus et permet, sans modifier l’installation, de faire fonctionner n’importe quel PC, netbook ou un Mac récent, dans l’environnement pour enfant Sugar. Sugar est également disponible pour la plupart des distributions GNU/Linux, peut fonctionner de manière virtualisée sur Windows et Apple OS X et intègre nativement des fonctionnalités de collaboration et de sauvegarde dans le Journal des activités. + +La dernière version de Sugar propose : +- une navigation web simplifiée, +- une meilleure gestion des réseaux sans fil, +- un portail d’installation de nouvelles Activités pour enfants, +- une configuration clavier facilitée, +- et l’intégration de **Gnash** pour le support des contenus Adobe Flash. + +De nouvelles Activités comme **Physiques** et **OOo4Kids** complètent les applications favorites telles que **Naviguer** et **Lire**, adaptées à la lecture de livres électroniques. + +> “Sugar on a Stick est une merveilleuse manière d’expérimenter Sugar,” commente Walter Bender, le président exécutif du Sugar Labs. “En cette période de fêtes de fin d’année, nous souhaitons rappeler aux parents et aux enseignants que les livres électroniques ne sont pas réservés à des coûteux lecteur dédiés, mais font partie du mouvement libre d’accès à la connaissance pour aider les enfants partout dans le monde à développer un accès critique à la connaissance et combler le fossé numérique partout où il existe.” + +Sugar on a Stick intègre plusieurs activités de lecture de livres électroniques pour télécharger et visualiser des livres aux formats PDF, EPUB et DejaVu. De plus, l’Activité **Read Etexts** peut lire des livres électroniques à haute voix, permettant de convertir n’importe quel vieux PC ou un netbook à bas coût en un outil de lecture audio pour les personnes à vision réduite. Avec Sugar, les enfants peuvent même construire leurs propres livres électroniques. + +Des centaines de livres électroniques pour enfants sont disponibles sur : +- [Projet Gutenberg](https://www.gutenberg.org), +- [Internet Archive Children’s Library](https://archive.org/details/iacl), +- [epubBooks.com](https://www.epubbooks.com), +- [Feedbooks.com](https://www.feedbooks.com), +- [ManyBooks.net](https://manybooks.net), +- et d’autres comme [International Children’s Digital Library](http://en.childrenslibrary.org). + +Des projets pilotes sont en cours dans des écoles aux États-Unis et en Europe. Les responsables d’écoles intéressés par Sugar seront ravis de découvrir la mise à jour du **Serveur d’école XS**, qui permet : +- un accès protégé à Internet, +- la distribution de contenu, +- une intégration Moodle, +- et des sauvegardes centralisées. + +Pour soutenir ce déploiement, Sugar Labs a établi un partenariat avec **Nexcopy, Inc.**, basée à Rancho Santa Margarita, Californie. Nexcopy, spécialiste des solutions de duplication USB, a lancé le site [http://recycleusb.com](http://recycleusb.com). Ils récupèrent des clés USB, les chargent avec Sugar on a Stick, puis les renvoient au Sugar Labs pour distribution dans les écoles. Nexcopy a également offert une unité de réplication de 20 clés au projet. + +> Greg Morris, Président de Nexcopy, commente : +> “Nexcopy est fier d’être partenaire avec une organisation à but non lucratif comme le Sugar Labs. Nous sommes convaincus que la plate-forme éducative Sugar est un pas dans la bonne direction pour permettre aux enfants d’être efficaces avec les ordinateurs. Notre objectif est de donner au Sugar Labs le support et l’équipement nécessaire pour permettre le succès de cette opération philanthropique et permettre la production de masse d’un grand nombre de clés Sugar pour un déploiement global. Je suis très honoré que Nexcopy fasse partie de ce processus.” + +### À propos du Sugar Labs +Sugar Labs est une organisation non lucrative de volontaires, membre du projet **Software Freedom Conservancy**. À l’origine intégré au projet One Laptop Per Child, Sugar Labs coordonne les efforts mondiaux pour fournir des opportunités éducatives à travers la plate-forme Sugar. Soutenu par des dons, Sugar Labs cherche activement des fonds pour accélérer son développement. +🔗 [http://www.sugarlabs.org](http://www.sugarlabs.org ) + +### À propos de Nexcopy Incorporated +Nexcopy Incorporated est spécialisée dans le développement d’outils de duplication de mémoire flash de haute performance. Présente sur les marchés d’Amérique Centrale et du Sud, d’Europe, d’Inde, d’Asie, ainsi que sur le marché américain, la société est basée en Californie. + +--- + +Sugar Labs est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leurs auteurs. +`,ra=Object.freeze(Object.defineProperty({__proto__:null,default:_},Symbol.toStringTag,{value:"Module"})),E=`--- +title: "Sugar Labs Nonprofit Announces v2 of Sugar on a Stick with Improved E-Book Readers, Recycles Any USB Stick Into Learning Environment for Children; Partners with Nexcopy, Inc." +category: "PRESS RELEASE" +date: "2009-12-08" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +PARIS, December 8, 2009 — Netbook World Summit — Sugar Labs® (R), volunteer-driven nonprofit provider of the Sugar Learning Platform for over one million children around the world, announces the release of Sugar on a Stick v2 “Blueberry.” Available for download at [http://www.sugarlabs.org](http://www.sugarlabs.org), Sugar on a Stick can be loaded onto any ordinary 1GB or greater flash drive to reboot any PC, netbook or recent Mac directly into the child-friendly Sugar environment without touching the existing installation. + +Sugar is also available for GNU/Linux distributions, runs under virtualization on Windows and Apple OS X, and features built-in classroom collaboration and automatic backup to a Journal. The latest version of Sugar offers simpler navigation, improved wireless networking, streamlined updating of Activities for children, easier keyboard configuration, better Gnash support for Adobe Flash content, and more. New Activities such as Physics and OOo4Kids join updated favorites such as Browse and Read, suitable for reading e-books. + +“Sugar on a Stick is a great way to experience Sugar,” commented Walter Bender, Sugar Labs executive director. “In this holiday season, we wish to remind parents and teachers that e-books are not only for costly reader units for the well-to-do, but freely available as part of the open-access to knowledge movement to help children everywhere develop critical learning skills and to bridge the digital divide wherever it exists.” + +Sugar on a Stick includes several e-book reader Activities to find and display e-books in PDF, EPUB, and DejaVu formats. The Read Etexts Activity can read e-books out loud, converting any old PC or inexpensive netbook into a text-to-speech aid for disabled readers. With Sugar, children can even make their own e-books. Thousands of e-books for children are available on websites such as Project Gutenberg, the Internet Archive Children’s Library, epubBooks.com, Feedbooks.com, and ManyBooks.net. Other sites offer online reading, such as the International Children’s Digital Library. + +Pilot Sugar projects are underway in American and European schools. School administrators wishing to deploy Sugar will be interested in OLPC’s recently updated XS school server software, which provides “safety net” and connectivity services at the school level: backup, content distribution, filtered access to the Internet, and Moodle integration. + +To assist schools interested in testing this technology, Sugar Labs has partnered with Nexcopy, Inc. of Rancho Santa Margarita, California, an industry leader in USB duplicator solutions, to open [http://recycleusb.com](http://recycleusb.com). Nexcopy will collect used USB sticks, reload them with Sugar on a Stick, and forward them to Sugar Labs for distribution to schools. Nexcopy has also donated a 20-stick USB duplication unit to Sugar Labs. + +Greg Morris, President of Nexcopy, commented, “Nexcopy is proud to partner with a nonprofit organization such as Sugar Labs. We believe the Sugar Learning Platform is clearly a step in the right direction for getting children involved with personal computers. Our objective is to give Sugar Labs the back-end equipment support needed to make this philanthropy successful and help with producing the large number of Sugar Sticks needed for global deployment. I am very honored Nexcopy is a part of this process.” + +**About Sugar Labs**: Sugar Labs, a volunteer-driven, nonprofit organization, is a member project of the Software Freedom Conservancy. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. Sugar Labs is supported by donations and is seeking funding to accelerate development. For more information, please visit [http://www.sugarlabs.org](http://www.sugarlabs.org). + +**About Nexcopy Incorporated**: Nexcopy Incorporated specializes in developing and manufacturing the finest and most feature-rich flash memory duplicators in the market. Pioneering the solid-state memory duplication market, Nexcopy supplies Central and South America, Europe, India, Asia, Pacific Rim and serves the U.S. market through its headquarters in California. + +Sugar Labs is a registered trademark of the Software Freedom Conservancy. Other names are trademarks of their respective owners.`,sa=Object.freeze(Object.defineProperty({__proto__:null,default:E},Symbol.toStringTag,{value:"Module"})),D=`--- +title: "L'Office de secours et de travaux des Nations unies choisi les ordinateurs du projet One Laptop per Child et la plate-forme Sugar pour un projet majeur d'éducation au proche orient" +category: "PRESS RELEASE" +date: "2010-04-29" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +CAMBRIDGE, Mass, 29 avril 2010 - L'Office de secours et travaux des Nations unies pour les réfugiés de Palestine au proche orient ([UNRWA](http://www.unrwa.org)) a annoncé un programme ambitieux de 3 ans pour fournir à un demi-million d'enfants réfugiés Palestinien, dans la bande de Gaza, au Liban, en Syrie et en Jordanie, un ordinateur équipé de la plateforme éducative Sugar, plusieurs fois primée. + +"Motiver la prochaine génération en lui donnant l'accès à la connaissance et à l'apprentissage est capital pour les projets éducatifs de l'UNRWA. Nous enseignons à 500 000 enfants au Proche Orient chaque jour et donner à chacun d'entre eux un ordinateur sera une énorme contribution pour combler le fossé technologique et d'accès au savoir dans l'une des régions les plus troublée du monde", a indiqué Chris Gunness, le porte-parole de l'UNWRA. + +Selon Walter Bender, fondateur et directeur exécutif du Sugar Labs: "Aujourd'hui, de la forêt vierge du Pérou aux steppes de Mongolie, des collines du Rwanda aux montages d'Afghanistan, un million et demi d'enfants apprennent chacun dans leur langue maternelle, sur les ordinateurs XO du projet OLPC grâce à Sugar et sa suite d'Activités d'apprentissage. Le projet de l'UNRWA ajoutera un demi-million d'apprenants supplémentaires en provenance de la vallée de Jordanie et du Moyen Orient, et d'autres projets vont voir le jour prochainement. C'est une génération entière qui apprend avec Sugar." + +Le cœur de Sugar, ce sont ses Activités pour les enfants ([http://activities.sugarlabs.org](http://activities.sugarlabs.org)). Amusant et motivant, ce sont des programmes qui permettent de lire des livres électroniques, d'écrire, de dessiner, de naviguer sur Internet, de programmer et plein d'autres choses. Sugar intègre de plus le travail collaboratif et l'enregistrement des activités réalisées dans le journal ce qui le rend particulièrement adapté à l'utilisation en classe mais aussi en dehors de l'école pour continuer les apprentissages. Complété par un serveur d'école XS, un logiciel libre et ouvert proposé par le projet One Laptop Per Child, il permet de fournir aux jeunes apprenants un environnement connecté sûr et sécurisé. + +Les contenus existant de l'UNRWA seront adaptés à Sugar et la formation des enseignants va démarrer prochainement. Le projet de l'UNRWA fait suite au déploiement l'année dernière de 1000 ordinateurs XO dans les écoles Palestinienne par le PEI (Palestine Education Initiative [http://www.pei.gov.ps](http://www.pei.gov.ps), [http://en.palexo.com](http://en.palexo.com)). Sugar Labs est à la recherche de développeurs et de volontaires pour faire de ce projet un vrai succès. + +A propos du Sugar Labs: Sugar Labs est un organisation non lucrative de volontaires, membre du projet Software Freedom Conservancy. A l’origine intégré au projet One Laptop Per Child, Sugar Labs coordonne les volontaires dans le monde qui sont passionés par l’idée de fournir des opportunités d’éducation à travers la plate-forme éducative Sugar. Sugar Labs est soutenu par des donations et cherche des fonds pour accélérer son développement. Pour plus d’information, voir [http://www.sugarlabs.org](http://www.sugarlabs.org) + +Sugar Labs est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leur auteurs.`,la=Object.freeze(Object.defineProperty({__proto__:null,default:D},Symbol.toStringTag,{value:"Module"})),j=`--- +title: "United Nations Relief and Works Agency Sceglie i Laptop di One Laptop per Child con Sugar per un Importante Progetto Educativo in Medio Oriente" +category: "PRESS RELEASE" +date: "2010-04-29" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +CAMBRIDGE, Mass., 29 Aprile, 2010 — L'Agenzia delle Nazioni Unite per i rifugiati della Palestina nel Medio Oriente ([UNRWA](http://www.unrwa.org)) ha annunciato un ambizioso programma triennale per fornire un computer portatile dotato del premiato ambiente software Sugar Learning Platform a mezzo milione di bambini palestinesi rifugiati nella Striscia di Gaza, Libano, Siria, e Giordania. + +“Rafforzare la prossima generazione grazie a conoscenza e capacità di apprendimento è l'aspetto centrale per progetti educativi dell'UNRWA. Ogni giorno forniamo istruzione a 500.000 bambini nel Medio Oriente e fornire ad ognuno di loro un laptop sarà un grande aiuto a chiudere il gap di conoscenza e tecnologie in una delle regioni del mondo con maggiori problemi,” dice Chris Gunness, portavoce dell'UNRWA. + +Walter Bender, fondatore e Direttore Esecutivo di Sugar Labs, dichiara: “Ad oggi, un milione e mezzo di bambini, dalle foreste equatoriali del Perù alle steppe della Mongolia, dalle colline del Rwanda alle montagne dell'Afganistan, stanno imparando, utilizzando la loro lingua madre grazie a Sugar e alla collezione di Attività didattiche con i laptop XO di OLPC. Il progetto di UNRWA accrescerà di un altro mezzo milione di studenti nella valle del Giordano e nel Medio Oriente, altri progetti sono in sviluppo. Una intera nuova generazione sta apprendendo con Sugar.” + +Al cuore di Sugar sono le Attività: [http://activities.sugarlabs.org](http://activities.sugarlabs.org) – programmi divertenti e appassionanti, nati per leggere libri elettronici, scrivere, disegnare, navigare la rete Internet, programmare, e molto altro ancora. Sugar integra capacità di collaborazione fra utenti e di memorizzazione dei dati in una struttura organizzata in base temporale (Diario), funzionalità estremamente adatte sia ad un utilizzo in classe che per continuare ad apprendere e studiare anche al di fuori della scuola. Il sistema XS School Server, basato su software libero, reso disponibile da One Laptop per Child, permette un accesso sicuro e filtrato alla rete Internet per i giovani studenti. + +I materiali didattici di UNRWA esistenti saranno adattati a Sugar e si sta già provvedendo anche alla formazione dei docenti. Il progetto di UNRWA segue le orme della distribuzione avvenuta lo scorso anno di 1000 laptops XO nelle scuole della Palestina a cura della Palestine Education Initiative ([http://www.pei.gov.ps](http://www.pei.gov.ps), [http://en.palexo.com](http://en.palexo.com)). Sugar Labs è lieta di accogliere sviluppatori e volontari che vogliano collaborare alla riuscita di questa iniziativa.`,da=Object.freeze(Object.defineProperty({__proto__:null,default:j},Symbol.toStringTag,{value:"Module"})),W=`--- +title: "United Nations Relief and Works Agency chooses One Laptop per Child Laptops with Sugar for Major Education Project in Mideast" +category: "PRESS RELEASE" +date: "2010-04-29" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +CAMBRIDGE, Mass, April 29, 2010 - The United Nations Relief and Works Agency for Palestine Refugees in the Near East (UNRWA, [http://www.unrwa.org](http://www.unrwa.org)) has announced an ambitious three-year program to provide a laptop loaded with the award-winning Sugar Learning Platform to one-half million Palestine refugee children in the West Bank and Gaza, Lebanon, Syria, and Jordan. + +“Empowering the next generation through knowledge and learning is central to UNRWA’s education projects. We are teaching 500,000 children in the Middle East every day and having all of them with a laptop will be a huge contribution to bridging the technology and knowledge gap in one of the most troubled regions of the world,” said Chris Gunness, UNWRA Spokesman. + +Walter Bender, founder and Executive Director of Sugar Labs, said: “Today, one-and-one-half-million children, from the rain forests of Peru to the steppes of Mongolia, from the hills of Rwanda to the mountains of Afghanistan, are learning in their native tongues with Sugar and its suite of learning Activities on OLPC’s XO laptops. The UNRWA project will add one-half million more learners in the Jordan valley and throughout the Middle East, and more projects are on the way. An entire generation is learning with Sugar.” + +The heart of Sugar is its Activities for children ([http://activities.sugarlabs.org](http://activities.sugarlabs.org)), fun and engaging programs for reading e-books, writing, drawing, browsing the Internet, programming, and so on. Sugar has collaboration and backup to a Journal built-in, making it particularly well-suited both for the classroom and outside school where learning continues. The free open source XS School Server, available from One Laptop per Child, provides a safely filtered online environment for young learners. + +Existing UNRWA learning content will be adapted to Sugar and teacher training is underway. The UNRWA project follows last year’s deployment of 1000 XO laptops in Palestinian schools by the Palestine Education Initiative ([http://www.pei.gov.ps](http://www.pei.gov.ps), [http://en.palexo.com](http://en.palexo.com)). Sugar Labs welcomes developers and volunteers to make this important endeavor successful. + +About Sugar Labs: Sugar Labs, a volunteer-driven, nonprofit organization, is a member project of the Software Freedom Conservancy. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. Sugar Labs is supported by donations and is seeking funding to accelerate development. For more information, please visit [http://www.sugarlabs.org](http://www.sugarlabs.org).`,ca=Object.freeze(Object.defineProperty({__proto__:null,default:W},Symbol.toStringTag,{value:"Module"})),O=`--- +title: "La Plataforma de Aprendizaje Sugar y el Escritorio GNOME se distribuirán hoy en la One Laptop per Child modelo XO-1.5; también se ejecutará en el nuevo XO-HS High School Edition" +category: "PRESS RELEASE" +date: "2010-06-04" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +ASUNCIÓN, 14 de junio de 2010 — Sugar Labs, el Proyecto de Escritorio Libre GNOME, y One Laptop per Child (OLPC) han anunciado una actualización del software que se ofrece en el OLPC XO-1.5. Los 1,5 millones de niños que ya usan Sugar en el XO-1 original también podrán beneficiarse de la actualización ya que Paraguay Educa ha portado el software. + +La plataforma de aprendizaje Sugar promueve el aprendizaje colaborativo a través de Actividades amigables para los niños que fomentan el pensamiento crítico. El escritorio libre GNOME es un componente distinguido de todas las principales distribuciones de GNU/Linux, adecuado para niños mayores y adultos. El cambio entre los dos entornos se realiza con un único click. Con GNOME en el portátil XO, se abre la puerta a miles de aplicaciones de formación y de productividad adicionales. + +El XO-1.5 tiene el mismo diseño industrial que el XO-1 original. Está basado en un procesador VIA, que proporciona el doble de velocidad que el XO-1, y tiene 4 veces más de memoria DRAM y memoria FLASH. OLPC ha anunciado la disponibilidad de una edición para secundaria del XO-1.5, el XO-HS High School Edition, con un diseño de teclado nuevo, más cómodo para los estudiantes mayores. El primer despliegue del XO-HS está programado para empezar en Uruguay en el marco del exitoso Plan Ceibal a partir de septiembre. + +Los niños familiarizados con el XO-1 evolucionarán naturalmente a las funcionalidades ampliadas del XO-1.5. "One Laptop per Child promueve software libre y de código abierto para que pueda evolucionar y adaptarse a las necesidades de los niños. La plataforma Sugar en el XO es clave para nuestra misión educativa porque proporciona a los estudiantes un entorno de software de aprendizaje único e intuitivo", dijo el director ejecutivo de la asociación OLPC Rodrigo Arboleda. + +Stormy Peters, Directora Ejecutiva de la GNOME Foundation, dice: “Estamos muy entusiasmados de estar trabajando con Sugar y OLPC para proveer software de escritorio para niños de todas las edades. La misión de GNOME es proporcionar un escritorio libre y accesible para todos. Los niños, desde Uruguay hasta Ghana, serán capaces de utilizar sus XO para aprender y mostrar a sus amigos y familias cómo usar Sugar y GNOME." + +Walter Bender, director ejecutivo de Sugar Labs, dijo que "la fluidez de cambio entre los dos escritorios ofrece al alumno la capacidad de transición de un entorno de aprendizaje —Sugar— a un entorno de producción —GNOME—. Así disponen de los medios para perfeccionar las habilidades creativas adquiridas en educación primaria, con las capacidades emprendedoras de la educación secundaria". + +“Sugar on a Stick” permite a los niños que no tienen un ordenador portátil XO beneficiarse de este nuevo software. Disponible para descarga desde Sugar Labs, en la nueva distribución v3 Mirabelle, puede ser cargada en un pendrive USB común y usarse para iniciar Sugar en una PC sin tocar el disco duro. Las laptops XO y Sugar on a Stick ejecutan Fedora GNU/Linux. + +**Acerca de Sugar Labs®:** Sugar Labs es una organización dirigida por voluntarios, sin ánimo de lucro y es un proyecto miembro de Software Freedom Conservancy. Originalmente parte del proyecto One Laptop Per Child, Sugar Labs coordina voluntarios en todo el mundo apasionados por la posibilidad de proveer oportunidades educacionales a niños a través de la Sugar Learning Platform. Sugar Labs es soportada por donaciones y está en busca de apoyo económico y voluntarios para acelerar el desarrollo. Para más información, por favor visita: [http://www.sugarlabs.org](http://www.sugarlabs.org). + +**Acerca de GNOME:** GNOME es un proyecto de software libre que desarrolla un estándar de escritorio completo, accesible y fácil de utilizar en todas las distribuciones principales de GNU/Linux y Unix. Popular en instalaciones corporativas grandes y entre millones de pequeñas y medianas empresas y usuarios domésticos a lo largo del mundo, incluye un entorno de desarrollo para crear nuevas aplicaciones. La Fundación GNOME se compone de cientos de desarrolladores voluntarios y compañías líderes de la industria. Se puede obtener mayor información en [http://www.gnome.org](http://www.gnome.org) y [http://foundation.gnome.org](http://foundation.gnome.org). + +**Acerca de One Laptop per Child:** ([http://www.laptop.org](http://www.laptop.org)) OLPC es una organización sin ánimo de lucro creada por Nicholas Negroponte y otros del Media Lab del MIT para diseñar, fabricar y distribuir portátiles lo suficientemente baratos como para proporcionar a cada niño en el mundo acceso al conocimiento y a las formas modernas de educación.`,ua=Object.freeze(Object.defineProperty({__proto__:null,default:O},Symbol.toStringTag,{value:"Module"})),B=`--- +title: "Sugar Labs Announces New Version of Sugar on a Stick, Educational Software for Children" +category: "PRESS RELEASE" +date: "2010-06-10" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +BERLIN, June 10, 2010 — LinuxTag — Sugar Labs®, nonprofit provider of the Sugar Learning Platform to over one and a half million children worldwide, has released Mirabelle, the third version of Sugar on a Stick, a collaborative learning environment that can be loaded onto any ordinary USB thumbdrive and used with a PC, netbook or Mac without touching the hard disk. It is available free for download at [https://wiki.sugarlabs.org/go/Sugar_on_a_Stick](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick). Sugar runs natively on major GNU/Linux distributions and can also run in virtualization under Microsoft Windows and Apple OS X. + +One year after the premiere of v1 Strawberry at LinuxTag 2009 and following v2 Blueberry last December, v3 Mirabelle brings improved stability and simplified customization to curious teachers interested in testing Sugar on new netbooks or PCs already in the classroom. We suggest teachers reach out to university-level computer science and education schools to build local support structures, important with an ICT project. + +Sebastian Dziallas, Project Lead for Sugar on a Stick and a recent high school graduate based in Germany, said, "Teachers have told us how important reliability is in the classroom while engaging students, so we decided to create a release that has a stable core and can be customized to fit every deployment's needs. Mirabelle is a solid baseline which teachers can customize with Activities interesting to young learners. Part of our strategy is to achieve sustainable development while inviting new contributors. We achieved this by integrating Sugar on a Stick more closely with Fedora, the underlying GNU/Linux distribution; Mirabelle is now an official Fedora Spin." + +Sugar Labs is also making available a Sugar Creation Kit, a downloadable DVD which includes Mirabelle, documentation, and a library of Sugar Activities, fun and engaging programs for children taken from the [Sugar Activity Library](http://activities.sugarlabs.org). + +Thomas Gilliard, a Sugar Labs contributor, said, "The Sugar Creation Kit turns any PC into a Sugar on a Stick generating station. Tools and documentation are gathered on one disk; busy teachers don't have to hunt down anything. This makes it possible to work via 'sneaker net' and in a classroom behind a firewall." + +Visitors to LinuxTag are invited to meet Sugar Labs contributors at Hall 7.2a, Booth 115. + +**About Sugar Labs**: Sugar Labs, a volunteer-driven, nonprofit organization, is a member project of the Software Freedom Conservancy. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. Sugar Labs is supported by donations and is seeking funding to accelerate development. For more information, please visit [http://www.sugarlabs.org](http://www.sugarlabs.org).`,ha=Object.freeze(Object.defineProperty({__proto__:null,default:B},Symbol.toStringTag,{value:"Module"})),R=`--- +title: "Sugar Labs Annuncia una Nuova Versione di Sugar on a Stick, piattaforma software educativa per bambini" +category: "PRESS RELEASE" +date: "2010-06-10" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +**BERLINO, 10 Giugno, 2010 — LinuxTag** — Sugar Labs®, il produttore nonprofit della Sugar Learning Platform utilizzata da più di un milione e mezzo di bambini nel mondo, ha rilasciato *Mirabelle*, la terza versione di Sugar on a Stick, una piattaforma collaborativa di apprendimento che può essere caricata su un normale disco rimovibile USB e utilizzata su un PC, netbook o Mac senza alcuna modifica al disco rigido del sistema ospite. È liberamente disponibile per il download all'indirizzo [https://wiki.sugarlabs.org/go/Sugar_on_a_Stick](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick). +Sugar funziona in modo nativo sulle principali distribuzioni GNU/Linux e attraverso la virtualizzazione su Microsoft Windows e Apple OS X. + +Esattamente un anno dopo la premiere della v1 Strawberry al LinuxTag 2009 e dopo la v2 Blueberry resa disponibile lo scorso dicembre, la v3 Mirabelle presenta maggior stabilità e una più facile personalizzazione per gli insegnanti interessati a sperimentare Sugar sui nuovi netbook o PC eventualmente già presenti in classe. Suggeriamo agli insegnanti di contattare facoltà universitarie di informatica ed educazione per costruire strutture di supporto locali, fondamentali per un progetto ICT. + +Sebastian Dziallas, Project Leader di Sugar on a Stick e neodiplomato residente in Germania, dichiara: +> “Gli insegnanti ci hanno detto quanto l'affidabilità sia fondamentale lavorando in classe con gli studenti, quindi abbiamo deciso di creare una versione caratterizzata da un core affidabile e che potesse poi essere personalizzata per soddisfare qualsiasi esigenza di rilascio. +> Mirabelle è una base solida che gli insegnanti possono personalizzare con le Attività maggiormente interessanti per i loro giovani studenti. +> La nostra strategia è mirata anche a sviluppare la piattaforma grazie alla collaborazione di nuovi contributori. Abbiamo ottenuto questo grazie anche alla integrazione più stretta di Sugar on a Stick con Fedora, la distribuzione GNU/Linux su cui è basato; Mirabelle ora è un Fedora Spin ufficiale.” + +Sugar Labs rende inoltre disponibile un **Sugar Creation Kit**, un DVD scaricabile che include Mirabelle, documentazione e una completa libreria di Attività Sugar, programmi divertenti ed interessanti estratti dalla Sugar Activity Library disponibile online ([http://activities.sugarlabs.org](http://activities.sugarlabs.org)). + +Thomas Gilliard, un contributore di Sugar Labs, commenta: +> “Il *Sugar Creation Kit* trasforma ogni PC in una stazione in grado di produrre istanze di Sugar on a Stick. Strumenti e documentazione sono tutti raccolti in un unico disco; gli insegnanti non perderanno tempo nella ricerca di quanto possa essere utile alla loro attività didattica. +> Questo strumento permette inoltre di lavorare via 'sneaker net' (non connessi a Internet) e in aule protette da firewall.” + +I visitatori del LinuxTag sono invitati ad incontrare gli sviluppatori di Sugar Labs presso il **Booth 115, Hall 7.2a**.`,ga=Object.freeze(Object.defineProperty({__proto__:null,default:R},Symbol.toStringTag,{value:"Module"})),z=`--- +title: "Sugar Labs annonce la nouvelle version de «Sugar-On-A-Stick», son système éducatif à destination des enfants" +category: "PRESS RELEASE" +date: "2010-06-10" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + + +Berlin, le 10 juin 2010 - LinuxTag - Sugar Labs, organisation à but non lucratif à l’origine du développement de la plateforme éducative Sugar (déjà utilisée par plus de 1,5 millions d’enfants dans le monde), a dévoilé la troisième version de Sugar on a Stick, «Mirabelle», qui offre un environnement d’apprentissage collaboratif, utilisable depuis un PC, un netbook ou un Mac, sans aucune manipulation sur le système d’exploitation d’origine installé sur son disque, en utilisant une simple clé USB préchargée. Sugar on a Stick est téléchargeable à l’adresse suivante : [https://wiki.sugarlabs.org/go/Sugar_on_a_Stick](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick). Le programme Sugar fonctionne nativement avec la majorité des distributions GNU/Linux et peut être également utilisé depuis une machine virtuelle sur environnement Microsoft Windows ou Apple OS X. + +Un an après la première version de Sugar on a Stick («Strawberry») présentée lors de la conférence LinuxTag 2009 et suivi par «Blueberry» en décembre dernier, la nouvelle version «Mirabelle» apporte une meilleure stabilité et améliore les possibilités de personnalisation du système qui est offerte aux enseignants curieux et désireux d’utiliser Sugar sur les ordinateurs déjà présents en classe. D’ailleurs, nous recommandons vivement aux enseignants de développer autour de leur projet les différentes interactions et les échanges, en particulier avec le milieu universitaire autour de l’information ou des sciences de l’éducation. C’est un élément essentiel pour mener à bien un projet TICE. + +Sebastian Dziallas, chef de projet Sugar on a Stick, et étudiant allemand récemment diplômé rapporte que «les enseignants nous ont dit à quel point la fiabilité du programme est importante lorsqu’il est utilisé par les élèves en classe. C’est pour cela que nous avons décidé de rendre disponible une version avec un noyau stable et qui soit adaptable facilement à son environnement. Mirabelle est une version avec laquelle les enseignants pourront adapter les Activités en fonction des intérêts des enfants. De plus, une partie de notre stratégie consiste à faire naître un schéma de développement durable en invitant de nouvelles personnes à contribuer au projet. Nous avons aussi pu proposer les nouveautés de Mirabelle en optimisant la base de Sugar, la distribution GNU/Linux Fedora. Mirabelle est donc officiellement dérivée de Fedora, un Fedora Spin.» + +Sugar Labs a également rendu disponible le «Sugar Creation Kit», un DVD qui comprend Mirabelle, la documentation associée ainsi qu’un ensemble d’Activités pour Sugar, parmi les plus amusantes et attrayantes, aussi disponibles également en téléchargement sur le Sugar Activity Library ([http://activities.sugarlabs.org](http://activities.sugarlabs.org)). + +Thomas Gilliard, un des contributeurs à Sugar Labs explique que «Le Sugar Creation Kit permet de transformer n’importe quel PC en un poste capable de configurer des clés Sugar On A Stick. Les outils et la documentation nécessaire sont déjà présents sur le DVD si bien que les enseignants ne perdront pas de temps à rechercher une information, même derrière un pare-feu, sans avoir à se connecter au réseau». + +Sugar Labs sera présent pour toute la durée du salon LinuxTag 2010 au stand 115, Hall 7.2a. + +**À propos du Sugar Labs** : Sugar Labs est une organisation non lucrative de volontaires, membre du projet Software Freedom Conservancy. À l’origine intégré au projet One Laptop Per Child, Sugar Labs coordonne les volontaires dans le monde qui sont passionnés par l’idée de fournir des opportunités d’éducation à travers la plate-forme éducative Sugar. Sugar Labs est soutenu par des donations et cherche des fonds pour accélérer son développement. Pour plus d’informations, voir [http://www.sugarlabs.org](http://www.sugarlabs.org) + +Sugar Labs est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leurs auteurs.`,ma=Object.freeze(Object.defineProperty({__proto__:null,default:z},Symbol.toStringTag,{value:"Module"})),U=`--- +title: "La plateforme éducative Sugar et l'interface bureautique GNOME désormais présents sur le nouvel XO 1.5 de la fondation OLPC, ainsi que le nouveau modèle XO-HS High School Edition" +category: "PRESS RELEASE" +date: "2010-01-14" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +ASUNCIÓN, le 14 juin 2010 – Sugar Labs, le projet d'interface bureautique libre GNOME, et la fondation One Laptop per Child (OLPC) ont annoncé conjointement une mise à jour du logiciel de l'ordinateur XO-1.5. Les 1,5 millions d'enfants qui utilisent déjà Sugar sur le XO-1 d'origine pourront également bénéficier de cette mise à jour, grâce au concours du Paraguay Educa qui a adapté cette mise à jour pour le XO-1. + +La plateforme éducative Sugar fait la promotion de l'apprentissage collaboratif à travers des Activités adaptées aux enfants, qui encouragent une pensée critique. L'interface bureautique GNOME, installé sur toutes les distributions majeures GNU/Linux, est destinée aux enfants plus âgés et aux adultes. Changer d'environnement se fait en un clic. Avec l'environnement GNOME présent sur l'ordinateur XO, la porte est ouverte à des millers d'applications éducatives et créatives supplémentaires. + +Le XO-1.5 est basé sur le même design que le premier XO. Equipé d'un processeur VIA, il est deux fois plus rapide que la première génération et dispose de quatre fois plus de mémoire RAM et d'espace de stockage. La fondation OLPC a annoncé la disponibilité d'une version destinée aux collégiens du dernier XO-1.5, nommé XO-HS (High School Edition), avec un clavier entièrement revu, plus confortable pour les élèves plus âgés. Le premier déploiement du XO-HS se déroulera en septembre en Uruguay dans le cadre du très réussi Plan Ceibal. + +Les enfants habitués au XO-1 pourront évoluer vers un XO-1.5 avec ses fonctionnalités supérieures. "Le projet One Laptop per Child promeut le logiciel libre si bien que l'enfant pourra grandir et adapter son XO à ses besoins. La plateforme Sugar sur le XO est l'élément clé de notre mission éducative car il offre à l'élève un environnement d'apprentissage unique et intuitif", explique Rodrigo Arboleda, président de l'association OLPC. + +Stormy Peters, Directeur Exécutif de la fondation GNOME, indique que "Nous sommes vraiment enthousiasmés de travailler avec Sugar et le projet OLPC pour fournir une interface bureautique aux enfants de tous les âges. La mission de GNOME est de fournir une interface bureautique libre et accessible à tous. De l'Uruguay au Ghana, les enfants pourront utiliser leurs nouveaux XO pour apprendre et pour montrer à leurs amis et famille comment utiliser Sugar et GNOME." + +Walter Bender, Directeur Exécutif du Sugar Labs, précise que "La fluidité du passage d'un bureau à l'autre offre aux élèves la capacité de passer d'un environnement d'apprentissage - Sugar - à un environnement de production et de productivité - GNOME. Ils ont ainsi les moyens de transformer les compétences créatives qu'ils ont acquis à l'école primaire en des compétences entrepreneuriales dans le cadre de l'enseignement secondaire." + +De plus, Sugar on a Stick permet aux enfants qui n'ont pas l'ordinateur XO de bénéficier de ce nouveau logiciel. Il est téléchargeable sur le site web du Sugar Labs dans sa nouvelle version, v3 "Mirabelle". Il peut être chargé sur n'importe quelle clé USB et utilisé pour démarrer un PC sous Sugar, sans modifier le contenu du disque dur. L'ordinateur XO et Sugar on a Stick fonctionnent avec Fedora GNU/Linux. + +**À propos du Sugar Labs :** +Sugar Labs est une organisation non lucrative de volontaires, membre du projet Software Freedom Conservancy. À l’origine intégré au projet One Laptop Per Child, Sugar Labs coordonne les volontaires dans le monde qui sont passionnés par l’idée de fournir des opportunités d’éducation à travers la plate-forme éducative Sugar. Sugar Labs est soutenu par des donations et cherche des fonds pour accélérer son développement. Pour plus d’information, voir <http://www.sugarlabs.org> + +**À propos de GNOME :** +GNOME est un projet de logiciel libre qui développe, pour toutes les distributions majeures de GNU/Linux et d'Unix, une interface bureautique complète, accessible et facile d'utilisation. Fort d'un succès mondial, grâce à de larges déploiements dans les grandes entreprises et avec des millions d'utilisateurs dans les PME et chez les particuliers, GNOME intègre un environnement de développement permettant de créer de nouvelles applications. La fondation à but non lucratif GNOME est constituée de centaines de volontaires développeurs et entreprises leader sur leur marché. Plus d'informations sont disponibles sur [http://www.gnome.org](http://www.gnome.org) et [http://foundation.gnome.org](http://foundation.gnome.org). + +**À propos de One Laptop per Child** +([http://www.laptop.org](http://www.laptop.org)) : OLPC est une organisation à but non-lucratif créée par Nicholas Negroponte et d'autres membres du Media Lab du MIT afin de concevoir, produire et distribuer des ordinateurs portables suffisamment abordables pour permettre à chaque enfant du monde d'avoir un accès au savoir et aux formes modernes d'éducation. + +*Sugar Labs est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leurs auteurs.*`,pa=Object.freeze(Object.defineProperty({__proto__:null,default:U},Symbol.toStringTag,{value:"Module"})),F=`--- +title: "Sugar Learning Platform and GNOME Desktop Now Shipping on the One Laptop per Child XO-1.5; Will Run On New XO-HS" +category: "PRESS RELEASE" +date: "2010-06-14" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +ASUNCIÓN, June 14, 2010 – Sugar Labs, the GNOME Free Desktop Project, and One Laptop per Child (OLPC) have announced an update to the software offered on the OLPC XO-1.5. The 1.5 million children already using Sugar on the original XO-1 can also benefit from the update, since Paraguay Educa has backported the software. + +The Sugar Learning Platform promotes collaborative learning through child-friendly Activities that encourage critical thinking. The GNOME free desktop is a hallmark of all major GNU/Linux distributions, suitable for older children and grownups. Switching between the two environments takes only a single click. With GNOME on the XO laptop, the door is opened to thousands of additional educational and productivity applications. + +The XO-1.5 has the same industrial design as the original XO-1. Based on a VIA processor, it provides 2× the speed of the XO-1, 4× DRAM memory, and 4× FLASH memory. OLPC has announced the availability of a high-school edition of the XO-1.5, the XO-HS, with a newly designed keyboard, more comfortable for older students. The first deployment of the XO-HS is set to begin in Uruguay under the highly successful Plan Ceibal in September. + +Children familiar with the XO-1 will naturally grow into the XO-1.5 with its expanded functionality. “One Laptop per Child promotes open-source software so that it can grow and adapt to the needs of the child. The Sugar platform on the XO is key to our educational mission because it gives students a unique and intuitive learning software environment,” said OLPC Association CEO Rodrigo Arboleda. + +Stormy Peters, Executive Director of the GNOME Foundation, said, “We're really excited to be working with Sugar and OLPC to provide desktop software to children of all ages. GNOME's mission is to provide a free desktop accessible to everyone. Children from Uruguay to Ghana will be able to use their XOs to learn and to show their friends and families how to use Sugar and GNOME.” + +Walter Bender, Executive Director of Sugar Labs, said “the fluidity of movement between the two desktops gives learners the ability to transition from a learning environment – Sugar – to a production and productivity environment – GNOME. They have the means of honing the creative skills acquired in an elementary education setting into entrepreneurial skills in a secondary education setting.” + +“Sugar on a Stick” allows children who don't have an XO laptop to benefit from this new software. Available for download from Sugar Labs in the new, v3 Mirabelle flavor, it can be loaded onto an ordinary USB thumbdrive and used to start a PC in Sugar without touching the hard disk. The XO laptops and Sugar on a Stick run Fedora GNU/Linux. + +### About Sugar Labs + +Sugar Labs, a volunteer-driven, nonprofit organization, is a member project of the Software Freedom Conservancy. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. Sugar Labs is supported by donations and is seeking funding to accelerate development. For more information, please visit [http://www.sugarlabs.org](http://www.sugarlabs.org). + +### About GNOME + +GNOME is a free-software project which develops a complete, accessible and easy-to-use desktop standard on all leading GNU/Linux and Unix distributions. Popular with large corporate deployments and millions of small-business and home users worldwide, it includes a development environment to create new applications. The nonprofit GNOME Foundation is composed of hundreds of volunteer developers and industry-leading companies. More information can be found at [http://www.gnome.org](http://www.gnome.org) and [http://foundation.gnome.org](http://foundation.gnome.org). + +### About One Laptop per Child + +[http://www.laptop.org](http://www.laptop.org): OLPC is a non-profit organization created by Nicholas Negroponte and others from the MIT Media Lab to design, manufacture and distribute laptop computers that are inexpensive enough to provide every child in the world access to knowledge and modern forms of education.`,ba=Object.freeze(Object.defineProperty({__proto__:null,default:F},Symbol.toStringTag,{value:"Module"})),N=`--- +title: "Sugar Learning Platform e GNOME Desktop sono disponibili per gli XO-1.5 di One Laptop per Child; Compatibili anche per i nuovi XO-HS High School Edition" +category: "PRESS RELEASE" +date: "2010-06-14" +author: "Sugar Labs" + +--- +<!-- markdownlint-disable --> + +ASUNCIÓN, 14 Giugno, 2010 – Sugar Labs, GNOME Free Desktop Project, e One Laptop per Child (OLPC) annunciano un aggiornamento al software fornito insieme sui OLPC XO-1.5. Anche il milione e mezzo di bambini che già utilizzano Sugar con gli XO-1 originali potranno beneficiare dell'aggiornamento grazie al backporting realizzato da Paraguay Educa. + +Sugar Learning Platform promuove l'apprendimento collaborativo attraverso molteplici Attività orientate all'infanzia, studiate anche per stimolare il pensiero critico. Lo GNOME free desktop è il marchio di fabbrica di tutte le principali distribuzioni GNU/Linux ed è ottimo per i bimbi più grandi e gli adolescenti. Per alternare i due ambienti operativi è sufficiente un singolo click. Con GNOME sui laptop XO si apre la porta a migliaia di altri applicativi per la didattica e per la produttività. + +Il laptop XO-1.5 ha design identico all'XO-1 originale. Essendo basato su processore VIA, ha il doppio della velocità, il quadruplo della memoria RAM ed il quadruplo della memoria FLASH rispetto a un XO-1. OLPC ha annunciato la disponibilità di una versione specifica per le scuole superiori dell'XO-1.5, che sarà chiamata XO-HS, dotata di una tastiera riprogettata per essere più funzionale per gli studenti più grandi. La prima consegna di XO-HS è prevista in settembre in Uruguay nel contesto del progetto di successo Plan Ceibal. + +I bambini che hanno già familiarità con XO-1 potranno crescere con le maggiori funzionalità di XO-1.5. “One Laptop per Child" promuove il software libero così che possa crescere, migliorare ed adattarsi alle esigenze dei bambini. La Piattaforma Sugar su XO è un componente chiave per la nostra missione educativa, in quanto offre agli studenti un ambiente software di lavoro uniforme e intuitivo", dichiara Rodrigo Arboleda, CEO della OLPC Association. + +Stormy Peters, Direttore Esecutivo della GNOME Foundation, dichiara, “Siamo entusiasti di avere l'opportunità per lavorare con Sugar e OLPC per fornire un software di desktop ai giovani di tutte le età. La missione di GNOME è quella di realizzare un desktop libero utilizzabile da tutti. Bambini dall'Uruguay al Ghana potranno utilizzare i loro laptop XO per apprendere e insegnare ai loro amici e genitori come utilizzare insieme Sugar e GNOME.” + +Walter Bender, Direttore Esecutivo di Sugar Labs, dichiara “la fluidità di movimento fra i due ambienti desktop offre agli studenti la possibilità di passare da una piattaforma di apprendimento – Sugar – ad un ambiente di produttività e lavoro – GNOME. Avranno quindi gli strumenti per utilizzare le conoscenze creative acquisite nella loro educazione di base per sviluppare capacità imprenditoriali nella educazione secondaria.” + +“Sugar on a Stick” permette ai bambini che non possiedono un laptop XO di beneficiare di questo nuovo software. Disponibile per il download dal sito internet di Sugar Labs nella nuova versione, v3 Mirabelle, può essere caricato su una normale chiavetta USB di memoria ed utilizzata per avviare un PC con Sugar senza modificare in alcun modo il computer ospite. I laptop XO e Sugar on a Stick utilizzano Fedora GNU/Linux. + +**In merito a Sugar Labs**: Sugar Labs, a volunteer-driven, nonprofit organization, è un progetto membro della Software Freedom Conservancy. Originariamente parte del progetto One Laptop Per Child, Sugar Labs coordina volontari di tutto il mondo motivati ad offrire opportunità ai bambini di apprendere attraverso la Sugar Learning Platform. Sugar Labs è sorretta solo da donazioni e sta cercando aiuto e collaborazione da volontari per accelerare lo sviluppo. Per maggiori informazioni visitate: [http://www.sugarlabs.org](http://www.sugarlabs.org). + +**In merito a GNOME**: GNOME è un progetto di free-software che sviluppa un desktop standard completo, accessibile e di facile utilizzo, per tutte le principali distribuzioni GNU/Linux e Unix. Ampiamente conosciuto e utilizzato nelle grandi imprese e in milioni di piccole aziende e utenti privati nel mondo, include anche un ambiente completo di sviluppo per creare nuovi programmi. La nonprofit GNOME Foundation è costituita da centinaia di sviluppatori volontari e da industrie-leader. Ulteriori informazioni possono essere reperite presso: [http://www.gnome.org](http://www.gnome.org) e [http://foundation.gnome.org](http://foundation.gnome.org). + +**In merito a One Laptop per Child** ([http://www.laptop.org](http://www.laptop.org)): OLPC è una organizzazione non-profit creata da Nicholas Negroponte ed altri del MIT Media Lab per progettare, produrre e distribuire laptop computers che siano così economici da poter fornire ad ogni bambino del mondo accesso alla conoscenza e alle più moderne forme di apprendimento.`,fa=Object.freeze(Object.defineProperty({__proto__:null,default:N},Symbol.toStringTag,{value:"Module"})),q=`--- +title: "La organización sin fines de lucro Sugar Labs patrocina el equipo de ciclistas Team Chipotle para dar a conocer su misión educativa." +excerpt: "Sugar Labs se asocia con el equipo de ciclismo Team Chipotle en un acuerdo innovador de patrocinio para recaudar fondos y dar a conocer su misión educativa, involucrando a niños en Uruguay para documentar la carrera usando sus laptops XO." +category: "PRESS RELEASE" +date: "2011-04-15" +slug: "sugar-labs-patrocina-team-chipotle-mision-educativa" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "ciclismo,educacion,olpc,uruguay,team-chipotle,stem,plan-ceibal,laptops-xo" +--- +<!-- markdownlint-disable --> + +MONTEVIDEO, Uruguay, Abril 15, 2011 — Sugar Labs (R), el fabricante de software para el proyecto One Laptop Per Child (OLPC), va a patrocinar a Team Chipotle, el equipo de ciclistas de Slipstream Sports LLC en un acuerdo sin precedentes que permitirá recabar fondos para la organización sin fines de lucro. La participación del equipo Chipotle permitirá que se conozca la labor de Sugar Labs a lo largo de todo el mundo: la camiseta del equipo Chipotle Development llevará el logo de Sugar Labs. + +"El joven equipo de ciclistas Slipstream Sports ha surgido del objetivo fundacional de la compañía de apoyar los jóvenes talentos y desarrollar la próxima generación de campeones de ciclismo. A los niños les encantan las carreras de bicicletas, y los jóvenes ciclistas son excelentes referentes para los ellos", dijo Jonathan Vaughters, CEO de Slipstream Sports. "Queremos generar un cambio en las vidas de los jóvenes estudiantes y atletas y nuestro innovador acuerdo de patrocinio con Sugar Labas es parte de ello." + +El equipo participará durante los próximos 10 días en la 68a. Vuelta Ciclista del Uruguay 2011. Los escolares uruguayos se incorporarán al evento tomando fotos y escribiendo artículos con sus laptops verdes XO cuando la carrera llegue a sus ciudades. Enviarán su trabajo a [concurso@rapceibal.info](mailto:concurso@rapceibal.info) para que se publique en el blog [http://www.sugarlabs.org/vueltaciclista](http://www.sugarlabs.org/vueltaciclista). Los mejores artículos recibirán premios que serán entregados en el próximo evento de desarrolladores de software eduJAM! que tendrá lugar en Montevideo del 5 al 7 de mayo ([http://ceibaljam.org](http://ceibaljam.org)). + +"Los deportes y STEM (por ciencia, tecnología, ingeniería y matemáticas en inglés) tienen una gran sinergia. Estamos entusiasmados con las oportunidad de despertar el interés de los niños en matemáticas y ciencia a través de su interés por la carrera", dijo Walter Bender, fundador y director ejecutivo de Sugar Labs. + +Uruguay es el primer país en el mundo de equipar al 100% de estudiantes y maestros de escuela primaria, más de medio millón de personas, con una laptop OLPC XO ejecuando Sugar a través del Plan Ceibal ([http://ceibaljam.org](http://ceibaljam.org)). + +Según Gabriel Eirea del CeibalJAM!, "Esta carrera, luego del fútbol, es el evento deportivo más popular en nuestro país y es una parte integral de la cultura local. Cada año durante Semana Santa esta carrera recorre muchas localidades remotas del país y es seguida por cientos de miles de entusiastas espectadores. La comunidad de voluntarios que apoya la implementación del Plan Ceibal, representada por RAP Ceibal y ceibalJAM!, desea promover el uso de las laptops XO en las escuelas, en las comunidades y promueve la apropiación de la tecnología. Con la plataforma Sugar y la laptop XO, nuestros niños no solamente consumen contenido, sino que lo generan. Durante la carrera, niños de todo el país bloguearán sobre el equipo. En el evento eduJAM!, desarrolladores de la plataforma Sugar se encontrarán con niños que se beneficiarán de su trabajo y son el centro de su misión." + +Image:  + +**Sobre Sugar Labs®**: Sugar Labs, una organización sin fines de lucro, conducida por voluntarios, es un proyecto miembro de Software Freedom Conservancy. Originalmente parte del proyecto One Laptop Per Child, Sugar Labs coordina voluntarios en todo el mundo que tienen pasión por dar a los niños oportunidades de educarse a través de la Plataforma de Aprendizaje Sugar. Sugar Labs se mantiene en base a donaciones y está buscando financiación y voluntarios para acelerar su desarrollo. Por más información, visite por favor [http://www.sugarlabs.org](http://www.sugarlabs.org). + +**Sobre Slipstream Sports LLC**: fundada en 2005, Slipstream Sports, LLC es una empresa de avanzada en el rubro de gestión deportiva dedicada a promover el crecimiento ético del ciclismo y desarrollar la próxima generación de campeones de ciclismo. Por más información, por favor visite [http://www.slipstreamsports.com](http://www.slipstreamsports.com). + +*Sugar Labs es una marca registrada de Software Freedom Conservancy. Otros nombres son marcas registradas de sus respectivos dueños.* + +**NOTA:** El equipo Chipotle Development desafortunadamente no va a participar de la 68a. Vuelta Ciclista del Uruguay este año.`,ya=Object.freeze(Object.defineProperty({__proto__:null,default:q},Symbol.toStringTag,{value:"Module"})),H=`--- +title: "Sugar Labs Nonprofit Sponsoring Team Chipotle to Raise Awareness of Educational Mission" +excerpt: "Sugar Labs partners with Team Chipotle cycling team in an innovative sponsorship arrangement to raise awareness and funds for its educational mission while engaging children in Uruguay to document the race using their XO laptops." +category: "PRESS RELEASE" +date: "2011-04-15" +slug: "sugar-labs-sponsoring-team-chipotle-awareness-educational-mission" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "cycling,education,olpc,uruguay,team-chipotle,stem,plan-ceibal,xo-laptops" +--- +<!-- markdownlint-disable --> + + +MONTEVIDEO, Uruguay, April 15, 2011 — Sugar Labs®, software provider to the +One Laptop Per Child (OLPC) project, will sponsor Team Chipotle, the +Continental cycling team owned and operated by Slipstream Sports LLC, in a +groundbreaking arrangement which will raise funds to support the nonprofit's +educational mission. Team Chipotle will raise awareness for Sugar Labs at +races around the world with team jerseys carrying the Sugar Labs logo. + +"Team Chipotle has grown out of our founding goal of developing the next +generation of cycling champions. Every kid loves a bike race and young +cyclists provide great role models for children," said Jonathan Vaughters, CEO +of Slipstream Sports. "We want to make a difference in the lives of young +athletes and children and our innovative sponsorship arrangement with Sugar +Labs is part of that." + +The team will race over the next ten days in the 68th Vuelta Ciclista del +Uruguay 2011 and pupils there will participate, taking photos and writing +articles with their green XO laptops as the race passes through their towns, +and e-mailing them to +[concurso@rapceibal.info](mailto:concurso@rapceibal.info) for posting to a +blog ([http://www.sugarlabs.org/vueltaciclista](http://www.sugarlabs.org/vueltaciclista)). The best articles will win +prizes to be awarded at the eduJAM! Developers Summit which will take place in +Montevideo May 5–7 ([http://ceibaljam.org](http://ceibaljam.org)). + +"Sports and STEM (Science, Technology, Engineering, and Mathematics) have a +great synergy. We are excited by the prospect of engaging children in learning +math and science through their excitement about the race", said Walter Bender, +founder and Executive Director of Sugar Labs. + +Uruguay is the first country in the world to provide 100% of its elementary +school pupils and teachers - over half a million - with an OLPC XO laptop +running Sugar through its Plan Ceibal ([http://ceibaljam.org](http://ceibaljam.org)). + +According to Gabriel Eirea of CeibalJAM!, "This race is, after football, the +most popular sports event in the country and is an integral part of our local +culture. Every year during Holy Week this race passes through the remotest +towns of the country and is followed by hundreds of thousands of enthusiastic +viewers. The volunteer community supporting Plan Ceibal, represented by RAP +Ceibal and ceibalJAM!, wants to promote the use of XO laptops beyond the +schools, inside the communities, advocating technology appropriation. With +Sugar and the XO, our children don't just consume content, they create it. +During the race, children throughout the country will be blogging about the +team. At eduJAM!, Sugar Labs developers will meet children who are at the +center of their mission and benefit from their work." + +Image:  + +About Sugar Labs: Sugar Labs, a volunteer-driven, nonprofit organization, is a +member project of the Software Freedom Conservancy. Originally part of the One +Laptop Per Child project, Sugar Labs coordinates volunteers around the world +who are passionate about providing educational opportunities to children +through the Sugar Learning Platform. Sugar Labs is supported by donations and +is seeking funding to accelerate development. For more information, please +visit [http://www.sugarlabs.org](http://www.sugarlabs.org). + +About Slipstream Sports LLC: Founded in 2005, Slipstream Sports, LLC is a +highly progressive sports management company dedicated solely to promoting the +ethical growth of cycling and developing the next generation of cycling +champions. For more information, please visit +[http://www.slipstreamsports.com](http://www.slipstreamsports.com). + +Sugar Labs is a registered trademark of the Software Freedom Conservancy. +Other names are trademarks of their respective owners. + +NOTE: The Chipotle Development Team will unfortunately not race in the Vuelta +Ciclista del Uruguay this year.`,wa=Object.freeze(Object.defineProperty({__proto__:null,default:H},Symbol.toStringTag,{value:"Module"})),K=`--- +title: "La organización educacional sin fines de lucro Sugar Labs(R) celebra el Día del Aprendizaje Digital con dos ganadores del premio Google Code-In" +excerpt: "Sugar Labs anuncia que dos estudiantes, Agustín Zubiaga Sánchez y Aneesh Dogra, han sido ganadores del premio principal de Google Code-In por sus significativas contribuciones a la plataforma de aprendizaje Sugar." +category: "PRESS RELEASE" +date: "2013-02-05" +slug: "sugar-labs-celebra-dia-aprendizaje-digital-ganadores-code-in" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "google-code-in,dia-aprendizaje-digital,educacion,programacion,estudiantes,codigo-abierto,python" +--- +<!-- markdownlint-disable --> + +[PDF](/assets/post-assets/press/SugarLabsPR-es.20130205.pdf) + +CAMBRIDGE, Mass, 5 de Febrero del 2013 – Sugar Labs(R), una organización educativa sin fines de lucro, proveedora de software libre para el aprendizaje para niños, se enorgullece de celebrar el 6 de febrero como el Día del Aprendizaje Digital. +**Enlace:** [Digital Learning Day](http://www.digitallearningday.org) + +...con dos ganadores del principal premio del Google Code-In, Agustin Zubiaga Sanchez y Aneesh Dogra, quienes tuvieron una brillante participación en el programa anual de Google, para estudiantes de entre 13 y 17 años de edad. Más de 50 participantes de 14 países participaron para mejorar Sugar, guiados por 22 voluntarios de Sugar Labs(R). Los ganadores visitarán las instalaciones de Google en Mountain View, CA, esta primavera. +**Más info:** [Google Code-In 2012](http://developers.google.com/open-source/gci/2012) + +Agustin (Aguz para sus amigos) tiene 15 años, vive en un pueblo de Uruguay y es un reciente graduado de la escuela técnica Rafael Perazza dependiente de la Universidad del Trabajo del Uruguay. Luego de usar Sugar por varios años, su maestro del club de computadoras lo animó a aprender el lenguaje de programación Python usado en Sugar. Uno de sus proyectos involucra código para agregar una imagen de fondo a la Vista de Hogar de Sugar. Él dice: "Comencé a programar gracias a Sugar y ahora estoy muy contento de ser uno de sus desarrolladores." + +Aneesh, quien ya ganó el Google Code-In del año anterior, tiene 17 años y vive en Punjab, India. Él trabajó actualizando un gran número de Actividades Sugar para niños y contribuyó con el libro electrónico "Cómo hacer una Actividad Sugar". +**Libro (EN):** [Make Your Own Sugar Activities](http://www.flossmanuals.net/make-your-own-su%20gar-activities) +**Libro (ES):** [Cómo Hacer una Actividad Sugar](http://en.flossmanuals.net/como-hacer-una-actividad-sugar) + +Habiendo ganado premios previamente, incluyendo el Concurso Raspberry Pi Summer Coding del último año, está interesado en aplicaciones audiovisuales y seguridad informática. +**Premio anterior:** [Raspberry Pi Summer Coding](http://www.raspberrypi.org/archives/2544) +**Blog personal de Aneesh:** [anee.me](http://anee.me) + +"Fue muy difícil elegir los ganadores," comentó Chris Leonard, enlace por Sugar Labs(R) para el Google Code-In. "Un tercio de nuestros participantes completó múltiples tareas. Aneesh fue muy prolífico, completando más de 40 tareas y Aguz hizo mejoras fundamentales en la plataforma Sugar. Todos nuestros participantes aprendieron cosas en estos tres meses. Notablemente, un participante, Daniel Francis, de Uruguay, tuvo que retirarse del concurso porque fue elegido para la Comisión de Supervisión de Sugar Labs, durante el concurso, a la madura edad de 14 años." + +"Seis años después de que Sugar apareció en las aulas, su primera generación de estudiantes está convirtiéndose en los ingenieros, escritores y maestros del mañana," dice Walter Bender, fundador de Sugar Labs. "Aguz y Daniel crecieron con Sugar en Uruguay donde es usado en cada escuela, y Google Code-In tuvo su primer participante desde Perú, donde Sugar es parte de un programa nacional también. Sugar fue diseñado para tener un piso bajo, sin techo, y su Diario, Actividades, colaboración integrada y Visualización de código lo hacen ideal para el aula." + +Aunque Sugar es usado principalmente en países en desarrollo mundialmente a través del programa One Laptop Per Child, apela a que todos los niños descubran la era digital del siglo 21. +**Conoce más:** [One Laptop Per Child](http://laptop.org) + +El Dr. Gerald Ardito, un miembro del comité para Sugar Labs(R), maestro de escuela media y profesor de Ciencias de la Computación en Westchester, NY, ha usado las Laptops XO y Sugar en una variedad de contextos educacionales. "Lo que ha sido tan poderoso es ver a los estudiantes ser capaces de tomar posesión real de su aprendizaje cuando usan Sugar", él dice. "Los he visto una y otra vez, pasar de ser consumidores a ser productores de medios digitales." + +Sugar Labs(R) desea agradecer a Google y a Bradley Kuhn de la organización Software Freedom Conservancy, madre de Sugar Labs y otros proyectos de software libre/código abierto. + +**Imagen del anuncio:** + + +--- + +**Sobre Sugar Labs(R):** +Sugar Labs, una organización sin fines de lucro, conducida por voluntarios, es un proyecto miembro de Software Freedom Conservancy. Originalmente parte del proyecto One Laptop Per Child, Sugar Labs coordina voluntarios en todo el mundo que tienen pasión por dar a los niños oportunidades de educarse a través de la Plataforma de Aprendizaje Sugar. +Sugar Labs se mantiene en base a donaciones y está buscando financiación y voluntarios para acelerar su desarrollo. +**Sitio oficial:** [www.sugarlabs.org](http://www.sugarlabs.org) + +*Sugar Labs es una marca registrada de la Software Freedom Conservancy. Otros nombres y marcas corresponden a sus respectivos dueños.*`,va=Object.freeze(Object.defineProperty({__proto__:null,default:K},Symbol.toStringTag,{value:"Module"})),V=`--- +title: "Le Sugar Labs(R), organisme non lucratif à but éducatif, célèbre le 'Digital Learning Day' avec deux lauréats au grand prix du 'Google Code-In'" +excerpt: "Sugar Labs annonce deux étudiants, Agustin Zubiaga Sanchez et Aneesh Dogra, comme lauréats du grand prix Google Code-In qui ont apporté des contributions significatives à la plateforme d'apprentissage Sugar." +category: "PRESS RELEASE" +date: "2013-02-05" +slug: "sugar-labs-celebre-digital-learning-day-lauréats-google-code-in" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "google-code-in,digital-learning-day,education,programming,students,open-source,python" +--- +<!-- markdownlint-disable --> + +[PDF](/assets/post-assets/press/SugarLabsPR-fr.20130205.pdf) + +Cambridge (Massachusetts), 5 février 2013 — Le Sugar Labs(R), l'éditeur éducatif à but non lucratif de logiciels libres et ouverts à destination des enfants, a le plaisir de célébrer la Journée d'Apprentissage Numérique (Digital Learning Day) du 6 février. +**Lien :** [Digital Learning Day](http://www.digitallearningday.org) + +Avec les lauréats au grand prix Google Code-In : +**Lien :** [Google Code-In 2012](http://developers.google.com/open-source/gci/2012) +Agustin Zubiaga Sanchez et Aneesh Dogra, deux participants brillants au programme annuel de Google destiné aux élèves de l'enseignement secondaire, âgés de 13 à 17 ans. Plus de 50 participants représentant 14 pays, accompagnés par 22 tuteurs volontaires pour le Sugar Labs, ont contribué à améliorer Sugar. Les lauréats visiteront le siège de Google à Mountain View, en Californie, au cours du printemps prochain. Google Code-In et son programme associé destiné aux étudiants de niveau universitaire, le Google Summer of Code, invitent les organismes open source à encadrer des étudiants travaillant sur des tâches de programmation et de documentation réelles. + +Agustin (Aguz pour ses amis) est âgé de 15 ans. Il vit dans un village en Uruguay et vient d'obtenir son diplôme universitaire du centre Rafael Perazza de l'Universidad del Trabajo del Uruguay (UTU). Utilisateur de Sugar depuis plusieurs années, son enseignant du club informatique l'a encouragé à apprendre le langage de programmation Python utilisé par Sugar. L'un de ses projets consistait à ajouter des images d'arrière-plan à la page d'accueil de Sugar. Il déclare : "C'est grâce à Sugar que j'ai commencé à programmer. Aujourd'hui, je suis très heureux d'être l'un de ses développeurs." + +Aneesh, lui aussi lauréat du Google Code-In de l'an passé, a 17 ans et vit au Punjab, en Inde. Il a participé à la mise à jour de plusieurs "apps" Sugar destinées aux enfants et a contribué à la rédaction du livre électronique : +**Lien :** [Réalisez votre propre activité Sugar](http://www.flossmanuals.net/make-your-own-sugar-activities) + +Après avoir gagné différents prix, parmi lesquels : +**Lien :** [Raspberry Pi Summer Coding Contest](http://www.raspberrypi.org/archives/2544), +il s'intéresse aux applications audiovisuelles et à la sécurité informatique. Aneesh publie son blog : +**Lien :** [anee.me](http://anee.me) + +"Choisir les lauréats n'était pas une tâche facile", explique Chris Leonard, le correspondant du Sugar Labs auprès du Google Code-In. "Un bon tiers de nos participants ont réalisé différentes tâches. Aneesh a eu une activité prolifique, avec plus de 40 tâches à son actif, et Aguz a apporté des améliorations capitales à la plateforme Sugar. Tous nos participants ont beaucoup appris au cours de ces trois derniers mois. Fait remarquable, l'un des participants, Daniel Francis, d'Uruguay, a dû se retirer du concours après avoir été désigné au Sugar Labs Oversight Board pendant le déroulement du concours. Détail important : il vient tout juste d'avoir 14 ans." + +"Six ans après la première utilisation de Sugar dans des salles de classe, cette première génération d'étudiants préfigure les ingénieurs, les auteurs et les enseignants de demain," a déclaré Walter Bender, le fondateur du Sugar Labs. "Aguz et Daniel ont grandi avec Sugar, en Uruguay, alors que Sugar est utilisé dans toutes les écoles et que le Google Code-In compte son tout premier participant originaire du Pérou, pays dans lequel Sugar intègre également le cursus scolaire national. Sugar a été conçu pour sa facilité d'accès et son potentiel illimité. Le 'Journal', les 'Activités', les fonctions de collaboration et de visualisation du code source, qui intègrent la plateforme Sugar, en font un instrument idéal pour la classe." + +Sugar est utilisé dans de nombreux pays émergents dans le monde entier, participant au programme : +**Lien :** [One Laptop Per Child](http://laptop.org) +Il s'adresse, plus largement, à tous les enfants qui découvrent le 21ème siècle numérique. + +Gerald Ardito, membre du bureau du Sugar Labs, enseignant de collège et professeur d'informatique à Westchester (New-York), utilise Sugar dans différents contextes éducatifs. De son propre aveu, "Observer les étudiants prendre littéralement en mains leur propre apprentissage grâce à Sugar est une expérience unique". "J'ai observé à de nombreuses reprises, au cours de ces dernières années, comment ils passaient du stade de consommateurs de médias numériques à celui de producteurs." + +Le Sugar Labs tient à exprimer sa gratitude à Google et tout particulièrement à Bradley Kuhn, le directeur exécutif du Software Freedom Conservancy, organisme fédérant le Sugar Labs et 27 autres projets de logiciels libres et ouverts. + +**Image :** + + +--- + +**À propos de Sugar Labs(R)** +Sugar Labs(R) est une organisation non lucrative de volontaires, membre du projet Software Freedom Conservancy. À l’origine intégré au projet One Laptop Per Child, Sugar Labs coordonne les volontaires dans le monde qui sont passionnés par l’idée de fournir des opportunités d’éducation à travers la plate-forme éducative Sugar. Sugar Labs(R) est soutenu par des donations et cherche des fonds pour accélérer son développement. Pour plus d’information, voir [www.sugarlabs.org/press](http://www.sugarlabs.org/press) ou contacter **pr@sugarlabs.org**. + +*Sugar Labs(R) est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leur auteurs.*`,ka=Object.freeze(Object.defineProperty({__proto__:null,default:V},Symbol.toStringTag,{value:"Module"})),J=`--- +title: "Sugar Labs(R) Educational Nonprofit Celebrates Digital Learning Day With Two Google Code-In Grand Prize Winners" +excerpt: "Sugar Labs announces two students, Agustin Zubiaga Sanchez and Aneesh Dogra, as Google Code-In grand prize winners who made significant contributions to the Sugar Learning Platform." +category: "PRESS RELEASE" +date: "2013-02-05" +slug: "sugar-labs-celebrates-digital-learning-day-code-in-winners" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "google-code-in,digital-learning-day,education,programming,students,open-source,python" +--- +<!-- markdownlint-disable --> + +[PDF](/assets/post-assets/press/SugarLabsPR-en.20130205.pdf) + +CAMBRIDGE, Mass, February 5, 2013 — Sugar Labs(R), educational nonprofit provider of free and open-source learning software for children, is proud to celebrate **[Digital Learning Day](http://www.digitallearningday.org)** on February 6th with **[Google Code-In](http://developers.google.com/open-source/gci/2012)** grand prize winners Agustin Zubiaga Sanchez and Aneesh Dogra, who participated brilliantly in Google's annual program for middle and high school students aged 13 to 17. Over 50 participants from 14 countries, mentored by 22 Sugar Labs volunteers, helped to improve Sugar. The winners will visit Google headquarters in Mountain View, CA this spring. Google Code-In and its sister program for university students, Google Summer of Code, invite open source organizations to mentor students who work on real programming and documentation tasks. + +Agustin (Aguz to his friends) is 15, lives in a village in Uruguay and is a recent graduate of Rafael Perazza Technical High School at Universidad del Trabajo del Uruguay. After using Sugar for several years, his computer club teacher encouraged him to learn the Python programming language used in Sugar. One of his projects involved code to add background images to Sugar's Home View. He says, "I started programming thanks to Sugar and now I am very happy to be one of its developers." + +Aneesh, also a winner at last year's Google Code-In, is 17 and lives in Punjab, India. He worked on updating a large number of Sugar "Apps" for children and contributed to the "**[Make Your Own Sugar Activities!](http://www.flossmanuals.net/make-your-own-sugar-activities)**" ebook. Having won previous honors, including runner-up in last year's **[Raspberry Pi Summer Coding Contest](http://www.raspberrypi.org/archives/2544)**, he is interested in audiovisual applications and computer security. More information about Aneesh is available on his **[blog](http://anee.me)**. + +"We had a hard time choosing our winners," commented Chris Leonard, Sugar Labs liaison for Google Code-In. "Fully a third of our participants completed multiple tasks. Aneesh was prolific, completing over 40 tasks, and Aguz made fundamental improvements to the Sugar platform itself. All of our participants learned over these past three months. Notably, one participant, Daniel Francis of Uruguay, had to take his name out the running because he was elected to the Sugar Labs Oversight Board during the contest at the ripe old age of 14." + +"Six years after Sugar first appeared in classrooms, its first generation of learners are becoming tomorrow's engineers, writers, and teachers," said Walter Bender, founder of Sugar Labs. "Aguz and Daniel grew up with Sugar in Uruguay where Sugar is used in every school and Google Code-In had its first ever participant from Peru, where Sugar is part of the nationwide curriculum as well. Sugar was designed to be low floor, no ceiling and its Journal, Activities, built-in collaboration and View Source features make Sugar ideal for the classroom." + +Sugar is used in developing countries worldwide through the **[One Laptop Per Child program](http://laptop.org)**, but it also appeals to all children discovering the digital 21st century. Dr. Gerald Ardito, a Sugar Labs board member, as well as a middle school teacher and professor of Computer Science in Westchester, NY, has used Sugar in a variety of educational settings. "It is so powerful to watch students be able to take real ownership of their learning when they are using Sugar", he said. "I have seen them time and time again move from being consumers of computer centered media to producers." + +Sugar Labs wishes to thank Google and in particular Bradley Kuhn, executive director of the Software Freedom Conservancy, parent organization of Sugar Labs and 27 other free/libre software projects. + +**Image:** + + +--- + +**About Sugar Labs(R):** +Sugar Labs(R), a volunteer-driven, educational nonprofit organization, is a member project of the Software Freedom Conservancy. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. Sugar Labs(R) is supported by donations and is seeking funding to accelerate development. For more information, please visit [sugarlabs.org/press](http://www.sugarlabs.org/press) or contact pr@sugarlabs.org. + +Sugar Labs(R) is a registered trademark of the Software Freedom Conservancy. Other names are trademarks of their respective owners.`,Sa=Object.freeze(Object.defineProperty({__proto__:null,default:J},Symbol.toStringTag,{value:"Module"})),X=`--- +title: "Children Programmers Abound at First International TurtleArt Day" +excerpt: "Sugar Labs celebrates the first TurtleArt Day in Caacupé, Paraguay, with 275 students and 77 teachers exploring creative programming through the TurtleArt environment." +category: "PRESS RELEASE" +date: "2013-10-12" +slug: "children-programmers-first-international-turtleart-day" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "turtleart,programming,education,art,logo,children,paraguay,international-day" +--- +<!-- markdownlint-disable --> + +[PDF](/assets/post-assets/press/SugarLabsPR-en.20131015.pdf) + +CAACUPÉ, Paraguay, October 12, 2013 — Sugar Labs®, educational nonprofit provider of free and open-source learning software for children, is proud to celebrate **TurtleArt Day** +- **Event Info:** [TurtleArt Day](http://turtleartday.org) +in Caacupé, Paraguay, with 275 students, their parents, and 77 teachers. They were joined by educators and Sugar developers from 8 countries throughout the Americas and as far away as Australia. Additional TurtleArt Days are planned for Peru, Costa Rica, Argentina, and Malaysia; the next will be October 15th in Montevideo, Uruguay. + +Caacupé has been the focus of a one-to-one learning program run by +- **Organization:** [Paraguay Educa](http://www.paraguayeduca.org) +since 2008. The foundation is active in 35 schools, working with 365 teachers and 9,700 children. The children of Caacupé live in areas with high poverty levels: 60% of them are street workers and most have at least one parent living abroad. Much of the coordination was done by "Evolution" children, youth leaders in Caacupé who attend school in the morning, teach in the afternoon, and on weekends supply technical support to school programs. + +TurtleArt is a programming environment with a graphical "turtle" that draws colorful art based on snap-together elements. Its "low floor" provides an easy entry point for beginners. It also has "high ceiling" programming features that challenge the more adventurous student. TurtleArt's roots are in Logo, the first programming language for children, created by Seymour Papert, Wally Feurzeig, Daniel Bobrow, and Cynthia Solomon in 1967. Logo's friendly turtle, which relies on instructions from children to move, has inspired adaptations from Logo for the Apple® II to Lego® Mindstorms®, TurtleArt, and Scratch. + +An international group of TurtleArtists travelled to Caacupé with the generous support of BBVA Bank to launch the first TurtleArt Day. Also participating was +- **EduJam Group:** [EduJam!](http://ceibaljam.org) +attendants, a group of developers who work on open-source educational software. Caacupé's participants enjoyed workshops to create TurtleArt projects; interactive programming that involved robots and sensors; and discussions where educators and children shared their experiences. + +> "Logo was designed to be 'mathland'; TurtleArt is 'artland'," says Artemis Papert, co-creator of TurtleArt. +> "It allows us to bring together art and programming. While you do art, you also do programming, math, and geometry — the tools you need while focusing on doing art. We have observed that artists become more comfortable with programming and programmers become more comfortable with art when they use TurtleArt." + +Cecilia Rodríguez Alcalá, Executive Director of Paraguay Educa, said, +> "The aspects of TurtleArt Day highlighted by the Evolution team included cultural exchange between the children and the international community, and children teaching each other, pursuing their personal interests, including projects involving physical-world interaction." + +Claudia Urrea, an educator and member of the Sugar Labs Oversight Board, said, +> "With TurtleArt, the children enjoyed programming the robots and using sensors, creating artistic images, engaging in the concrete use of mathematical concepts such as variables and random numbers, realizing how quickly the pace of their learning evolved, and discovering the multiple applicabilities of computation." + +Andres Aguirre of the Butia project, a robot programmed with TurtleArt, said, +> "Even though the children had limited time to use the robots, they were able to experiment with some high-level programming concepts such as conditionals and control structures." + +**Images:** +-  +-  + +--- + +### About Sugar Labs® +Sugar Labs, a volunteer-driven, nonprofit organization, is a member project of the Software Freedom Conservancy. Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities through the Sugar Learning Platform. Sugar is installed on more than three million computers. Sugar Labs is supported by donations and is seeking funding to accelerate development. + +For more information, please visit [sugarlabs.org/press](http://www.sugarlabs.org/press) or contact **pr@sugarlabs.org**. + +*Sugar Labs® is a registered trademark of the Software Freedom Conservancy. Other names are trademarks of their respective owners.*`,Ia=Object.freeze(Object.defineProperty({__proto__:null,default:X},Symbol.toStringTag,{value:"Module"})),$=`--- +title: "Programadores niños abundan en el primer Día Internacional de TurtleArt" +excerpt: "Sugar Labs celebra el primer Día de Tortugarte en Caacupé, Paraguay, con 275 estudiantes y 77 profesores explorando programación creativa a través del entorno TurtleArt." +category: "PRESS RELEASE" +date: "2013-10-12" +slug: "primer-dia-internacional-turtleart" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "tortugarte,programming,education,art,logo,children,paraguay,international-day" +--- +<!-- markdownlint-disable --> + + +[PDF](/assets/post-assets/press/SugarLabsPR-es.20131015.pdf) + +Caacupé, Paraguay, 12 de octubre de 2013 — Sugar Labs®, el proveedor educativo de aprendizaje sin fines de lucro de software libre y de código abierto para los niños, se enorgullece de celebrar el Día de Tortugarte en Caacupé, Paraguay, con 275 estudiantes, sus padres y 77 profesores. A ellos se sumaron educadores y desarrolladores de Sugar procedentes de 8 países de América y de otros lugares lejanos como Australia. Están previstos Días de Tortugarte adicionales para Perú, Costa Rica, Argentina y Malasia; el próximo será el 15 de octubre en Montevideo, Uruguay. + +Caacupé ha sido objeto del programa Una Computadora Por Niño —modelo de aprendizaje uno a uno— a cargo de Paraguay Educa desde 2008. La fundación opera en 35 escuelas, en colaboración con 365 profesores y 9.700 niños. Los niños y niñas de Caacupé viven en áreas con altos niveles de pobreza: el 60 % de ellos trabaja en la calle y la mayoría tiene al menos un padre que vive en el extranjero. Gran parte de la coordinación fue hecha por los chicos "Evolution", líderes juveniles de Caacupé que asisten a la escuela por la mañana, enseñan por la tarde y los fines de semana ofrecen asistencia técnica a los programas escolares. + +Tortugarte es un entorno de programación con una "tortuga" gráfica que dibuja arte colorido a base de elementos de cierre conjunto. Su "piso bajo" proporciona un punto de entrada fácil para los principiantes. También cuenta con funciones de programación de "alto techo" que retan al estudiante más aventurero. Las raíces de Tortugarte están en Logo, el primer lenguaje de programación para niños, creado por Seymour Papert, Wally Feurzeig, Daniel Bobrow y Cynthia Salomón en 1967. La tortuga amistosa del logotipo, que se basa en las instrucciones de los niños para moverse, ha inspirado adaptaciones de Logo para Apple® II, Lego® Mindstorms®, Tortugarte y Scratch. + +Un grupo internacional de Tortu-artistas viajó a Caacupé con el generoso apoyo del banco BBVA para lanzar el primer Día de Tortugarte. También participaron del eduJAM!, un evento de desarrolladores que trabajan en software educativo de código abierto. Los participantes disfrutaron de talleres para crear proyectos de Tortugarte en Caacupé, programación interactiva con robots y sensores, y discusiones donde educadores y niños compartieron sus experiencias. + +"El logotipo fue diseñado para ser 'La Tierra de las Matemáticas'; Tortugarte es 'La Tierra del Arte'", dice Artemis Papert, co-creadora de Tortugarte. "Nos permite reunir el arte y la programación. Mientras uno hace arte, también hace programación, matemáticas y geometría —las herramientas que se necesitan mientras se centra en hacer arte. Hemos observado que los artistas se sienten más cómodos con la programación y los programadores se sienten más cómodos con el arte cuando utilizan Tortugarte." + +Brian Silverman, co-creador de Tortugarte, observó: "Me quedé sorprendido por la pasión de los niños que vinieron al Día de Tortugarte: fueron salvajemente entusiastas y mantuvieron su atención durante seis horas. Llegaron al evento con solo una experiencia rudimentaria en Tortugarte y se fueron con más conocimiento acerca de su potencial artístico". + +Cecilia Rodríguez Alcalá, directora ejecutiva de Paraguay Educa, dijo: "Entre los aspectos destacados del Día de Tortugarte sobresale el desempeño en equipo de los jóvenes Evolution, ya que incluye el intercambio cultural entre los niños y la comunidad internacional, así como la enseñanza entre pares y proyectos de interacción física en el mundo". + +Claudia Urrea, educadora y miembro de la Junta de Supervisión de Sugar Labs, dijo: "Con Tortugarte, los niños disfrutaron de la programación de robots y el uso de sensores, la creación de imágenes artísticas, y la participación concreta en el uso de conceptos matemáticos como variables y números aleatorios. Fue notable la rapidez con que evolucionó su aprendizaje y el descubrimiento de las múltiples aplicaciones de la informática". + +Andrés Aguirre, del proyecto Butiá —un robot programado con Tortugarte—, dijo: "A pesar de que había tiempo limitado para usar los robots, los niños fueron capaces de experimentar con algunos conceptos de programación de alto nivel, tales como condicionales y estructuras de control". + +**Más información:** +- [Día de Tortugarte](http://turtleartday.org) +- [Paraguay Educa](http://www.paraguayeduca.org) +- [Ceibal Jam](http://ceibaljam.org) + +**Imágenes del evento:** +-  +-  + +**Sobre Sugar Labs®:** +Es una organización sin fines de lucro dirigida por voluntarios, miembro de la Software Freedom Conservancy. Sugar Labs coordina alrededor del mundo a voluntarios apasionados por proveer oportunidades educativas a través de la plataforma de aprendizaje Sugar. Sugar se encuentra instalada en más de tres millones de computadoras. Sugar Labs se mantiene a base de donaciones y busca fondos para acelerar su desarrollo. Para más información visita [sugarlabs.org/press](http://www.sugarlabs.org/press) o escribe a [pr@sugarlabs.org](mailto:pr@sugarlabs.org). + +Sugar Labs es una marca registrada de la Software Freedom Conservancy. Otros nombres y marcas mencionados corresponden a sus respectivos dueños.`,Aa=Object.freeze(Object.defineProperty({__proto__:null,default:$},Symbol.toStringTag,{value:"Module"})),Y=`--- +title: "Une foule d'enfants programmeurs participe à la 1ère Journée Internationale TurtleArt" +excerpt: "Sugar Labs célèbre la première Journée TurtleArt à Caacupé, Paraguay, avec 275 élèves, 77 professeurs et des participants internationaux explorant la programmation créative à travers l'environnement TurtleArt." +category: "PRESS RELEASE" +date: "2013-10-12" +slug: "premiere-journee-internationale-turtleart" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "turtleart,programming,education,art,logo,children,paraguay,international-day" +--- +<!-- markdownlint-disable --> + +[PDF](/assets/post-assets/press/SugarLabsPR-fr.20131015.pdf) + +CAACUPÉ, Paraguay, le 12 Octobre 2013. Sugar Labs(R), fournisseur à but non lucratif de programmes éducatifs gratuits et sous licence libre, célèbre avec une grande fierté la journée TurtleArt à Caacupé, au Paraguay. 275 élèves y participent avec leurs parents ainsi que 77 professeurs. Des éducateurs et des développeurs Sugar se sont joints à eux, venant de 8 pays des Amériques mais aussi d'aussi loin que l'Australie. De nouvelles journées TurtleArt sont prévues au Pérou, au Costa Rica, en Argentine et en Malaysie; la prochaine aura lieu le 15 octobre à Montevideo, Uruguay. + +Caacupé héberge depuis 2008 un programme d'"apprentissage un-à-un" mené par [Paraguay Educa](http://www.paraguayeduca.org). Cette fondation est présente dans 35 écoles, collabore avec 365 professeurs et 9.700 enfants. Les enfants de Caacupé vivent dans des zones de grande pauvreté: 60% d'entre eux sont des travailleurs des rues et la plupart ont au moins un de leur parents qui vit à l'étranger. Une bonne part de la coordination a été assurée par des jeunes de Caacupé, engagés dans le programme "Evolution". Ils suivent les cours à l'école le matin, enseignent l'après-midi et fournissent une assistance technique aux programmes de l'école le week-end. + +TurtleArt est un environnement de programmation au sein duquel une "tortue" graphique trace des dessins colorés à partir d'éléments de base pouvant s'emboîter. Son caractère accessible fait d'elle l'activité idéale pour une initiation à la programmation. TurtleArt trouve ses origines dans le langage Logo, le premier langage de programmation pour enfants créé par Seymour Papert, Wally Feurzeig, Daniel Bobrow et Cynthia Solomon en 1967. La sympathique tortue de Logo, qui se déplace suivant les instructions données par les enfants, a inspiré des adaptations allant de l'Apple(R) II à Lego(R) Mindstorms(R), TurtleArt et Scratch. + +Un groupe international d'artistes TurtleArt a fait le voyage jusqu'à Caacupé pour ce lancement de la première journée TurtleArt, grâce au généreux soutien financier de la banque BBVA. Parmi les participants à cette première journée on trouve aussi des développeurs de [EduJam!](http://ceibaljam.org), groupe qui développe des logiciels éducatifs en licence libre. + +Les participants de Caacupé ont pris part avec enthousiasme à des ateliers autour de projets TurtleArt; de la programmation interactive utilisant des robots et des capteurs et enfin de discussions où éducateurs et enfants ont pu partager leurs expériences. + +"Le langage Logo a été conçu comme le 'royaume des maths'; TurtleArt est plutôt le 'royaume du dessin d'art'" nous confie Artemis Papert, co-créateur de TurtleArt. "Il nous offre la possibilité de réunir dessin et programmation. Quand vous pratiquez le dessin, vous faites aussi de la programmation, des maths et de la géométrie – vous vous en servez comme outil pour dessiner. Nous avons remarqué que les artistes se sentent ensuite plus à l'aise en programmation et les programmeurs plus à l'aise dans les activités artistiques quand ils utilisent TurtleArt." + +Brian Silverman, co-créateur de TurtleArt fait la remarque suivante: "J'ai été fasciné par la passion éveillée chez les enfants venant participer à la journée TurtleArt. Ils étaient enthousiastes en diable et sont restés concentrés pendant six heures. Ils sont venus ici avec une expérience de TurtleArt vraiment rudimentaire et sont repartis avec une meilleure compréhension de son potentiel artistique." + +Cecilia Rodríguez Alcalá, directrice de Paraguay Educa, déclare: "Ce que l'équipe Evolution a mis en lumière lors de cette journée TurtleArt, ce sont les aspects d'échange culturel entre les enfants et la communauté internationale et le fait que les enfants enseignent les uns aux autres, tout en suivant leurs goûts personnels, notamment sur des projets qui comportent une interaction avec le monde physique." + +Claudia Urrea, éducatrice et membre du bureau de supervision de Sugar Labs s'entousiasme : "Avec TurtleArt, les enfants adorent programmer les robots et utiliser les capteurs pour créer des images artistiques, s'adonner à des activités concrètes utilisant des concepts mathématiques tels que les variables et les nombres aléatoires. Ils se rendent compte de la vitesse à laquelle ils apprennent et découvrent les applications multiples de l'informatique." + +Andres Aguirre du projet Butia, un robot programmé avec TurtleArt, déclare: "Bien que les enfants aient disposé d'un temps limité pour utiliser les robots, ils ont pu faire l'expérience de concepts de programmation haut-niveau tels que les tests conditionnels et structures de contrôle." + +- **Lien:** [Día de Tortugarte](http://turtleartday.org) +- **Lien:** [Paraguay Educa](http://www.paraguayeduca.org) +- **Lien:** [CeibalJam!](http://ceibaljam.org) + +Image:  +Image:  + +--- + +**À propos de Sugar Labs(R)** +Sugar Labs(R) est une organisation non lucrative de volontaires, membre du projet Software Freedom Conservancy. Sugar Labs coordonne les volontaires dans le monde qui sont passionnés par l'idée de fournir des opportunités d'éducation à travers la plate-forme éducative Sugar; installée sur plus de 3 millions d'ordinateurs. Sugar Labs(R) est soutenu par des donations et cherche des fonds pour accélérer son développement. Pour plus d'information, voir [http://www.sugarlabs.org/press](http://www.sugarlabs.org/press) ou contacter **pr@sugarlabs.org**. + +Sugar Labs(R) est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leurs auteurs.`,La=Object.freeze(Object.defineProperty({__proto__:null,default:Y},Symbol.toStringTag,{value:"Module"})),Q=`--- +title: "Sugar Labs(R), organización sin fines de lucro para la Educación celebra dos Ganadores del Gran Premio de Google Code-In" +excerpt: "Sugar Labs reconoce a los estudiantes Ignacio Rodríguez y Jorge Alberto Gómez López como ganadores del gran premio de Google Code-In, quienes contribuyeron significativamente a mejorar la plataforma de aprendizaje Sugar." +category: "PRESS RELEASE" +date: "2014-01-22" +slug: "sugar-labs-celebra-ganadores-google-code-in" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "google-code-in,open-source,education,students,programming,development,uruguay,el-salvador" +--- +<!-- markdownlint-disable --> + +[PDF](/assets/post-assets/press/SugarLabsPR-es.20140122.pdf) + +CAMBRIDGE, Mass, Enero 22, 2014 — Sugar Labs(R), organización educativa sin fines de lucro que provee software de aprendizaje libre y de código abierto para niños, se enorgullece en reconocer a los ganadores del gran premio de Google Code-In (GCI) Ignacio Rodríguez y Jorge Alberto Gómez López, quienes participaron de forma brillante en el programa anual de Google para estudiantes de secundaria y bachillerato entre 13 a 17 años de edad. + +A través de GCI, Google invita a las organizaciones de código abierto a asesorar estudiantes que trabajan en tareas reales de programación y documentación. Poco más de 30 participantes de más de una docena de países —desde Australia a Zimbabwe—, asesorados por voluntarios de Sugar Labs, ayudaron a mejorar la plataforma de aprendizaje Sugar que utilizan más de tres millones de niños en todo el mundo. Los ganadores visitarán la sede de Google en Mountain View, California esta primavera. + +Ignácio, quien tiene 14 años y vive en Canelones, Uruguay, creció con Sugar y comenzó a participar en el desarrollo de Sugar desde hace tres años. "¡La competencia fue un lugar para socializar y hacer amigos!", dice él. "Aunque sentí presión, la comunidad estaba allí para ayudar." + +Jorge, de 17 años, vive en Santa Tecla, El Salvador. "Nunca en mi vida soñé empezar a trabajar en un proyecto de código abierto; fue muy divertido explorar un mundo totalmente nuevo, aprender nuevas herramientas, y lo más importante, hacer nuevos amigos de diferentes partes del mundo —personas que comparten el mismo objetivo y trabajan como una comunidad. Siento que soy parte de Sugar Labs, que formó parte de un gran proyecto, con los amigos y mentores". + +Completan la lista de finalistas de Sugar Labs: Sai Vineet de Jamshedpur, India; Emil Dudev desde Sofía, Bulgaria; y Sam Parkinson desde Canberra, Australia (la plataforma Sugar se utiliza ampliamente en las escuelas australianas). Sam comentó: "Contribuir a Sugar, además de darme experiencia en programación, me ha mostrado cómo la programación colaborativa puede ser divertida. ¡Y también ha sido divertido trabajar hacia una meta significativa común!" + +"GCI ha hecho evidente que los usuarios de Sugar se están convirtiendo en los desarrolladores de Sugar: Sugar no sólo les da la licencia, sino también los medios para desarrollar sus propias herramientas de aprendizaje. Al tomar posesión, se convierten en responsables," dijo Walter Bender, fundador de Sugar Labs. "Ha sido difícil elegir a los ganadores. Muchos participantes completaron múltiples tareas. Ignacio fue prolífico, completando más de 60 tareas, pero nuestros cinco finalistas realizaron mejoras fundamentales a la plataforma misma de Sugar." + +José Miguel García, un pedagogo del Departamento de Tecnología Educativa de CODICEN-ANEP en Montevideo, observó: "Por segundo año consecutivo, un joven de Uruguay ha ganado la competencia. La implementación del Plan Ceibal, que entrega en propiedad una computadora portátil por niño y adolescente en Uruguay permite alcanzar niveles de equidad en cuanto al acceso a las tecnologías. Estas computadoras portátiles, además de ser utilizadas en la educación formal, permiten a los jóvenes investigar y desarrollarse en diversas actividades, ya sean lúdicas, artísticas, comunicativas, de programación, etc. Estos jóvenes, orientados e incentivados por su familia, profesores y/o por la propia comunidad de Sugar, alcanzan niveles importantes en el desarrollo del conocimiento, habilidad fundamental para la sociedad del siglo XXI." + +Sugar Labs desea agradecer a Google y, en particular, a Bradley Kuhn, director ejecutivo de la Software Freedom Conservancy. + +--- + +**Sobre Google Code-In** +**Sitio Oficial:** [developers.google.com/open-source/gci](http://developers.google.com/open-source/gci) +**Blog Oficial:** [google-opensource.blogspot.fr](http://google-opensource.blogspot.fr/2014/01/google-code-in-2013-drumroll-please.html) + +--- + +**Imágenes** + + + +--- + +**Sobre Sugar Labs(R)** +Sugar Labs, una organización sin fines de lucro conducida por voluntarios, es un proyecto miembro de Software Freedom Conservancy. Originalmente parte del proyecto One Laptop Per Child, Sugar Labs coordina voluntarios en todo el mundo que tienen pasión por dar a los niños oportunidades de educarse a través de la Plataforma de Aprendizaje Sugar. + +Sugar Labs se mantiene en base a donaciones y está buscando financiación y voluntarios para acelerar su desarrollo. Por más información, por favor visite [sugarlabs.org](http://www.sugarlabs.org) o contacte a [pr@sugarlabs.org](mailto:pr@sugarlabs.org). + +Sugar Labs es una marca registrada de la Software Freedom Conservancy. Otros nombres y marcas corresponden a sus respectivos dueños. + +---`,Ta=Object.freeze(Object.defineProperty({__proto__:null,default:Q},Symbol.toStringTag,{value:"Module"})),Z=`--- +title: "Sugar Labs(R) Educational Nonprofit Celebrates Two Google Code-In Grand Prize Winners" +excerpt: "Sugar Labs recognizes students Ignacio Rodríguez and Jorge Alberto Gómez López as winners of the Google Code-In Contest, who contributed significantly to improving the Sugar Learning Platform used by over three million children worldwide." +category: "PRESS RELEASE" +date: "2014-01-22" +slug: "sugar-labs-celebrates-google-code-in-winners" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "google-code-in,education,open-source,students,programming,development,uruguay,el-salvador" +--- +<!-- markdownlint-disable --> + +[PDF](/assets/post-assets/press/SugarLabsPR-en.20140122.pdf) + +CAMBRIDGE, Mass, January 22, 2014 — Sugar Labs®️, educational nonprofit provider of free and open-source learning software for children, is proud to recognize the **Google Code-In Contest**. + +**Watch Live:** [Google Code-In Overview](http://developers.google.com/open-source/gci/) +**Platform:** [Google Open Source Blog](http://google-opensource.blogspot.fr/2014/01/google-code-in-2013-drumroll-please.html) + +Grand-prize winners **Ignacio Rodríguez** and **Jorge Alberto Gómez López**, who participated brilliantly in Google's annual program for middle- and high-school students aged 13 to 17. Through GCI, Google invites open source organizations to mentor students who work on real programming and documentation tasks. Over 30 participants from more than a dozen countries — from Australia to Zimbabwe — mentored by Sugar Labs volunteers, helped to improve the Sugar Learning Platform used by over three million children worldwide. The winners will visit Google headquarters in Mountain View, California this spring. + +Ignacio, who is 14 and lives in Canelones, Uruguay, grew up with Sugar and began participating in Sugar development three years ago. "The competition was a place to socialize and make friends!", he says. "While I felt pressure, the community was there to help." + +Jorge, age 17, lives in Santa Tecla, El Salvador. "I never dreamed I would be working on an open source project; it was really fun to explore a whole new world, learn new tools, and most importantly, make new friends from different parts of the world — people that share the same objective and work as a community. I feel that I'm part of Sugar Labs, part of a big project, with friends and mentors." + +Rounding out the Sugar Labs list of finalists are **Sai Vineet** from Jamshedpur, India, **Emil Dudev** from Sofia, Bulgaria, and **Sam Parkinson** from Canberra, Australia (Sugar is widely deployed in Australian schools). Sam remarked, "Contributing to Sugar has, besides giving me experience in programming, shown me how fun programming collaboratively can be! And it's also been fun working towards a common, meaningful goal." + +> "GCI has made it evident that Sugar users are becoming the Sugar developers: Sugar not only gives them the license but also the means for developing their own tools for learning. In taking ownership, they become responsible," +> — *Walter Bender, founder of Sugar Labs* + +"We had a difficult time choosing our winners. Many participants completed multiple tasks. Ignacio was prolific, completing over 60 tasks, but all five of our finalists made fundamental improvements to the Sugar platform itself." + +**José Miguel García**, an education researcher from the Department of Educational Technology at Uruguay's CODICEN-ANEP in Montevideo, observed: + +> "For the second consecutive year a youth from Uruguay has won the competition. The nationwide Plan Ceibal, which delivers a laptop running Sugar to every child, achieves levels of equity in access to technology. These laptops, besides being used in formal education, enable young people to explore and develop activities, whether recreational, artistic, communication, programming, etc. These young people, guided and encouraged by their families, teachers, and the Sugar community are reaching significant levels in the development of 21st century skills." + +Sugar Labs wishes to thank Google and in particular **Bradley Kuhn**, executive director of the Software Freedom Conservancy. + +<img src="/assets/post-assets/press/SugarLabs_GCI_2013_Winner_Ignacio.jpg" alt="SugarLabs_GCI_2013_Winner_Ignacio.jpg" style="width:100%"> + +<img src="/assets/post-assets/press/SugarLabs_GCI_2013_Winner_Jorge.jpg" alt="SugarLabs_GCI_2013_Winner_Jorge.jpg" style="width:100%"> + +--- + +### About Sugar Labs®️ + +Sugar Labs®️ is a volunteer-driven member project of [Software Freedom Conservancy](https://sfconservancy.org/), a nonprofit corporation. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. + +Sugar Labs®️ is supported by donations and is seeking funding to accelerate development. For more information, please visit [www.sugarlabs.org/press](http://www.sugarlabs.org/press) or contact \`pr@sugarlabs.org\`. + +Sugar Labs®️ is a registered trademark of the Software Freedom Conservancy. Other names are trademarks of their respective owners.`,Pa=Object.freeze(Object.defineProperty({__proto__:null,default:Z},Symbol.toStringTag,{value:"Module"})),ee=`--- +title: "The connection between Sugar - Students - Teachers" +excerpt: "This Sugar Story explores how the Sugar learning platform connects students and teachers, highlighting user contributions, educational impact, and how the platform's open design encourages innovation from its community." +category: "SUGAR STORIES" +date: "2016-05-15" +slug: "connection-between-sugar-students-teachers" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "education,open-source,teachers,students,uruguay,programming,contribution,learning" +--- +<!-- markdownlint-disable --> + +Story1: The connection between Sugar - Students - Teachers +--------------------------------------------------------- +* * * + +One of the first formal studies of Sugar took place in Uruguay in 2009–10. Uruguay was the first country to provide every child a free internet-connected laptop computer. They began distributing OLPC XO laptops running Sugar in 2007. Even though Uruguay is a relatively small country, with less than 500,000 children, it took several years before they could achieve full coverage. The last region to receive laptops was Montevideo. Montevideo was last because there was less need there than in the more rural regions, since many urban children already had access to computers. The delay in deploying in Montevideo presented an opportunity to study the impact of Sugar. Children were asked in 2009—before they has Sugar—what they did with their computers. It should come as no surprise that they used their computers to play games (See Figure). The same children were asked in 2010—after almost one year of using Sugar—what they did with their computers. Again they responded that they used their computers to play games. They were still children after all. But they also used their computers to write, chat, paint, make and watch videos, search for information, etc. In other words, with Sugar, they used the computer as a tool. Children play games. But given the opportunity and the correct affordances, they can leverage computation to do much much more. + +<img src="/assets/post-assets/data.png" alt="Image of data from a DSPE-ANEP survey" class="img-fluid" width="100%"/> + +**Figure: Data from a DSPE-ANEP survey of students in Montevideo before and after the deployment of Sugar** + +Sugar was designed so that new uses emerging from the community could easily be incorporated, thus Sugar could be augmented and amplified by its community and the end users. We encouraged our end users to make contributions to the software itself. This was in part out of necessity: we were a small team with limited resources and we had no direct access to local curricula, needs, or problems. But our ulterior motive was to engage our users in development as a vehicle for their own learning. + +One of the first examples of end-user contributions took place in Abuja, Nigeria, site of the first OLPC pilot project. While teachers and students took to Sugar quickly, they did confront some problems. The most notable of these was that the word-processor application, Write, did not have a spelling dictionary in Igbo, the dialect used in this particular classroom (and one of the more than three-hundred languages currently spoken in Nigeria). From a conventional software-development standpoint, solving this problem (300 times) would be prohibitively expensive. But for children in Abuja, equipped with Sugar, the solution was simple: confronted with the problem of lacking a dictionary, they made their own Igbo dictionary. The did not look for others to do the work for them. The took on the responsibility themselves. The Free/Libre Software ethic built into Sugar enabled local control and innovation. + +John Gilmore heard the about our aspiration to reach out to our end users—children—at the 2008 Libreplanet conference. He asked, "how many patches have you received from kids?" At the time, the answer to his question was zero. But over the past nine years, the situation has changed dramatically. By 2015, 50% of the patches in our new releases were coming from children (See Table); our release manager in 2015–16 (Sugar v0.108) was Sam Parkinson, a fifteen-year-old from Australia; our current release manager (Sugar v0.110) is Ignacio Rodríguez, an eighteen-year-old from Uruguay who began hanging out on our IRC channel at age ten and contributing code at age twelve. + +| Release number (date) | Total Commits | Youth Commits | Release note URL | +|-------------------------|---------------|---------------|------------------------------------------------------------------------| +| 0.102 (July 2014) | 424 | 108 | [View Notes](https://wiki.sugarlabs.org/go/0.102/Notes) | +| 0.104 (February 2015) | 249 | 127 | [View Notes](https://wiki.sugarlabs.org/go/0.104/Notes) | + +**Table 1: Sugar commits by youth contributors** + +When the now former president of Uruguay, José Mujica, learned that a twelve-year-old from a small town east of Montevideo had programmed six entirely new Sugar activities for the XO, he smiled and said triumphantly: "Now we have hackers." In his eyes, this one child's ability to contribute to the global Sugar development community was a leading indicator of change and development in his country. + +None of this happened on its own. End-user contributions are not simply an artifact of Sugar been Free/Libre Software. Open-source Software gives you access to the code and that Free/Libre Software gives you a license to make changes. But without some level of support, very few people will have the means to exercise the rights granted to them under the license. For this reason, we built scaffolding into Sugar to directly support making changes and extensions to Sugar applications and Sugar itself. + +Sugar has no black boxes: the learner sees what the software does and how it does it. Sugar is written in Python and comes with all of the tools necessary to modify Sugar applications and Sugar itself. We chose Python as our development language because of its transparency and clarity. It is a very approachable language for inexperienced programmers. With just one keystroke or mouse click, the Sugar "view source" feature allows the user to look at any program they are running. A second mouse click results in a copy of the application being saved to the Sugar Applications directory, where it is immediately available for modification. (We use a "copy on write" scheme in order to reduce the risk of breaking critical tools. If there is no penalty for breaking code, there is better risk-reward ratio for exploring and modifying code.) The premise is that taking something apart and reassembling it in different ways is a key to understanding it. + +Not every creative use of Sugar involves programming. Rosamel Norma Ramírez Méndez is a teacher from a school in Durazno, a farming region about two-hours drive north from Montevideo, Uruguay. Ramírez had her lessons for the week prepared when, first thing Monday morning, one of her students walked into her classroom holding a loofa. The child asked Ramírez, "teacher, what is this?" Rather than answering the question, Ramírez seized the opportunity to engage her class in an authentic learning experience. She discarded her lesson plans for the week. Instead, on Monday the children figured out what they had found; on Tuesday they determined that they could grow it in their community; on Wednesday they investigated whether or not they should grow it in their community; on Thursday they prepared a presentation to give to their farmer parents on Friday about why they should grow this potential cash crop. Not every teacher has the insight into learning demonstrated by Ramírez. And not every teacher has the courage to discard their lesson plans in order to capture a learning opportunity, But given an extraordinary teacher, she was able to mentor her students as they used Sugar as a tool for problem-solving. Ramírez encouraged her students to become active in their learning, which means that they engaged in doing, making, problem-solving, and reflection. + +_**"Teachers can learn (and contribute) too." – Walter Bender**_ + +Sometimes teachers have been directly involved in Sugar software development. Sugar has an abacus application to help children explore whole-number arithmetic and the concept base (the activity allows the user to switch between various base representations of whole numbers). It also lets children design their own abacus. Teachers in Caacupé, Paraguay, were searching for a way to help their students with the concept of fractions. After playing with the Sugar abacus activity, they conceived and created—with the help of the Sugar developer community—a new abacus that lets children add and subtract fractions (See Figure). Sugar didn't just enable the teachers to invent, it encouraged them to invent. + +<img src="/assets/post-assets/abacus.png" alt="Image of the Caacupé Abacus" width="100%" class="img-fluid" /> + +**Figure: The Caacupé Abacus. The white beads represent whole numbers. The black beads represent fractions.** + +Guzmán Trinidad, a high-school physics teacher from Montevideo, Uruguay and Tony Forster, a retired mechanical engineer from Melbourne, Australia collaborated on a collection of physics experiments that could be conducted with a pair of alligator clips and a small collection of Sugar applications. In the process of developing their experiments, they maintained regular communication with the developers, submitting bug reports, documentation, feature requests, and the occasional patch. Other examples of teacher and community-based contributions include Proyecto Butiá, a robotics and sensor platform build on top of Sugar (and GNOME) at Facultad de Ingeniería, Universidad de la República, Uruguay. Butiá inspired numerous other robotics platforms, e.g., RoDI (Robot Didáctico Inalámbrico) developed in Paraguay, as well as a wealth of projects aligned with the pedagogy of Constructionism. In the spirit of Sugar, these hardware projects were all designed to be "open": schematics and firmware were made available under Free/Libre licenses. + +In 2012, we were part of a team running a week-long Sugar workshop for more than 60 teachers who had traveled to Chachapoyas, the regional capital of the Amazonas region of Peru. During the day we spend time reviewing the various Sugar activities and discussing strategies for using Sugar in the classroom. In the evenings, we gave a series of optional workshops on specialized topics. One evening, mid-week, the topic was fixing bugs in Sugar. It was not expected that many teachers would attend—in part because we were competing with an annual festival and in part because their background in programming was minimal. But almost everyone showed up. In the workshop, we walked through the process of fixing a bug in the Sugar Mind Map activity and used git to push a patch upstream. Teachers, especially rural teachers, have a hunger for knowledge about the tools that they use. This is in part due to intellectual curiosity and in part due to necessity: no one is going to make a service call to Amazonas. As purveyors of educational technology we have both a pedagogical and moral obligation to provide the means by which our users can maintain (and modify) our products. Enabling those closest to the learners is in the interest of everyone invested in educational technology as it both ensures viability of the product and it is a valuable source of new ideas and initiatives. + +References +---------- + +**Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=vLiCumKjofc) +- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) + +- Ceibal Jam (2009). Convenio marco entre la Asociación Civil Ceibal Jam y la Universidad de la República. +- DSPE-ANEP (2011). Informe de evaluación del Plan Ceibal 2010. Administración Nacional de Educación Pública Dirección Sectorial de Planificación Educativa Área de Evaluación del Plan Ceibal.`,Ca=Object.freeze(Object.defineProperty({__proto__:null,default:ee},Symbol.toStringTag,{value:"Module"})),ne=`--- +title: "Sugar Labs receives eleven contributor projects for GSoC 2024" +excerpt: "Sugar Labs announces acceptance of eleven programming projects for Google Summer of Code 2024, including work on Music Blocks, Sugarizer, AI tools, and more." +category: "PRESS RELEASE" +date: "2024-05-01" +slug: "sugar-labs-gsoc-2024-projects" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "gsoc,google-summer-of-code,programming,education,ai,music-blocks,sugarizer,open-source,mentorship" +--- + +<!-- markdownlint-disable --> + +**CAMBRIDGE, MA, USA -- May 1, 2024 -- Sugar Labs today announced it received eleven projects for participation in this year's Google Summer of Code (GSoC).** + +## Sugar Labs receives eleven projects for GSoC + +Sugar Labs will receive eleven projects for this year's Google Summer of Code (GSoC), a [12+ week programming project under the guidance of mentors](https://summerofcode.withgoogle.com/). This marks the fourteenth year that Sugar Labs has participated in GSoC since 2009. + +## Sugar Labs projects for GSoC 2024 + +As part of GSoC 2024, Sugar Labs will be working on Music Blocks, Sugarizer, Flatpak, Raspberry Pi, and Sugar Activities. Plus, this summer, we will be working on several AI projects to create new tools for teaching and learning. These include an addition to the Chat and Pippy Activities in Sugar, as well as several Music Blocks projects. + +Here is a detailed list of all eleven projects: + +| Project Title | Contributor | Assigned Mentor(s) | +|--------------------------------------------------------|--------------------------|--------------------------| +| Musical ideation through Generative AI | AbhijeetGSOC | Devin Ulibarri | +| Sugar on Raspberry Pi | Anurag Singh (Oval-Elephant) | Walter Bender | +| Music Blocks v4 Project Builder Integration | Karan Palan | Anindya Kundu | +| Make your own Lesson Plan for Music Blocks | khadar | Devin Ulibarri | +| Add an AI-assistant to the Pippy Activity | Kshitij_Shah | Walter Bender | +| Develop 8 new mathematical activities | Marsian | Chihurumnaya Ibiam | +| Musical creation and transcription assistance via generative AI | Mubashir Shariq | Devin Ulibarri | +| Add an AI chatbot to the Chat Activity | Qixiang | Walter Bender | +| Sugarizer 3D Volume Activity | Samarth Bagga | Lionel Laské | +| Maintain and Port 12 Sugar Activities to Flatpak | SudoSu-bham | tchx84 | +| Sugarizer VueJS App | UtkarshSiddhpura | Lionel Laské | + +## Where to find more information about Sugar Labs and GSoC + +**Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=vLiCumKjofc) +**Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) + +GSoC publishes full details about each organization and their projects. You can find information about Sugar Labs's projects this year at [Google Summer of Code - Sugar Labs](https://summerofcode.withgoogle.com/programs/2024/organizations/sugar-labs). + +Since 2019, Sugar Labs has published projects it is considering for Google Summer of Code in a [public repository published on GitHub](https://github.com/sugarlabs/GSoC). People interested in participating as contributors are encouraged to follow this repository. + +## About Sugar Labs + +Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology to youth around the world. Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating the need for source code to be published publicly for study, licensed under a Free/Libre license for explicit permission to share and remix, and openly worked upon within a community where students are invited to make contributions, under guidance of experienced mentors. + +Donations to support the work of Sugar Labs can be made at [https://wiki.sugarlabs.org/go/Sugar_Labs/Donate](https://wiki.sugarlabs.org/go/Sugar_Labs/Donate).`,Ma=Object.freeze(Object.defineProperty({__proto__:null,default:ne},Symbol.toStringTag,{value:"Module"})),te=`--- +title: "Sugar Labs: Past, present, and future" +excerpt: "Join Sugar Labs for the kickoff of our new event series exploring our history, current projects, and vision for the future of educational technology for youth around the world." +category: "EVENTS" +date: "2024-05-03" +slug: "sugar-labs-past-present-future" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "events, education, open source, community, sugar labs" +--- + +<!-- markdownlint-disable --> + +**Sugar Labs kicks off a series of events with a live online event titled _"Sugar Labs: Past, present, and future"_ on Friday, May 3, 2024 at 15:00 ET (19:00 UTC).** We invite you to join us as we reflect on our story, explore our vision, and share how you can contribute. + +**Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=jZs-QJNfglc) +- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) + +--- + +## Event Information + +- **Event:** Sugar Labs: Past, present, and future +- **Date:** May 3, 2024 +- **Time:** 15:00 ET (19:00 UTC) +- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=jZs-QJNfglc) +- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) + +--- + +## About Sugar Labs + +Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology for youth around the world. + +Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating: + +- Public access to source code for study +- Free/Libre licensing for sharing and remixing +- Open collaboration within a welcoming community +- Contributions from students under experienced guidance + +Support our work: [Donate here](https://www.sugarlabs.org/donate/) + +--- +`,xa=Object.freeze(Object.defineProperty({__proto__:null,default:te},Symbol.toStringTag,{value:"Module"})),ae=`--- +title: "Sugar Labs announces nonprofit status, new executive director" +excerpt: "Sugar Labs officially announces its 501(c)(3) nonprofit status and the appointment of long-time contributor Devin Ulibarri as its first full-time executive director." +category: "PRESS RELEASE" +date: "2024-05-08" +slug: "sugar-labs-announces-nonprofit-status-new-executive-director" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "nonprofit,501c3,leadership,executive-director,free-software,education,announcement,organization" +--- +<!-- markdownlint-disable --> + +**CAMBRIDGE, MA, USA -- May 8, 2024 -- Sugar Labs today announced its 501(c)(3) nonprofit status as well as its pick for executive director, long-time contributor Devin Ulibarri.** + +## Sugar Labs is a 501(c)(3) nonprofit + +In 2019, the Sugar Labs oversight board voted to incorporate as its own entity and apply for nonprofit status. After that vote, the members of the board began efforts to leave the Software Freedom Conservancy, incorporate as Sugar Labs Inc., and applied for 501(c)(3) nonprofit status. In the spring of 2021, Sugar Labs Inc. was granted nonprofit status from the IRS. + +**More Info:** +- [Meeting Minutes – May 3, 2019](https://wiki.sugarlabs.org/go/Oversight_Board/Meeting_Minutes-2019-05-03) +- [Software Freedom Conservancy](https://sfconservancy.org/) + +## Devin Ulibarri hired as executive director + +In January 2024, the board agreed to hire long-time Sugar Labs contributor Devin Ulibarri as their first full-time executive director. Prior to stepping into this role, he worked as the outreach & communications coordinator for the [Free Software Foundation](https://fsf.org). + +**More Info:** +- [Free Software Foundation](https://fsf.org) +- [Music Blocks](https://www.sugarlabs.org/music-blocks) + +Ulibarri has been a part of the Sugar Labs community for ten years, primarily working together with Walter Bender on [Music Blocks](https://www.sugarlabs.org/music-blocks) development. Devin has been an advocate of the work and philosophy of Sugar Labs, giving talks and leading workshops internationally. As a former board member, he also played a major role in helping the organization achieve its current nonprofit status. + +Of the hiring, Sugar Labs board member and founder Walter Bender said, "Devin is a dedicated colleague, with deep roots in both Free/Libre Software and the pedagogy of Constructionism. We're thrilled to have Devin in this new role." Ulibarri responded: "I'm excited to serve within this capacity, to help Sugar Labs grow to bring all of its good work to more teachers, parents, and students across the US and, ultimately, around the globe." + +## Current leadership + +The officers of Sugar Labs Inc. are currently: Devin Ulibarri, executive director; Claudia Urrea, treasurer; and Walter Bender, secretary. The current board is Samson Goddy, Lionel Laské, Claudia Urrea, Walter Bender, and Alex Perez. + +**More Info:** +- [Sugar Labs Oversight Board](https://wiki.sugarlabs.org/go/Oversight_Board)`,Ga=Object.freeze(Object.defineProperty({__proto__:null,default:ae},Symbol.toStringTag,{value:"Module"})),oe=`--- +title: "Musical Squares: From Turtle Blocks to Music Blocks and Beyond" +excerpt: "Learn about Music Blocks, a visual programming language that combines music and coding, with a hands-on demonstration during this educational Sugar Labs livestream event." +category: "EVENTS" +date: "2024-05-10" +slug: "musical-squares-turtle-blocks-music-blocks-beyond" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "music,programming,education,turtle-blocks,visual-programming,livestream,coding,music-education" +--- +<!-- markdownlint-disable --> + +**Sugar Labs is hosting an event _"Learn about Music Blocks, visual programming language with a hands-on activity"_ on Friday, May 10, 2024 at 15:00 ET (19:00 UTC).** Join us for a fun and educational introduction to Music Blocks. + +## Event Information + +- **Title:** Musical Squares: From Turtle Blocks to Music Blocks and Beyond +- **Date:** May 10, 2024 +- **Time:** 15:00 ET (19:00 UTC) +- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=jZs-QJNfglc) +- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) + +--- + +## About Sugar Labs + +Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities`,_a=Object.freeze(Object.defineProperty({__proto__:null,default:oe},Symbol.toStringTag,{value:"Module"})),ie=`--- +title: "Learn to make games with Gameeky!" +excerpt: "Join developer Martin Abente Lahaye for a hands-on tutorial on creating games with Gameeky, a platform that empowers young learners and educators to build cooperative games and learning experiences." +category: "EVENTS" +date: "2024-05-17" +slug: "learn-make-games-with-gameeky" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "game-development,education,tutorial,livestream,programming,youth,coding,gameeky" +--- +<!-- markdownlint-disable --> + +**"Learn to make games with Gameeky" will be presented live by developer Martin Abente Lahaye. Get a hands-on tutorial for how to make games with Gameeky. Play, create, and learn: Gameeky lets young learners and educators create and explore cooperative games and learning experiences. Watch live on Friday, May 17, 2024 at 15:00 ET (19:00 UTC).** + +## Event Information + +- **Title:** Learn to make games with Gameeky +- **Date:** May 17, 2024 +- **Time:** 15:00 ET (19:00 UTC) +- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=vLiCumKjofc) +- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) + +--- + +## About Sugar Labs + +Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology for youth around the world. + +Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating: + +- Public access to source code for study +- Free/Libre licensing for sharing and remixing +- Open collaboration within a welcoming community +- Contributions from students under experienced guidance + +Support our work: [Donate here](https://www.sugarlabs.org/donate/) +`,Ea=Object.freeze(Object.defineProperty({__proto__:null,default:ie},Symbol.toStringTag,{value:"Module"})),re=`--- +title: "An OLPC update with Lylian Peraza" +excerpt: "Sugar Labs hosts Lylian Peraza, Vice President of Project Development at OLPC, for a livestream discussion about the latest developments and projects from One Laptop Per Child." +category: "EVENTS" +date: "2024-05-24" +slug: "olpc-update-lylian-peraza" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "olpc,education,technology,livestream,interview,nonprofit,laptops,global-education" +--- +<!-- markdownlint-disable --> + +**Join Sugar Labs for a discussion with Lylian Peraza, Vice President of Project Development at OLPC. Watch live on Friday, May 24, 2024 at 15:00 ET (19:00 UTC).** + +## Event Information + +- **Title:** An OLPC update with Lylian Peraza +- **Date:** May 24, 2024 +- **Time:** 15:00 ET (19:00 UTC) +- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=SuOta9MLLnw) +- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) + +--- + +## About Sugar Labs + +Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology for youth around the world. + +Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating: + +- Public access to source code for study +- Free/Libre licensing for sharing and remixing +- Open collaboration within a welcoming community +- Contributions from students under experienced guidance + +Support our work: [Donate here](https://www.sugarlabs.org/donate/) +`,Da=Object.freeze(Object.defineProperty({__proto__:null,default:re},Symbol.toStringTag,{value:"Module"})),se=`--- +title: "Learn: How to git involved with Sugar Labs this summer" +excerpt: "Join Sugar Labs Executive Director Devin Ulibarri for a live session on how to get involved with Sugar Labs this summer while learning valuable programming skills and contributing to educational software." +category: "EVENTS" +date: "2024-05-31" +slug: "how-to-git-involved-sugar-labs-summer" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "volunteer,git,programming,education,summer-programs,open-source,mentorship,coding" +--- +<!-- markdownlint-disable --> + +**Sugar Labs executive director Devin Ulibarri gives a short intro on ways to "git" involved with Sugar Labs this summer, while learning valuable skills. Watch live on Friday, May 31, 2024 at 15:00 ET (19:00 UTC).** + +## Event information + +- **Title:** Learn: How to git involved with Sugar Labs this summer +- **Date:** May 31, 2024 +- **Time:** 15:00 ET (19:00 UTC) +- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=W5ZLFBZkE34) +- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) + +## About Sugar Labs + +Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology to youth around the world. Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating the need for source code to be published publicly for study, licensed under a free/libre license for explicit permission to share and remix, and openly worked upon within a community where students are invited to make contributions, under guidance of experienced mentors. + +Support our work: [Donate here](https://www.sugarlabs.org/donate/) +`,ja=Object.freeze(Object.defineProperty({__proto__:null,default:se},Symbol.toStringTag,{value:"Module"})),le=`--- +title: "GSoC+DMP contributors initial check-in 1 of 2: Music Blocks projects" +excerpt: "Join Sugar Labs for an introduction to Google Summer of Code (GSoC) and DMP projects this summer, presented by GSoC and DMP interns andfacilitated by their mentors, Devin Ulibarri, Walter Bender, and Anindya Kundu. Watch live on Friday, June 7, 2024 at 13:00 ET (17:00UTC)." +category: "EVENTS" +date: "2024-06-07" +slug: "gsoc-dmp-contributors" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "volunteer,git,programming,education,summer-programs,open-source,mentorship,coding" +--- +<!-- markdownlint-disable --> + +**Join Sugar Labs for an introduction to Google Summer of Code (GSoC) and DMP projects this summer, presented by GSoC and DMP interns andfacilitated by their mentors, Devin Ulibarri, Walter Bender, and Anindya Kundu. Watch live on Friday, June 7, 2024 at 13:00 ET (17:00UTC).** + +## Event information + +- **Title:** GSoC+DMP contributors initial check-in 1 of 2: Music Blocks projects +- **Date:** June 7, 2024 +- **Time:** 13:00 ET (17:00 UTC) +- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=PeIS3gXPFj0) +- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) +--- + +## About Sugar Labs + +Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology for youth around the world. + +Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating the need for source code to be published publicly for study, licensed under a free/libre license for explicit permission to share and remix, and openly worked upon within a community where students are invited to make contributions, under guidance of experienced mentors. + +Support our work: [Donate here](https://www.sugarlabs.org/donate/) +`,Wa=Object.freeze(Object.defineProperty({__proto__:null,default:le},Symbol.toStringTag,{value:"Module"})),de=`--- +title: "Writing new Activities and sharing sugar with Youth" +excerpt: "James Simmons shares his journey of contributing to Sugar Labs since 2007, including developing Activities for reading e-texts and creating resources to help others build their own Sugar Activities." +category: "SUGAR STORIES" +date: "2024-9-13" +slug: "writing-new-activities-sharing-sugar-with-youth" +author: "James Simmons" +description: "Sugar Labs Contributor" +tags: "community,activities,development,python,education,programming,ebooks,manuals" +--- +<!-- markdownlint-disable --> + +_Editorial note: This article was given to us by Sugar Labs community member James Simmons as part of a series called Sugar Stories, which aims to highlight stories from members our community. If you would like to share your Sugar Story with us as an article for possible publication, please send a draft to_ [_info@sugarlabs.org_](mailto:info@sugarlabs.org)_. Please be aware that there is an editorial process that will require some additional effort and collaboration, even after submission._ + +I started working with OLPC with the Give One Get One program back in 2007. Honestly speaking, at the time, I was more interested in getting an XO laptop for myself than in working for the project. I thought I could use the laptop to read plain textbooks from [Project Gutenberg](https://www.gutenberg.org/). Kindles were very expensive back then, and this looked like a good alternative. And it was. But, at the time, the Read Activity only worked with PDFs. In an effort to expand this functionality, I taught myself to program in Python, studied the code for the [Read Activity](https://activities.sugarlabs.org/en-US/sugar/addon/4028), and created the [Read Etexts Activity](https://activities.sugarlabs.org/en-US/sugar/addon/4035), which supported reading plain text files. Next, I decided that I wanted to have an Activity for reading comic books in CBZ format and created two of them: [View Slides](https://activities.sugarlabs.org/en-US/sugar/addon/4039) and [Read SD Comics](https://activities.sugarlabs.org/en-US/sugar/addon/4340). + + + +Photo of James Simmons with a copy of "Make your own Sugar Activities". Simmons has been contributing to Sugar since 2007. + +At the time, the best, and maybe only, way to learn how to create Activities was to study the code of existing ones. I'm a systems analyst, so that wasn't too difficult for me, since I already had some of the important skills needed to do this. But this situation wasn't great for teachers and their students who may want to create Activities but didn't yet have the skills needed. In 2009 or so, I convinced myself to write a proper manual, which we called [_Make Your Own Sugar Activities!_](https://archive.org/details/MakeYourOwnSugarActivities) I did this using the Floss Manuals website. I was fortunate enough to have a very nice cover illustration done for me by [Oceana Rain Fields](https://archive.flossmanuals.net/make-your-own-sugar-activities/about-the-authors.html), a student participating in the Rural Design Collective's summer mentorship program. The printed book was given out as a door prize at one of the first OLPC conferences. The book was later translated into Spanish by a team of Sugar Labs volunteers as [_Como Hacer Una Actividad Sugar_](https://archive.org/details/ComoHacerUnaActividadSugar). + +My personal involvement in Sugar Labs did not require any direct work with children, but, recently, I had the opportunity to introduce a young boy to Sugar. I had an old computer that I was going to give to a family friend, who was studying computer programming in college. His nine-year-old brother found out about it and wanted it for himself, so I installed the latest [Sugar Learning Platform](https://wiki.sugarlabs.org/go/What_is_Sugar#About_the_Sugar_Learning_Platform) and updated my old Activities to run on Python 3. He is pleased to have [the same operating system (OS) used by astronauts on the International Space Station (ISS)](https://www.fsf.org/blogs/community/gnu-linux-chosen-as-operating-system-of-the-international-space-station) and enjoys playing [Tux Kart](https://supertuxkart.net/Main_Page). I look forward to introducing him to even more that Sugar has to offer in the coming months. + +It's nice to have the [Sugar environment](https://wiki.sugarlabs.org/go/What_is_Sugar) as an option for kids, as well as ways for the community to participate in the creation of new Activities.`,Oa=Object.freeze(Object.defineProperty({__proto__:null,default:de},Symbol.toStringTag,{value:"Module"})),ce=`--- +title: "The Sweet Spot – Issue 001" +excerpt: "The inaugural issue of Sugar Labs' newsletter covering recent updates, GSoC projects, ways to get involved, and community news." +category: "COMMUNITY NEWS" +date: "2024-09-20" +slug: "the-sweet-spot-issue-001" +author: "Sugar Labs" +description: "Community Newsletter" +tags: "newsletter,community,gsoc,dmp,updates,volunteer,outreach,education" +--- +<!-- markdownlint-disable --> +# Recent news for September 20, 2024 + +Welcome to the very first issue of the **"Sweet Spot"**, a newsletter for Sugar Labs-related news in development, student and teacher work, events, how to get involved, and other news and information. This newsletter will be published semi-regularly for now, but the plan is to publish it on a bi-monthly, perhaps even monthly, basis in the future. Our aim with this newsletter is to help keep the growing body of Sugar Labs contributors on the same page, all while documenting our growth for our own and others' reference. + +This first issue is meant to set a precedent of communication and documentation, as well as to help inform the community of our current status, recent progress, and future plans. Its predecessor is the ["Sugar Digest"](https://lists.sugarlabs.org/archive/community-news/), which still serves as an important catalog of our activities. Like Sugar Digest, this newsletter is intended to keep community members in the loop about everything going on within Sugar Labs. It will highlight any recent publications from us. It will occasionally include links to third-party news and updates that our community finds relevant. + +This first issue has links and "news" from a few months back. Future installments will focus on a more acute timeframe than this inaugural issue, which aims to cover our news since the beginning of this year. + +We hope that you enjoy this first issue. And, if you have something you'd like to share, please feel free to email [info@sugarlabs.org](mailto:info@sugarlabs.org). And for those who would like to volunteer in other ways, this edition has a list of volunteer help that we need with Sugar Labs overall. + +## Updates + +### GSoC and DMP students complete their projects + +This year's GSoC and DMP students have completed their work for Sugar Labs. Students were asked to document their progress through blogs and participate in online events showcasing their work at regular intervals throughout the summer. You can find links to their blog posts on our bi-weekly summary posts on Medium and watch videos of their presentations on YouTube. + +#### Bi-weekly GSoC and DMP summaries: + +- [Please help us welcome this summer's Google Summer of Code team for Music Blocks development](https://medium.com/@sugarlabs/please-help-us-welcome-this-summers-google-summer-of-code-team-for-music-blocks-development-6c2524244605) +- [GSoC 2024 Students Weekly Report 1](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-report-1-1af7c29ede0a) +- [GSoC 2024 Students Weekly Reports 2 and 3](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-reports-2-and-3-af03ec159b49) +- [GSoC 2024 Students Weekly Reports 4 and 5](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-reports-4-and-5-987825617340) +- [GSoC 2024 Students Weekly Reports 6 and 7](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-reports-6-and-7-9eacb78e4093) +- [GSoC 2024 Students Weekly Reports 8 and 9](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-reports-8-and-9-fb7d86cfabb1) +- [GSoC 2024 Students Weekly Reports 10 and 11](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-reports-10-and-11-670e9f3bb6b0) + +#### YouTube updates: + +- [GSoC+DMP contributors initial check-in 1 of 2: Music Blocks projects](https://www.youtube.com/watch?v=PeIS3gXPFj0) +- [GSoC+DMP contributors initial check-in 2 of 2: Sugarizer, Raspberry Pi, Math games, and more](https://www.youtube.com/watch?v=k7eY-tkl2zw) +- [Summer Interlude by GSoC+DMP Interns, Presentation 1 of 2: Music Blocks and Sugarizer](https://www.youtube.com/watch?v=qWLWCdp4_D4) +- [Summer Interlude by GSoC+DMP Interns, Presentation 2 of 2: RPi, AI Assists, Math games, and more](https://www.youtube.com/watch?v=TARoJDitQVg) +- [Summer Finale by GSoC Interns, Presentation 1 of 3: Music Blocks and Sugarizer](https://www.youtube.com/watch?v=dVYpK5fTHsQ) +- [Summer Finale by GSoC Interns, Presentation 2 of 3: RPi, AI Assists, Math games, and more](https://www.youtube.com/watch?v=d0nTfKmOWl8) +- [Summer Finale by DMP Interns, Presentation 3 of 3: Music Blocks, Raspberry Pi and Math games](https://www.youtube.com/watch?v=0yMqz3GW3rY) + +### Ways to get involved + +Sugar Labs is seeking volunteer assistance in the following ways. Sustained, committed help in any of the following areas will help us grow as an organization. If you are passionate or curious to learn more about any of these roles, and are able to commit the time necessary, then we encourage you to apply. Send a notification of your interest to [info@sugarlabs.org](mailto:info@sugarlabs.org), including some information about yourself, what interests you about the volunteer role, and what experience/qualities make you a good candidate for the position. + +- [Help Wanted](https://wiki.sugarlabs.org/go/Help_Wanted) +- [Introduction Video](https://www.youtube.com/watch?v=W5ZLFBZkE34) + +## Social Links + +- **Wiki** – [https://wiki.sugarlabs.org](https://wiki.sugarlabs.org) +- **Mastodon** – [https://mastodon.social/@sugar_labs](https://mastodon.social/@sugar_labs) +`,Ba=Object.freeze(Object.defineProperty({__proto__:null,default:ce},Symbol.toStringTag,{value:"Module"})),ue=`--- +title: "Board election results announcement: Three new members for the 2025-26 cycle" +excerpt: "The election results for the Sugar Labs Board of Directors have been announced. Devin Ulibarri, Sumit Srivastava, and Sebastian Silva will serve on the board for the 2025-26 cycle." +category: "COMMUNITY NEWS" +date: "2024-11-08" +slug: "board-election-results-2025-26" +author: "Devin Ulibarri" +description: "Executive Director" +tags: "markdown,parser,test,education,post,aigenerated" +--- +<!-- markdownlint-disable --> + +# The results for the 2025-26 Sugar Labs board cycle have been determined. + +The votes have been counted, and the [results](https://bettervoting.com/dp3xc7/) for the [2025-26 Sugar Labs board cycle](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) have been determined. + +The winners are **Devin Ulibarri, Sumit Srivastava, and Sebastian Silva**. They have all been notified and have agreed to serve on the Board of Directors for the 2025-26 cycle. For this election, we used [bettervoting.com](https://bettervoting.com) after doing research on various voting systems. Please read our [original election announcement](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) for more information on how we decided upon this voting system. + +The new members of the board will be filling the seats of two outgoing board members, **Lionel Laské and Alex Perez**, and one vacant seat. + +The next election for three seats to the **2026-27 cycle** is planned for **August of next year**. All Sugar Labs members may vote, and members can: +- Run for election to the Board of Directors +- Vote in the elections for the Board of Directors +- Suggest referenda + +As indicated in the [Sugar Labs Inc. bylaws](https://wiki.sugarlabs.org/go/Sugar_Labs/Governance), anyone with "significant and sustained" contributions to Sugar Labs is eligible for membership. If you believe you qualify for membership based on this criteria and are interested in [becoming an official member of Sugar Labs](https://wiki.sugarlabs.org/go/Sugar_Labs/Members), you are encouraged to send an email to <members@sugarlabs.org>. + +If you were a member in the past but [did not vote in this election](https://www.sugarlabs.org/community/2024/11/22/elections-extension/), you will need to reapply for membership in order for your membership status to be reinstated. *(If you voted in this election, no further action is required.)* Registering for membership early will help ensure that you will be ready for the next election. + +If you are interested in volunteering to assist with the next election in 2025, please contact <volunteering@sugarlabs.org> with your interest. + +On behalf of the [Sugar Labs Board of Directors](https://www.sugarlabs.org/leadership/), we offer a big **Thank you!** to all who participated in this year's election. +`,Ra=Object.freeze(Object.defineProperty({__proto__:null,default:ue},Symbol.toStringTag,{value:"Module"})),he=`--- +title: "Deadline extended to November 24 to apply for a ballot and apply for candidacy" +excerpt: "Sugar Labs has extended the deadline for board of directors election participation to November 24, including both ballot applications and candidacy submissions for the upcoming election cycle." +category: "COMMUNITY NEWS" +date: "2024-11-22" +slug: "elections-extension-november-2024" +author: "Devin Ulibarri" +description: "Executive Director" +tags: "elections,governance,board,voting,deadline,community,membership" +--- +<!-- markdownlint-disable --> + +**Sugar Labs is running an election this fall for three seats to its board of directors. The deadline to apply for a ballot, as well as submit candidacy for the board, is November 24. Sugar Labs community members are encouraged to participate. By submitting an application for a ballot you will also be considered for membership. Current members who do not apply for a ballot will have their membership rescinded.** + +The deadline to apply for a ballot and apply for candidacy is fast approaching. Extended to Sunday, the deadline to [apply for a ballot](https://forms.gle/48F6h5wdV6BpSro66) is now November 24, 2024, End of Day (EoD), Anywhere on Earth (AoE). It is also the deadline to [submit for candidacy](https://wiki.sugarlabs.org/go/Oversight_Board/2025-2026-candidates#Candidates) for the [board of directors](https://www.sugarlabs.org/leadership/). + +### Eligibility to vote + +Since we made [our initial announcement](https://www.sugarlabs.org/community/2024/11/08/fall-board-elections-how-to-participate/), one of the most frequently asked questions has been *what determines eligibility for participating in the election?* Participation in the election is open to any member of Sugar Labs, and the eligibility requirements for membership are published on [Sugar Labs Members page](https://wiki.sugarlabs.org/go/Sugar_Labs/Members). + +The main gist, however, is that you've made a contribution to Sugar Labs. According to our definition, such a contribution "may be code, documentation, translations, maintenance of project-wide resources, *running a Sugar deployment*, or other non-trivial activities which benefit Sugar Labs." + +If you've made such a contribution to Sugar Labs, you are eligible as a member, and, as a member, you may vote. ***Also, if you're not a member or unsure about your status, we still encourage you to submit an application for a ballot.*** We will automatically begin to determine your membership eligibility based on your publicly visible contributions, so no other steps are necessary on your part. + +### Current members must vote in this election in order to maintain their membership status + +Our most recent membership list may be found [here](https://wiki.sugarlabs.org/go/Sugar_Labs/Members/List). If you are currently a member but you do not apply for a ballot to vote in this election, then we will consider your membership to be rescinded and your membership will be made inactive. Because [our bylaws require a majority vote from members to pass certain amendments](https://wiki.sugarlabs.org/go/Sugar_Labs/Governance#ARTICLE_XI), we need to ensure that our current membership list is up-to-date with active members. + +If you've made a contribution to Sugar Labs in the past, ***we strongly encourage you to vote in this election to maintain your membership status.*** We thank you for your contribution, and we encourage you to continue to participate in Sugar Labs, which is now investing in its growth and expansion like never before. + +If it's been a while since you've made a contribution, we encourage you to join us on our main [Matrix channel](https://matrix.to/#/#sugar:matrix.org) and follow us on [GitHub](https://github.com/sugarlabs/). These two channels are currently the most active for coordinating contributions. + +### Receive your ballot + +We encourage you to vote. The application to receive your ballot, due by the End of Day (EoD), Anywhere on Earth (AoE), November 24, 2024, is [here](https://forms.gle/48F6h5wdV6BpSro66). + +### Running for a board position + +For those of you who would like to run for a board position, you will need to add your name and statement to the list on the [candidate page](https://wiki.sugarlabs.org/go/Oversight_Board/2025-2026-candidates). If you need any technical assistance with the wiki, please contact <elections@sugarlabs.org>. + +Candidates should read and understand the terms of the [Sugar Labs Inc.'s Bylaws](https://wiki.sugarlabs.org/go/Sugar_Labs/Governance), as well as any domestic and international laws governing participation in a US-based 501(c)(3) nonprofit board. + +### Election timeline + +The updated timeline of the election is planned as follows, with a deadline to receive ballot applications for the End of Day (EoD), Anywhere on Earth (AoE), November 24, 2024, and a deadline to vote for the end of day on December 13, 2024. + +| Stage | Date | Event | +|------------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Stage I | November 8 | Announcement of election date and first call for candidates. | +| Stage II | ~~Nov 22~~ Nov 24 | Deadline to receive [candidacy applications](https://wiki.sugarlabs.org/go/Oversight_Board/2025-2026-candidates#Candidates) and [ballot applications](https://forms.gle/48F6h5wdV6BpSro66). | +| Stage III | November 27 | Ballots to be sent by email. If you do not receive your ballot by the following day, please email <elections@sugarlabs.org>. | +| Stage IV | December 13 | Deadline to vote. | +| Stage V | December 19 | Election results announced. | + +### Election method + +After doing research on various [election software recommended by the FLOSS community](https://github.com/sugarlabs/elections-research), we have decided to use [bettervoting.com](http://bettervoting.com). The software is licensed under the AGPLv3, and the system supports automatic runoff vote tallying. Our internal research on the system can be found in [this document](https://docs.google.com/document/d/1kuXXL-tVgB1Ptu50cTonWtRnAuKmWn1jyKd1qPgqFJY/edit?tab=t.0). + +Again, we encourage you to take the first step and apply for a ballot via our [application form](https://forms.gle/48F6h5wdV6BpSro66), and we look forward to your involvement. +`,za=Object.freeze(Object.defineProperty({__proto__:null,default:he},Symbol.toStringTag,{value:"Module"})),ge=`--- +title: "Today, help Sugar Labs continue to transform education" +excerpt: "Sugar Labs Executive Director Devin Ulibarri shares the organization's vision and growth plans, highlighting achievements and requesting community support through donations to expand their educational initiatives." +category: "COMMUNITY NEWS" +date: "2024-12-03" +slug: "help-sugar-labs-continue-transform-education" +author: "Devin Ulibarri" +description: "Executive Director" +tags: "fundraising,donations,education,nonprofit,growth,community,technology,open-source" +--- +<!-- markdownlint-disable --> + +**Shared recently on our [mailing list](https://buttondown.com/sugarlabs), Sugar Labs executive director Devin Ulibarri shares his dreams for the organization and how you can help us at this critical moment in our growth.** + +Hello, + +Sugar Labs is at a critical inflection point. We need your support to leverage some important opportunities to grow. + +Consider [donating to Sugar Labs](https://www.paypal.com/donate?campaign_id=NEAV3YL4H6B5S) as we move into our next phase. + + +*The Sugar Labs community is a global network of students, teachers, and developers.* + +I stepped into the executive director position in January of this year. I did so because I believe in Sugar Labs's mission to create educational software and experiences for children. + +I also believe in its approach—giving kids the *license* to learn, through free/libre/open (FLO) source software, as well as the *means* to learn through its community of learners and teachers working together to create a fun, safe, and welcoming *learn-by-doing* environment. + +Based on my own experience as an educator for more than twenty years, I truly believe this organization has the potential to be a positive, disruptive force in education. + +Sugar Labs has a history that dates back almost two decades, with methods (e.g. LOGO, constructionism, project-based learning) that date back more than half a century. + +Yet, as an independent nonprofit, the organization itself is basically a startup. Having left our former umbrella organization Software Freedom Conservancy in 2020, we must now take on the challenges inherent to growing our own organization. + +This independence brings challenges, such as finding stability and resilience. It also means, however, that we have an opportunity to build the kind of organization that truly serves our mission. I want to invite you to join us at this pivotal moment. + +At the time of its founding more than sixteen years ago, Sugar Labs ran exclusively on one platform, created for One Laptop Per Child (OLPC), which was put into the hands of over three million children in over thirty-five countries. + +Since that time, Sugar Labs has strategically expanded its scope and renewed its relevance. One way that we've accomplished this is by making the platform available on more devices through Sugar on a Stick (SoaS), maintained as a Fedora "Spin," and Raspberry Pi (RPi)—the latter for which [we made notable improvements over the summer](https://youtu.be/EW0b5OkxXVs). + +We also created web-based applications such as Turtle Blocks, Music Blocks, and Sugarizer, which can run on any computer, regardless of operating system. + +Music Blocks, in particular, has received recognition as an innovative tool for exploring music and programming. + +Perhaps most notably, the Japanese government provided two years of funding to create a version of Music Blocks specifically to help Japan's elementary school students learn programming. + +Additionally, Music Blocks was also part of a large-scale deployment of seven-hundred thousand tablets by the Peruvian Ministry of Education. + +This year I've spent time ensuring that our finances are stronger and more transparent than ever before. I did this so that charitable donations can be made with confidence, ultimately helping every financial contribution we receive go further. + +I won't go into all the details here, but one thing I did is to update and publish our 990s to our website. + +All of our tax filings are now up to date and published on [sugarlabs.org/donate](https://www.sugarlabs.org/donate/) under "Our 990 tax filings." + +I also helped Sugar Labs secure in-kind services that help our daily operations at no cost to us. + +This year, we received Open Source Credits from Amazon Web Services (AWS) that are helping us test and develop new educational software; we received over one-hundred terabytes of data storage through Google Workspace for nonprofits; and we received other in-kind services that are helping us run our organization more efficiently. + +I also started a series of live events online where past and current contributors and students have a platform to tell their stories, as well as to invite guests from other organizations to discuss the future of technology-in-education. + +I did this because, although Sugar Labs's impact is somewhat obvious to the many who are active in the community, I've found that there are still many untold stories from community members whose lives are impacted positively. + +As I've continued to speak to members of the community and published their stories, I've found that these previously untold stories continue to affirm the important role Sugar Labs plays in education. + +For example, in [one of my interviews with Ibiam Chihurumnaya](https://youtu.be/JLsUiVzZ5Z0), Ibiam shares how the Sugar Learning Platform and the Sugar community introduced him and his classmates to programming from a young age and has given him skills he continues to use to this very day. + +As for our work this summer, Sugar Labs participated in our fourteenth Google Summer of Code (GSoC) to assist students to work on eleven projects. + +This, combined with our first-ever participation in Code4GovTech's Dedicated Mentorship Program (DMP), advanced our software development, mentoring a total of fourteen students who worked an estimated five-thousand hours on projects spanning the gamut from *Maintaining and Porting Twelve Activities to Flatpak,* to creating new math games, to creating promising new generative-AI services for both teachers and learners. + +To get a better sense of all that we accomplished this summer, you are encouraged to watch the *Finale* series of students' presentations on our [YouTube channel](https://www.youtube.com/@SugarlabsOrg-EN). + +We're proud of the work we've done so far this year. Yet, we know that we can do even more. + +For example, in order to publicly deploy the five generative-AI services we created this summer, we'll need additional computational resources. + +We understand that using resources on "AI" may seem like a luxury at this point in time, but we're persuaded that gen-AI will remain as a mainstay technology, and we owe it to our students to assist them in understanding and navigating this technology in a way that empowers them. + +Plus, we've already created prototypes, such as an assistant for lesson plan creation and a bot to assist with learning the basics of programming in Python, that we have found to be helpful for our students to learn and cultivate important skills and new ways of looking at the world. + +Just as we did when we created web-based software to run on any system or computer, we understand that we'll need to offer learning opportunities in gen-AI in order to stay current and relevant in an ever-evolving landscape. + +That said, we haven't compromised on our fundamental values. + +All of the services we created over the summer are licensed under a FLO license, allowing for freedom and full transparency so that learners can explore these systems at whatever level satisfies their curiosity. + +And, of course, we design our software so that students are empowered to create with these tools and build a portfolio of their work. + +All of these projects are exciting for us, and we hope that you're excited about them, too. + +However, in order to successfully implement all these projects—plus the myriad grants that I've written, and continue to write—*we must expand our capacity as an organization*. And, in order to increase our capacity, we need to raise funds to hire more staff. + +I dream of the day that we have a team of at least ten staff dedicated to assisting schools with their deployments and curricula, conducting ongoing research on how our tools are being used, helping with ongoing software maintenance, and running daily operations. + +Having these sorts of resources would help us achieve learning outcomes for students and their teachers. + +And it would also free up our volunteer community to focus on what they love about Sugar Labs: working on innovative projects under knowledgeable mentors to build and learn new skills. + +We have set an initial goal for this fall of $25k to grow in our second year of operations. + +Can you help us in this goal by contributing $3 or more? Your tax-deductible contribution will help us increase our capacity to continue to create innovative tools for learning, together with teachers and learners. + +**[Donate to Sugar Labs today](https://www.paypal.com/donate?campaign_id=NEAV3YL4H6B5S)** + +Donate today: [https://www.paypal.com/donate?campaign_id=NEAV3YL4H6B5S](https://www.paypal.com/donate?campaign_id=NEAV3YL4H6B5S) + +We are hopeful for the future in large part because we've accomplished so much in the past. + +We couldn't have gotten to where we are today without the contributions of hundreds of supporters over the years, both financial and volunteer efforts. + +We continue to be a unique, positive community and a wonderful place where **youth can solve authentic tasks and learn by doing**. + +Looking toward the next three to five years, we want to amplify all the great things in our community—mentorship, learning software, emphasis on problem solving is welcome and encouraged. + +Your contribution can help us expand our reach, and it can help us do so much more. + +From the bottom of my heart, thank you for reading this message and thank you for your time and consideration. + +Sincerely, +Devin Ulibarri +Executive Director, Sugar Labs Inc. + +P.S. Visit [https://www.sugarlabs.org/donate/](https://www.sugarlabs.org/donate/) to donate to, and support, our mission today!`,Ua=Object.freeze(Object.defineProperty({__proto__:null,default:ge},Symbol.toStringTag,{value:"Module"})),me=`--- +title: "Board election results announcement: Three new members for the 2025-26 cycle" +excerpt: "The election results for the Sugar Labs Board of Directors have been announced. Devin Ulibarri, Sumit Srivastava, and Sebastian Silva will serve on the board for the 2025-26 cycle." +category: "COMMUNITY NEWS" +date: "2024-12-19" +slug: "board-election-results-2025-26" +author: "Devin Ulibarri" +description: "Executive Director" +tags: "elections,governance,board,community,leadership,voting" +--- +<!-- markdownlint-disable --> + +# The results for the 2025-26 Sugar Labs board cycle have been determined. + +The votes have been counted, and the [results](https://bettervoting.com/dp3xc7/) for the [2025-26 Sugar Labs board cycle](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) have been determined. + +The winners are **Devin Ulibarri, Sumit Srivastava, and Sebastian Silva**. They have all been notified and have agreed to serve on the Board of Directors for the 2025-26 cycle. For this election, we used [bettervoting.com](https://bettervoting.com) after doing research on various voting systems. Please read our [original election announcement](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) for more information on how we decided upon this voting system. + +The new members of the board will be filling the seats of two outgoing board members, **Lionel Laské and Alex Perez**, and one vacant seat. + +The next election for three seats to the **2026-27 cycle** is planned for **August of next year**. All Sugar Labs members may vote, and members can: +- Run for election to the Board of Directors +- Vote in the elections for the Board of Directors +- Suggest referenda + +As indicated in the [Sugar Labs Inc. bylaws](https://wiki.sugarlabs.org/go/Sugar_Labs/Governance), anyone with "significant and sustained" contributions to Sugar Labs is eligible for membership. If you believe you qualify for membership based on this criteria and are interested in [becoming an official member of Sugar Labs](https://wiki.sugarlabs.org/go/Sugar_Labs/Members), you are encouraged to send an email to <members@sugarlabs.org>. + +If you were a member in the past but [did not vote in this election](https://www.sugarlabs.org/community/2024/11/22/elections-extension/), you will need to reapply for membership in order for your membership status to be reinstated. *(If you voted in this election, no further action is required.)* Registering for membership early will help ensure that you will be ready for the next election. + +If you are interested in volunteering to assist with the next election in 2025, please contact <volunteering@sugarlabs.org> with your interest. + +On behalf of the [Sugar Labs Board of Directors](https://www.sugarlabs.org/leadership/), we offer a big **Thank you!** to all who participated in this year's election. +`,Fa=Object.freeze(Object.defineProperty({__proto__:null,default:me},Symbol.toStringTag,{value:"Module"})),pe=`--- +title: "Reflections as Parents and Teachers Sugar at home and in their classroom" +excerpt: "Sugar Labs Executive Director Devin Ulibarri shares personal experiences using the Sugar Learning Platform both as a parent with his son and as an educator in various classroom settings." +category: "SUGAR STORIES" +date: "2024-12-25" +slug: "reflections-as-parents-and-teachers-sugar-at-home-and-in-classroom" +author: "Devin Ulibarri" +description: "Executive Director" +tags: "education,parenting,classroom,sugar-activities,learning,teaching,literacy,programming" +--- +<!-- markdownlint-disable --> + +**Reflections as a parent and teacher: Sugar at home and in the classroom** +As the year comes to a close, I wanted to take some time to reflect upon how I've used Sugar both in the classroom and at home. I have a few hopes in mind as I share my experience engaging with Sugar both as a teacher and a parent. One hope is that it will show a window into some of the more grounded work Sugar Labs has done this year. + +Much of the most recent testimony that we've shared from the [Sugar Labs community](/@sugarlabs) has been centered around software development. While the success of students creating software is certainly important, the purpose of such progress is grounded in helping teachers teach and to help learners learn. Another hope is that the following vignettes will dispel doubts around the efficacy of the Sugar Learning Platform as an effective tool for education, which I've heard from a few folks during conversations throughout [my first year as Sugar Labs's executive director](https://www.sugarlabs.org/press/2024/05/08/Sugar-Labs-announces-nonprofit-status-new-executive-director/). This article will address those doubts directly. My third hope is that my experiences will inspire others, whether parents or teachers (or both), to try Sugar themselves. + +## The first few years as a parent + +My son Kai was born in 2017, but it was about three years before his birth that I became involved in Sugar Labs. It's a story that I've told in more depth before, but I became interested in Sugar Labs because of their unique approach to education. At the time, I was doing research on the _implications of software-freedom-in-education_, which led me to conclude that the freedoms granted to users in free/libre/open (FLO) source software have [profound positive implications for education](https://wiki.sugarlabs.org/go/File:Education-needs-free-software.pdf). I attended a talk given by Sugar Labs founder Walter Bender, and we soon began working together to integrate music into [Turtle Blocks](http://activities.sugarlabs.org/en-US/sugar/addon/4027), in what is now known as [Music Blocks visual programming language](https://www.sugarlabs.org/music-blocks/). It was also around this time in 2014 that I received a One Laptop Per Child (OLPC) laptop from Walter that I used to familiarize myself with the Sugar Learning Platform. + +Although I had shown Kai a few things on the OLPC when he was a toddler, such as creating a paint program for him in the Turtle Blocks Activity, it wasn't until he was about four years old that he really took to it. His first, most sustained, interest in the computer came when he was learning to read by himself. I remember that his desire to read was basically insatiable. In fact, he had memorized some sections of the graphic novel series _Dog Man_ by [Dav Pilkey](https://en.m.wikipedia.org/wiki/Dav_Pilkey), which I had read to him multiple times because he loved it so much. At four years old, Kai had memorized a lot of the story, but he wasn't yet reading himself; he was still dependent on others to read for him. It was at this point that he found the [Speak Activity](http://activities.sugarlabs.org/en-US/sugar/addon/4038) on his OLPC, and this is when he had a real breakthrough with reading. + + +*Kai, with his OLPC, running the Speak Activity on the Sugar Learning Platform.* + +The basic way that the Speak Activity works is by taking typed input from a user and speaking it back to them when they press return. I remember Kai walking around the house, finding words on various things around the house, typing those words into the computer, and listening to the result. It was in this way that he memorized the spelling of a few words, and, soon enough, he was creating sentences and telling the computer to speak those words back to him (or to me). It was also around this time that we went on a long family road trip, where Kai sat in the back seat typing various words and sentences and learning more and more about language. + + +*Kai, helping one of my students get up and running in Sugar for her first time.* + +Of course, I kept reading books to him, which is still invaluable to a child's development, but I am confident that the Speak Activity helped Kai become a more independent reader. The following year, Kai entered Kindergarten, where he learned phonics and he's been a solid reader ever since. He's now in second grade, and he often carries a few books around with him every day, everywhere he goes. + +## Reflections as a teacher in 2024 + +This year, I had a few memorable moments as a teacher in the classroom. This year, I mentored high school students in git version control, mentored another teacher in leading a Music Blocks class, and I even taught a group class for kids ages five and six on the Sugar Learning Platform. I'll share a little bit of what I learned from each experience here. + + +*Students in a Music Blocks class led by Rafael Moreno, who I guide as a teacher new to teaching programming.* + +Before the summer, I reached out to an acquaintance, Neil Plotnik, who teaches cybersecurity at a nearby high school. I [met Neil during my time at the Free Software Foundation](https://www.fsf.org/blogs/community/free-software-in-education-and-free-software-education) (FSF). He suggested that I reach out to the Computer Science (CS) teacher at his high school. Long story short, I spent a few weeks getting these youth ready to help with coding, mainly teaching them how to use git version control. These students had done a few coding projects at their school, but hadn't yet contributed to a community project. They hadn't used git before, which is important to know for software development (and the underlying concepts are important skills for any endeavor), so I spent most of the time showing them the basics. To be honest, I was a little bit surprised to find myself teaching git to a CS class, but I suppose this highlights one of the many reasons why an organization such as Sugar Labs is important. Sugar Labs offers pathways into collaborative software development that textbook coding exercises do not. + +Over the summer, I mentored a few contributors for Google Summer of Code (GSoC). A lot of this work is online, on our Medium blog and our YouTube channel. At the same time, however, I also worked with a student of mine, Nathan, who asked to have some internship experience over the summer. I've taught this particular student for almost ten years now. He's taken guitar lessons with me, and he's taken Music Blocks classes with Walter Bender and myself. First, I asked him to create some fun projects for kids, which he did with gusto. You can read about his projects here: [https://musicblocks.net/2024/08/05/nyc-interactive-subway/](https://musicblocks.net/2024/08/05/nyc-interactive-subway/) and [https://musicblocks.net/2024/07/18/sitar-tabla-and-tampura-for-makey-makey/](https://musicblocks.net/2024/07/18/sitar-tabla-and-tampura-for-makey-makey/). Then, I asked him to create lesson plans, which he also did very well. And then, near the end of the summer, I involved him with testing some of the latest development for Music Blocks, which included a few [AI projects](https://www.youtube.com/playlist?list=PLyTz5XRZyi-xR5NGo1fHLbYJYo2OwRFta). Testing these required that he set up a development environment, test the software as a user, and report the results as issues on GitHub. His work over the summer marked a good amount of growth and progress, which continues to this day. + + +*Nathan, testing new features for Music Blocks.* + +At the beginning of the school year in the fall, I began mentoring a fellow teacher who is leading a Music Blocks class on a weekly basis. I provide the teacher, Rafael Moreno, guidance in lesson planning and feedback on classes. Rafael is a singer from Panama, now living in Boston, MA, working as a teaching artist. + +Also in the fall, I started teaching kindergarten and first grade students in a weekly computer class. This class happens at the same time as Rafael teaches Music Blocks. We decided to split the group by age, and I decided that my (younger) group would benefit most from doing something a little more open ended and basic. So, for the first day, I prepared some OLPC laptops for the kids, and I had them just try the Speak Activity. They had a blast. At one point, I tried to show them another Activity, but they insisted on continuing with the Speak Activity. The following week, we had a new student and I didn't have more than two OLPCs, so I prepared two Thinkpad X1s with Sugar Toast installed for the new student and for Kai, who joined us that day to show the group what else the computers could do. Kai did a wonderful job leading this second day of classes, and it was heartwarming to see him share his knowledge with his new friends in the class. As of now, I've taught this class for a few months, and the kids have explored several of the Activities, including [Maze](http://activities.sugarlabs.org/en-US/sugar/addon/4071), [Write](http://activities.sugarlabs.org/en-US/sugar/addon/4201), [Chat](http://activities.sugarlabs.org/en-US/sugar/addon/4069), [Turtle Blocks](http://activities.sugarlabs.org/en-US/sugar/addon/4027), and several of the [games](http://activities.sugarlabs.org/en-US/sugar/browse/type:1/cat:60). At the end of each class, the kids are asked to share with the class what they're working on. And, on the last day of class before the break, they presented their work to their parents. + + +*Two of my students, smiling during their second class, using the Sugar Learning Platform on two OLPCs.* + +One of the things that strikes me the most from this particular class is the _joy_ that the kids show as they're working on their activities. It reminds me of a study I read by Bloom, described in Robert J. Trotter's article for _Psychology Today_, July 1986, "The Mystery of Mastery". Studying how people achieve mastery, Bloom observed a few common factors among those who became experts as adults. The children who later became experts were introduced to the field as a playful activity, and learning at this stage was "like a game." As for Sugar, the kids in my class are learning a lot of things in the class, such as spelling, typing, and language, but the playfulness they exhibit is developmentally appropriate. This is consistent with the research on human development, and I've found it to hold true during my own work in the classroom. + + +*Here are the notes I took in college that I used to reference the above paragraph. I add it here because I no longer have access to the original article, and I could not find a copy online. If you find a link to a electronic copy, please drop it into the comments below.* + +## Conclusions + +As I alluded to earlier, I have sometimes heard criticism of the Sugar Learning Platform, suspecting that it may be out of touch with the needs of the students. The criticism is typically accompanied by an argument that youth should be preparing for job skills by using a platform more similar to what an office worker uses (e.g. _Shouldn't the kids be taught how to use Microsoft Word instead?_). However, as an educator, I've never bought that argument. And now that I've spent ten years with Sugar — both as an educator and as a parent — I wholly reject it. I can say confidently that youth learn very important skills through their engagement with Sugar. And perhaps most importantly, they are introduced to concepts in stages that are appropriate to their development. + + +*One of the students in my Sugar class. She surprised me by coming in with this hand-drawn computer, which she made just a few days after taking one of her first classes.* + +I'm more proud than I ever have been to be a part of the Sugar community, and my decades' long experience with youth from ages five through college, only gives me stronger conviction that we're creating something of unique value for education.`,Na=Object.freeze(Object.defineProperty({__proto__:null,default:pe},Symbol.toStringTag,{value:"Module"})),be=`--- +title: "The Sweet Spot – Issue 002" +excerpt: "The second issue of Sugar Labs' newsletter covering recent updates, events, volunteer opportunities, and community news from December 2024." +category: "COMMUNITY NEWS" +date: "2024-12-29" +slug: "the-sweet-spot-issue-002" +author: "Devin Ulibarri" +description: "Executive Director" +tags: "newsletter,community,updates,elections,social-media,volunteer,outreach,education" +--- +<!-- markdownlint-disable --> + +# Recent news for December 29, 2024 + +Welcome to the second issue of the **"Sweet Spot"**, a newsletter for Sugar Labs-related news in development, student and teacher work, events, how to get involved, and other news and information. This newsletter will be published semi-regularly for now, but the plan is to publish it on a bi-monthly, perhaps even monthly, basis in the future. Our aim with this newsletter is to help keep the growing body of Sugar Labs contributors on the same page, all while documenting our growth for our own and others' reference. + +These first issues are meant to set a precedent of communication and documentation, as well as to help inform the community of our current status, recent progress, and future plans. Its predecessor is the [Sugar Digest](https://lists.sugarlabs.org/archive/community-news/), which still serves as an important catalog of our activities. Like Sugar Digest, this newsletter is intended to keep community members in the loop about everything going on within Sugar Labs. It will highlight any recent publications from us. It will occasionally include links to third-party news and updates that our community finds relevant. + +--- + +## Updates + +### Today, help Sugar Labs continue to transform education + +**December 3, 2024** + + +*Your donation helps us in many ways.* + +Sugar Labs is in the middle of a campaign to raise funds necessary for outreach, software development, project maintenance, mentorship, and more. Having left Software Freedom Conservancy in 2020, this year is the first that Sugar Labs is investing financially in its own growth, and we'd love to have your participation in this pivotal moment. We've been particularly heartened to see volunteers in our community assist with various aspects of this campaign, such as making improvements to our website. You may also participate in our fundraiser, while getting something nice for yourself or a loved one, by purchasing Sugar Labs merchandise from our new store on Bonfire. + +Read executive director Devin Ulibarri's letter to the community to learn more about the work we've done this year, consider making a donation or purchasing merchandise, and please help spread the word. + +- [Learn more about our work](https://www.sugarlabs.org/community/2024/12/03/help-SL-continue-to-transform-education/) +- [Donate now](https://www.paypal.com/donate?campaign_id=NEAV3YL4H6B5S) +- [Visit the new donation banner](https://www.sugarlabs.org/) +- [Get Sugar Labs merchandise](https://www.bonfire.com/sugar-labs-education/) + +--- + +### Sugar Labs election information and results + +**December 19, 2024** + +Sugar Labs completed an election for three seats to its Board of Directors for the 2025–26 cycle. The results are out, and the winners are **Devin Ulibarri, Sumit Srivastava, and Sebastian Silva**. Read the articles to learn more about Sugar Labs's election process and how you can prepare to participate in the next election. + +- [Election results](https://www.sugarlabs.org/community/2024/12/19/election-results/) +- [Elections extension](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) +- [How to participate](https://www.sugarlabs.org/community/2024/11/08/fall-board-elections-how-to-participate/) + +--- + +### Sugar Labs expands its social media presence to Bluesky and WhatsApp + +**December 9, 2024** + +Sugar Labs is now on **Bluesky** and **WhatsApp**. Sugar Labs continues to maintain a presence on X (formerly Twitter), Facebook, Mastodon, Instagram, YouTube, LinkedIn, and GitHub. We decided to join Bluesky and WhatsApp in an effort to expand our reach. For those active on any of these platforms, please follow Sugar Labs to help our outreach efforts. + +- [Marketing announcement](https://lists.sugarlabs.org/archive/marketing/2024-December/004160.html) + +**Newly joined social media platforms:** +- [Follow us on Bluesky](https://bsky.app/profile/sugarlabs.bsky.social) +- [Reach out on WhatsApp](https://wa.me/16177024088) + +--- + +### Reflections from Constructing Modern Knowledge 2024 + +**November 27, 2024** + +Sugar Labs executive director and Music Blocks co-maintainer **Devin Ulibarri** attended **Constructing Modern Knowledge (CMK)**. In this post, Ulibarri shares his experience at the teacher institute, what he learned, and what it could mean for Sugar Labs. + +- [Read Devin's reflection on Medium](https://medium.com/@sugarlabs/reflections-from-constructing-modern-knowledge-2024-1ce7d60fbb1c) + +--- + +### James Simmons's Sugar Story: Writing new Activities and sharing Sugar with youth + +**September 3, 2024** + +Sugar Labs community member **James Simmons** shares his story about his involvement with Sugar Labs. Simmons tells us how he began contributing to the Sugar Learning Platform by expanding the functionality of the Read Activity and adding support for e-texts. + +- [Read James's story](https://medium.com/@sugarlabs/james-simmonss-sugar-story-writing-new-activities-and-sharing-sugar-with-youth-9282c66f9219) +- *Make Your Own Sugar Activities!*: + - [English (Internet Archive)](https://archive.org/details/MakeYourOwnSugarActivities) + - [Spanish (Internet Archive)](https://archive.org/details/ComoHacerUnaActividadSugar) +- [See all of James's Activities](https://activities.sugarlabs.org/en-US/sugar/user/45) + +--- + +## (Volunteer) Help wanted + +Sugar Labs is seeking volunteer assistance in various areas. If you are passionate about our mission and can commit time, we encourage you to apply. + +- [Help Wanted wiki](https://wiki.sugarlabs.org/go/Help_Wanted) +- [Watch volunteer appeal](https://www.youtube.com/watch?v=W5ZLFBZkE34) + +--- + +## Upcoming events and meetings + +**Regular meetings:** + +- **Music Blocks meetings**: Every Sunday at 7:00 EST (12:00 UTC) + [Join on Jitsi](https://meet.jit.si/ResponsibleMasksForecastHastily) +- **Sugar Activity meetings**: Every Wednesday at 7:00 EST (12:00 UTC) + [Join on Jitsi](https://meet.jit.si/ResponsibleMasksForecastHastily) +- **Sugar Labs Board of Directors meetings**: Every Wednesday at 14:30 EST (19:30 UTC) + [Join on Matrix](https://matrix.to/#/#sugar:matrix.org) + +--- + +## About Sugar Labs + +**Sugar Labs®** is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology for youth. Volunteers work together to develop activity-focused software for children. + +Support Sugar Labs by donating at [www.sugarlabs.org/donate](http://www.sugarlabs.org/donate/). + +--- + +## Social and Communication Links + +Stay connected with Sugar Labs on the following platforms: + +- [Bluesky](https://bsky.app/profile/sugarlabs.bsky.social) +- [Facebook](https://www.facebook.com/SugarLabsforall/) +- [GitHub](https://github.com/sugarlabs) +- [Instagram](https://www.instagram.com/sugarlabsforall/) +- [LinkedIn](https://www.linkedin.com/company/sugar-labs) +- [Mailing lists](https://wiki.sugarlabs.org/go/Mailing_Lists) +- [Mastodon](https://mastodon.social/@sugar_labs) +- [Matrix](https://matrix.to/#/#sugar:matrix.org) +- [Medium](https://medium.com/@sugarlabs) +- [Twitter/X](https://twitter.com/sugar_labs) +- [WhatsApp](https://wa.me/16177024088) +- [YouTube](https://www.youtube.com/@SugarlabsOrg-EN) + +--- + +## Back issues of "The Sweet Spot" + +Find this issue and past issues at: [sugarlabs.org/community-news](https://www.sugarlabs.org/community-news/) +`,qa=Object.freeze(Object.defineProperty({__proto__:null,default:be},Symbol.toStringTag,{value:"Module"})),fe=`--- +title: "Get and gift Sugar: Purchase new Sugar on a Stick USBs" +excerpt: "Sugar Labs now offers pre-installed Sugar on a Stick USB drives for purchase, making it easier for educators and supporters to use and share our educational software." +category: "COMMUNITY NEWS" +date: "2025-01-21" +slug: "get-and-gift-sugar-soas-usbs" +author: "Devin Ulibarri" +description: "Executive Director" +tags: "products,merchandise,SoaS,USB,education,fundraising,open-source" +--- + +<!-- markdownlint-disable --> + +A few times in recent months, we received questions from folks about how to buy Sugar. Until now, the only response we had was that we didn't offer them for sale but that you could [create your own by following our instructions](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick/Installation). If you wanted to [run Sugar on a Stick](https://www.sugarlabs.org/booting-soas/), you had to flash a USB drive yourself before using it. + +Of course, flashing a USB can be a great educational experience, and this will remain an option. However, what we heard from people asking this question was that they wanted a few things that they couldn't get from flashing a USB themselves. + +One is that they wanted the **convenience—and added assurance—of purchasing a USB from a reputable vendor**. Another is that some people were expecting something **branded with the Sugar Labs logo**. For some, it may be the ability to **gift a USB** for a friend or teacher. And, for the majority who reached out to us, it seemed that they wanted a way to **pay us for the software**, and, in so doing, **help sustain our work for years to come**. + +Well, we're excited to share the news that you are **now able to purchase a Sugar Labs-branded USB with Sugar on a Stick pre-installed!** + + +*Samples of two USBs with Sugar on a Stick pre-installed. All profits from purchases will go to Sugar Labs to help develop current and future learning projects.* + + +We partnered up with USB Memory Direct for this particular offering. USB Memory Direct (UMD) has a history of supporting [free/libre/open source projects such as ours](https://www.sugarlabs.org/about-us/). They will also be handling inventory and shipping & handling, which means that we at Sugar Labs can keep focusing on what we do best: create learning software for education! Plus, UMD will give **all profits from sales to Sugar Labs**, which we will use to further our mission in Constructionist education. + +Now that we have both clothing merchandise and SoaS USBs for purchase, we created a new [product page](https://www.sugarlabs.org/product/). + +- 🧁 [Buy Sugar on a Stick (SoaS) USBs](https://www.usbmemorydirect.com/store/novelty/sugarlabs/) +- 👕 [Buy Sugar Labs clothing merch](https://www.bonfire.com/store/sugar-labs-merch/) + +Detailed product information and specifications are on the respective landing pages. + +If you purchase a USB or clothing merchandise, **please let us know about it!** You can either [contact us](https://www.sugarlabs.org/contact-us/) directly, or you can create a post on social media with the hashtag [#SugarLabs](https://mastodon.social/tags/sugarlabs) for us to find. + +📹 And if you create a video of your experience on YouTube, let us know and we can add it to [our Sugar on a Stick playlist](https://www.youtube.com/playlist?list=PLyTz5XRZyi-xuPdS7kReqP5Nu5TAlTu4f). + +We love hearing from you! +`,Ha=Object.freeze(Object.defineProperty({__proto__:null,default:fe},Symbol.toStringTag,{value:"Module"})),ye=`--- +title: "2024 Annual Report" +excerpt: "A comprehensive overview of Sugar Labs' accomplishments, activities, and financial status throughout 2024, including development projects, outreach efforts, classroom implementations, and community growth." +category: "COMMUNITY NEWS" +date: "2025-03-24" +slug: "annual-report-2024" +author: "Devin Ulibarri" +description: "Executive Director" +tags: "annual-report,education,gsoc,outreach,classroom,finance,development,community" +--- +<!-- markdownlint-disable --> + +# Annual report for 2024 + +This report is meant to be an overview of the work Sugar Labs did in 2024. Looking back, we did a lot of work. We participated in events in the US and India. We mentored more than a dozen students over the summer for Google Summer of Code and the Dedicated Mentorship Program, the latter of which we participated in for the first time last year. + +We launched a series of online videos to showcase our work to the public while simultaneously giving a platform for young contributors to reflect upon their progress and be introduced to a larger developer community. We created a handful of entirely new software projects for learning, such as new math games and Sugarizer activities. We improved our existing software—implementing new features, fixing bugs, and making our learning software available on more platforms. We did all this and more in 2024, which I detail below. + +In many aspects, this report is highly personal. I share about my own journeys to conferences, photos of the people I met, and the students to whom I introduced Sugar. In 2024, I became Sugar Labs's first full-time staff member, which helped me fully dedicate myself to many aspects of the organization. We were also able to sponsor community members like Anindya Kundu to represent Sugar Labs internationally. + +As you read this report, please understand that the vision for Sugar Labs as a nonprofit organization is to grow to be able to support more and more people like myself, so we can have an even wider reach. That said, Sugar Labs, being a free/libre/open source community-driven project, makes its tools available to the public under free licenses, so anyone may use what we've created to support teachers and classrooms in their communities, regardless of their "status" within the organization. + +In other words, Sugar Labs is *not* a one-man-band. Instead, it's a community of orchestras and ensembles. The organization is meant to support those orchestras and ensembles, comprised of teachers and learners, listening to and responding to their needs. + +It is my hope that 2025's annual report includes even more stories and photos from the broader Sugar Labs community. Sugar Labs welcomes your interest, support, and contributions. I encourage you to join our community of teachers, learners, and parents working together to create better tools and a supportive environment for learning. + +I hope the annual publication of our work in the form of an executive summary will serve as a benchmark as we work toward continuous self-improvement as a nonprofit dedicated to serving our community of teachers and learners. + +## Development in 2024 + +### Google Summer of Code (GSoC) and Dedicated Mentorship Program (DMP) + +As for our work this summer, Sugar Labs participated in our fourteenth Google Summer of Code (GSoC) to assist students in working on [eleven projects](https://www.sugarlabs.org/press/2024/05/01/Sugar-Labs-receives-eleven-contributor-projects-for-GSoC-2024/). This, combined with our first-ever participation in Code4GovTech's Dedicated Mentorship Program (DMP), advanced our software development, mentoring a total of fourteen students who worked an estimated five thousand hours on projects ranging from maintaining and porting twelve activities to Flatpak, to creating new math games, to promising new generative-AI services for both teachers and learners. + +To get a better sense of all that we accomplished this summer, you are encouraged to watch the Finale series of students' presentations on our YouTube channel at [https://www.youtube.com/@SugarlabsOrg-EN](https://www.youtube.com/@SugarlabsOrg-EN). + +We also encourage you to check out the work in more detail by reading the reports published on Medium: + +- [https://medium.com/@sugarlabs/list/google-summer-of-code-d90eae4b54fb](https://medium.com/@sugarlabs/list/google-summer-of-code-d90eae4b54fb) +- [https://medium.com/@sugarlabs/list/code4govtech-3377e03c6dd5](https://medium.com/@sugarlabs/list/code4govtech-3377e03c6dd5) + +## Outreach and communications + +### Online events + +In 2024, I started a series of live events online where past and current contributors and students have a platform to tell their stories, as well as invite guests from other organizations to discuss the future of technology in education. + +I did this because, although Sugar Labs's impact is obvious to many in the community, I've found that there are still many untold stories from community members whose lives have been impacted by our work. Publishing these stories has continued to affirm the important role Sugar Labs plays in education. + +For example, in [my interview with Ibiam Chihurumnaya](https://youtu.be/JLsUiVzZ5Z0), he shared how the Sugar Learning Platform and community introduced him and his classmates to programming from a young age and gave him skills he continues to use to this day. + +### Expanded social media presence + +Last year, we expanded our presence on social media. In addition to Facebook, Instagram, YouTube, and LinkedIn, we are now on Bluesky, WhatsApp, and my personal favorite, Mastodon. + +If you are on any of these platforms, please follow Sugar Labs and boost our posts to support our outreach. If you're interested in helping with our outreach, join our marketing mailing list and express your interest: [https://lists.sugarlabs.org/listinfo/marketing](https://lists.sugarlabs.org/listinfo/marketing). + +### Reboot of regular newsletters + +In 2024, we relaunched regular newsletters, now sent approximately once every three months. These newsletters share our progress as an organization and news valuable to our community: + +- [https://www.sugarlabs.org/community/2024/09/20/sweet-spot/](https://www.sugarlabs.org/community/2024/09/20/sweet-spot/) +- [https://www.sugarlabs.org/community/2024/12/29/sweet-spot-002/](https://www.sugarlabs.org/community/2024/12/29/sweet-spot-002/) + +### Newsletter email subscription + +Our newsletters are published to the website and also sent via email. In 2024, we started using Buttondown to send newsletters to subscribers worldwide. If you're not subscribed yet, please do so: [https://buttondown.com/sugarlabs](https://buttondown.com/sugarlabs). + +### Reboot of Sugar Stories + +In 2024, we began collecting stories from our community. While it's still early, we've already received some fantastic articles. + +- From [James Simmons](https://activities.sugarlabs.org/en-US/sugar/user/45): [Helping others to create their own Sugar Activities](https://www.sugarlabs.org/stories/2024/09/13/Writing-new-Activities-and-sharing-sugar-with-youth/) +- From me: [Reflections as Parents and Teachers](https://www.sugarlabs.org/stories/2024/12/25/Reflections-as-Parents-and-Teachers-Sugar-at-home-and-in-their-classroom/) + +You can read these and more at: [https://www.sugarlabs.org/sugar-stories/](https://www.sugarlabs.org/sugar-stories/) + +If you have a story, share it via [info@sugarlabs.org](mailto:info@sugarlabs.org) or through the mailing lists: + +- Education: [https://lists.sugarlabs.org/listinfo/iaep](https://lists.sugarlabs.org/listinfo/iaep) +- Development: [https://lists.sugarlabs.org/listinfo/sugar-devel](https://lists.sugarlabs.org/listinfo/sugar-devel) + +### Major improvements to our website + +Throughout 2024, I worked on updating our website, which needed attention. Being unfamiliar with Jekyll (the framework it's built on), I struggled at first, but with help from the free software community, I learned enough to begin publishing updates more regularly. + +Near the end of the year, more folks from the development community pitched in. Now, the site is in much better shape, and we are working toward a completely revamped version set to launch in April 2025. + +Thanks to the many volunteers who helped! Interested in joining the web team? Visit [https://matrix.to/#/#sugarlabs-web:matrix.org](https://matrix.to/#/#sugarlabs-web:matrix.org). + +### Conference talks + +In 2024, we sent representatives to a few in-person conferences. With limited budget, we focused on visibility, sending me to several conferences in the US and sponsoring Anindya Kundu to represent us at the Opportunity Open Source Conference at IIT Kanpur. + +### - LibrePlanet + +In May, I attended the Free Software Foundation's annual LibrePlanet conference in Boston, MA. There, I [handed out flyers](https://mstdn.io/@codewiz/112384505018899979) and showed off a computer running the Sugar Desktop Environment. + + +*Devin Ulibarri and FSF executive director Zoë Kooyman, in front of the FSF office in Boston, MA. The FSF hosts the annual Libre Planet conference.* + +### - 2024 Micro Camp + +In June, I spent a weekend at a 2024 Micro Camp, a retreat for microtonal musicians, where I showcased the Music Blocks visual programming language. Music Blocks, a flagship Sugar Labs project, has rich microtonal capabilities. I showcased those features during one of the first talks of the retreat, and I even used Music Blocks as a musical instrument to perform a piece of music that requires twenty-two divisions of the octave—something for which I did not have a capable physical instrument, except for [a programmed instrument I created within Music Blocks](https://musicblocks.sugarlabs.org/index.html?id=1719093905649087&run=True). + +At the conference, I was also pleasantly surprised to meet so many free/libre/open source developers and educators. A large percentage—much larger than at most music conferences—were developing software. In retrospect, it makes sense that there are so many microtonalists who develop software, because these musicians typically need to create instruments that play pitches differently from what you would find in most stores, and they use both physical and digital mediums to craft such unique instruments. + + +*Music Blocks has many affordances for tuning and temperament, an important concept in music. The program in this screenshot performs a 22 equal-divisions-of-the-octave (EDO) pitch whenever you touch one of the mice.* + + +*Devin (at right) performs a piece, written in 22 EDO, together with an ensemble using Music Blocks on a tablet.* + + +*The ideas that inspire Music Blocks come from musical concepts, instruments, and traditions. Devin (at left) performs together with composer and microtonalist Kite Giedraitis.* + +### - CMK + +In July, I attended Constructing Modern Knowledge (CMK), a retreat for teachers, in Manchester, NH. This retreat is a good fit for Sugar Labs as it is focused on Constructionism. CMK brings together passionate educators from around the world to work on new and creative projects, which they bring back to their respective schools. + + +*Gary Stager is the organizer of CMK, a retreat for teachers to work together on Constructionism projects.* + + +*CMK participants are expected to work in groups create a project. On the final day, each group presents their project.* + + +*The 2024 CMK brought two esteemed individuals working in music education, Tricia Tunstall (left) and Melissa Walker* + + +*Devin (at left) collaborated with Jamie Chelel (MIT) to create lego notation for the blind.* + + +*Devin and Jamie created a simple and detailed notation system as a starting point to explore lego as a music notation system for the blind.* + + +*CMK attracts many passionate instructors. Devin (far left) had the pleasure of working together with Josh Burker (left), Tracy Rudzitis (right) and many others.* + +You can read my full article on the experience, as well as work done toward creating a system for using Lego blocks to encode musical data, here: +[https://medium.com/@sugarlabs/reflections-from-constructing-modern-knowledge-2024-1ce7d60fbb1c](https://medium.com/@sugarlabs/reflections-from-constructing-modern-knowledge-2024-1ce7d60fbb1c). + +### - FOSSY 2024 + +In August, I attended FOSSY, hosted by the Software Freedom Conservancy, in Portland, OR. I gave a talk titled "[Mentoring youth: The FOSS strategy we've been looking for](https://2024.fossy.us/schedule/presentation/202/)". You can watch the talk on our YouTube channel at +[https://www.youtube.com/watch?v=mKBXSC9Veq8](https://www.youtube.com/watch?v=mKBXSC9Veq8). + +I also ran two Birds of a Feather sessions. One was a Music Blocks workshop, where Bryan Ollendyke of [HAX](https://hax.psu.edu/) tested the limits of the JavaScript editor in Music Blocks. The other was a free/libre/open (FLO) music concert, where I joined [Aaron Wolf](https://blog.snowdrift.coop/author/wolftune/), [Timmy Barnett](https://gnulinux.love/), [Kite Giedraitis](https://tallkite.com/), and others to showcase [FLO](https://wiki.snowdrift.coop/about/free-libre-open) through instruments, software, and a variety of music. + + +*Music Blocks has an export to Javascript feature, which got the attention of Bryan Ollendyke, creator of HAX.* + + +*Music Blocks is a waypoint not a destination. That's why we offer learners the option to export to Lilypond, MIDI, and Javascript.* + + +*At FOSSY, Devin gave one talk and led two Birds of a feather sessions. One session was for Music Blocks, and the other was a music concert.* + + +*Sugar Labs Google Code-In mentor and Libre Learn Lab director Mariah Villarreal (left) has dedicated her career to STEAM education and free software.* + + +*Free software volunteer Jason Self attended FOSSY.* + + +*Bryan Ollendyke (left), creator of HAX, and his son attended the Music Blocks workshop at FOSSY.* + + +*Devin performed together with microtonalist Kite Giedraitis at FOSSY.* + + +*There were many "FLO musicians" at FOSSY. Among the musicians who performed in the concert who also gave a talk were Aaron Wolf of Snowdrift (2nd from the left), Timmy Barnett (third from left), and Devin Ulibarri (2nd from the right).* + + +*After the concert, audience members got a chance to play the instruments. Alternate tuning on the Linnstrument is made possible thanks to free/libre/open (FLO) source software, an important concept for Sugar Labs.* + +### - Internet-in-a-box demonstration + +Also in August, I attended a meetup to demonstrate [Internet-in-a-box](https://internet-in-a-box.org/) (IIAB), led by [Adam Holt](https://github.com/holta). Kids and teachers got an opportunity to see what IIAB does and to try it. [Sugarizer](https://sugarizer.org/), the web-based version of the Sugar Learning Platform, is among the packages chosen for IIAB, which empowers schools to use learning services that would otherwise require an internet connection. + + +*Internet-in-a-Box (IIAB) is a solution for communities that do not have internet access. It acts as a server with educational software and services pre-installed.* + + +*Sugarizer is one of the programs that comes pre-installed on IIAB.* + +### - GSoC Mentor Summit + +Sugar Labs has participated in GSoC almost every year since 2009. This year, we worked on a number of projects. I was sent to represent Sugar Labs at the conference, hosted at Google headquarters. I met with other mentors, attended talks, and gave a lightning talk on our unique approaches to mentoring. + + +*Sameer Verma (at left) is the organizer for OLPC San Francisco and has documented some of Sugar Labs's growth over the years in the form of interviews.* + + +*Karen Sandler (at right) is the executive director for Software Freedom Conservancy, which acted as fiscal sponsor Sugar Labs until 2019.* + + +*Google hosts many orgs and many, many mentors for GSoC every year. Devin is at lower-left.* + +### - Opportunity Open Source Conference at IIT Kanpur + +Sugar Labs was invited to present at the Opportunity Open Source Conference at IIT Kanpur. We sponsored community member and Music Blocks v4 maintainer, Anindya Kundu, to represent our organization. Anindya presented his journey in Sugar Labs through a talk titled *"The 'build to learn' guide for Google Summer of Code and beyond."* + + +*Former GSoC participant and Music Blocks v4 maintainer Anindya Kundu represented Sugar Labs at the Opportunity Open Source Conference at IIT Kanpur in August.* + +Comment on, like, and share the original post: <https://www.instagram.com/p/C_S_ccSRlFR/> + +Interested in representing Sugar Labs at a conference? Please reach out to us at [info@sugarlabs.org](mailto:info@sugarlabs.org) for presentation feedback and handout materials. + +### - Boston Code Camp + +Sugar Labs Executive Director Devin Ulibarri and board member Walter Bender led a session for [Boston Code Camp on November 23, 2024](https://www.bostoncodecamp.com/CC37/Schedule/SessionGrid) titled *"Create musical code with Music Blocks"*, where they introduced Music Blocks to an audience of educators and technologists. + + +*Devin Ulibarri (at left) and Walter Bender (at right) have been working together on Music Blocks since its start in 2014.* + + +*Devin and Walter presented Music Blocks at Boston Code Camp in November.* + +## Sugar Labs in the Classroom + +### Music Blocks + +This year marked significant progress in research and development for the Music Blocks visual programming language. Alongside the development work done during GSoC over the summer, I explored every opportunity to bring the new features to students, teachers, and classrooms. + +I collaborated with one of my students, Nathan, who has studied music with me for about a decade and has also taken over a year of Music Blocks classes directly from Walter Bender. Together, we tested the new AI features, such as MIDI import, as well as experimental features like music transcription and lesson plan generators. + +During the same period, I worked closely with teachers who were preparing innovative Music Blocks lessons. They provided valuable feedback by reporting bugs and suggesting new feature requests based on their classroom experiences. + + +*Nathan (at back) has studied with Devin for ten years. Over the summer, Nathan came in regularly to test new Music Blocks features that were being developed as part of Google Summer of Code.* + + +*Two instructors for a summer camp at MAP Family Learning Center worked together to create lessons for different themes, such as Egypt, Spain, and India. One instructor is primarily a programmer, the other is a Berklee-trained musician.* + + +*One of the projects for GSoC was a LLM-enabled lesson plan generator. Nathan (at right) and I tested it as we were helping the instructors create lesson plans for five weeks of summer classes.* + + +*Nathan was eventually recruited to help the instructors create lesson plans. He utilized his knowledge and understanding of both music and programming to create projects for the students.* + + +*Nathan created unique projects for Music Blocks, which are now uploaded to the Planet. He had to debug both the music and the logic in order to make his projects work.* + + +*Lesson plans created by Nathan and the two teachers were used over the summer. The students had a great time, and we received important feedback to improve Music Blocks.* + +### Sugar Learning Platform and Sugar Activities + +In the fall, I began teaching a small group of kindergarten and first-grade students using the Sugar Learning Platform. We started with a few One Laptop Per Child (OLPC) laptops and later transitioned to newer hardware. The students quickly fell in love with their computers — calling the chat robot their "robot friend" — and eagerly created art, composed music, and played educational games. + +Our sessions covered a variety of topics, from spelling to problem-solving. The foundation we built early on eventually led to the students learning to program using Turtle Blocks. The class is ongoing, and it has been both a joy for the students and an insightful experience for me. + +Additionally, my time in the classroom has allowed me to provide valuable feedback to developers for future improvements to the platform. + + +*Devin ran "Sugar classes" for kindergarten and second grade in the fall.* + + +*The students in Devin's class expressed much joy as they explored the tools in Sugar.* + + +*Soon after the computers were introduced to the students, one student brought in her own computer. She had drawn a computer with a monitor and keyboard, modeled after her experience using Sugar.* + + +*Devin's son Kai (at right) helped the students in their first weeks.* + + +*At first, the computers took some getting used to. Now, the students understand the basics.* + + +*The students had a blast learning together with the Sugar Learning Platform.* + +### Teaching Git to Students of Everett High School + +In the spring, a couple of teachers at a local high school approached me about training their students in collaborative software development practices. I met with the students twice and followed up with them via email and group chat to support their learning journey. +Together, we covered the basics of Git version control, using the command line, and making their first contributions to our repositories. It was a rewarding experience that gave the students practical skills and an introduction to open source collaboration. + + +*The high school students were eager to contribute. Contributing to free/libre/open source projects like Sugar Labs typically requires version-control collaborative tools like git.* + + +*Devin (at left) met with the students of Everett High School two times to get them started as contributors for Sugar Labs.* + +## Finances + +Last year, I spent time working on our finances — where we keep our money, which platforms can be used to donate to our organization, and increasing the number of financial tools available to us. I did this work primarily to ensure that charitable donations can be made with confidence, ultimately helping every contribution we receive go further. + +One of the major improvements I made to increase financial transparency was updating and publishing our 990 tax filings. All of our tax documents are now up to date and publicly available on our [donations page](https://www.sugarlabs.org/donate/) under the section "Our 990 tax filings." + +In addition, I helped Sugar Labs secure in-kind services that directly support our day-to-day operations at no cost. This year, we received: + +- **Open Source Credits from AWS**: These credits are helping us test and develop new educational software. +- **Over 100 terabytes of data storage** through Google Workspace for Nonprofits. +- **Other in-kind services** that allow us to run more efficiently and at a lower cost. + +Lastly, I laid the groundwork for accepting financial contributions through a wide variety of platforms, including ACH, stocks, and even cryptocurrency. We were also added to the PayPal Giving Fund, which makes us discoverable through multiple corporate donation programs. Employers can now support Sugar Labs via Benevity, and all these channels are now live as of 2025 — a result of the foundational work completed in 2024. + +### Ways to Give + +- [every.org/sugar-labs](https://www.every.org/sugar-labs) +- [Benevity Causes](https://causes.benevity.org/causes/840-843289298) +- [MyGoodness by Benevity](https://mygoodness.benevity.org/community/cause/840-843289298/donate) +- [PayPal Giving Fund (for businesses)](https://www.paypal.com/us/fundraiser/charity/4357440) +- [Our Donations Page (up-to-date list)](https://www.sugarlabs.org/donate/) + +### In-kind Donations + +We received eleven ThinkPads (X1 Yogas) from Beacon Communities, LLC in April. These laptops feature touchscreens — a particularly useful feature for children — and have been used to teach both Sugar Activities and Music Blocks effectively. + + +*Trisquel is a distribution of GNU/Linux that offers a version for download that has the Sugar Learning Platform as its default.* + + +*The computers were received near the end of the school year, so the obvious way to test them out was to let the kids play with them.* + + +*The donated computers helped us train teachers and interns to use Music Blocks.* + + +*These nine computers are now property of Sugar Labs. They've been used since we've received them to teach Sugar and Music Blocks, as well as to test new code created by GSoC participants.* + + +*All of the donated laptops have touchscreens.* + + +*Students are able to interact with the computers via touch and with a mouse. They also ahve headphones they can use to hear sounds from the computers.* + +### AWS Open Source Credits + +In 2024, we applied for and were awarded **open-source credits worth $8,000** from Amazon Web Services (AWS). These credits will help us continue testing and developing the large language model (LLM) and neural network services we worked on over the summer. + +### New Sugar Labs Merchandise for Sale + +We added a fun twist to our fundraising efforts last year! Inspired by the community reaching out with questions like *"How can I buy Sugar?"*, we launched a variety of branded merchandise. + +We now offer: + +- **Clothing items** – Hoodies and t-shirts in a range of colors. +- **SoaS (Sugar on a Stick) USBs** – Bootable drives ready for use. + +To minimize overhead and simplify logistics, we partnered with two trusted vendors: + +- [**Bonfire**](https://www.bonfire.com/store/sugar-labs/) for apparel +- [**USB Memory Direct**](https://www.usbmemorydirect.com/) for USB drives + +All proceeds directly support Sugar Labs' mission to create educational software based on Constructionist learning principles. + + +*USB Memory Direct partnered with us to sell and distribute USBs with Sugar on a Stick (SoaS) pre-installed.* + + +*In 2024, we started a merchandise store through Bonfire.* + + +*The test package came with smarties and a sticker. The USB was tested and proven to work as expected.* + + +*Our store on Bonfire offers a range of colors and styles.* + +*To view and purchase our merchandise, please go to: +[https://www.sugarlabs.org/products/](https://www.sugarlabs.org/products/).* + +*Read more about the launch of our products: +[https://www.sugarlabs.org/community/2025/01/21/SoaS-USB-announcement/](https://www.sugarlabs.org/community/2025/01/21/SoaS-USB-announcement/).* + + +--- + +## 2024 Accounting Details: Revenue and Expenses + +In 2024, Sugar Labs reported a **net loss of $62,629.28**. + +### Revenue: +- **Total**: $7,872.86 + +### Expenses: +- **Total**: $70,502.14 + +#### Top Expenses: +1. Payroll: $45,136.99 +2. Contractor expenses: $9,978.19 +3. Taxes: $6,356.05 +4. Legal & accounting fees: $2,793.00 +5. Travel (conferences): $2,792.66 +6. Conference fees: $1,345.00 +7. Other (mail, marketing, insurance, government fees, web hosting): $2,100.25 + +#### Revenue Sources: +1. Google: $6,700.00 +2. Donations\\*\\*: $786.05 +3. Interest (US Bank checking account): $350.57 +4. Bonfire merchandise sales: $36.24 + +\\*\\*Note: We use the cash accounting method. Donations sent in 2024 but not deposited until 2025 are not reflected here. + +### In-Kind Donations + +In addition to financial income, we received **$8,000 in AWS Open Source Credits** in Fall 2024, which we plan to use to test the tools developed during GSoC. + +--- + +## Membership + +In 2024, we made one significant change to how membership is maintained. In preparation for our annual election, we required community members to reapply for membership to ensure active participation, as our [bylaws](https://wiki.sugarlabs.org/go/Sugar_Labs/Governance) require a majority vote from members for some decisions. + +Aside from this participation requirement, the eligibility criteria remain unchanged: + +> "Any 'significant and sustained' contributor to Sugar Labs is eligible for membership... Contributions may be code, documentation, translations, maintenance of project-wide resources, running a Sugar deployment, or other non-trivial activities which benefit Sugar Labs." + +If you're an active contributor — technical or non-technical — we encourage you to [apply for membership](https://wiki.sugarlabs.org/go/Sugar_Labs/Members). Membership gives you the right to vote in board elections and other key decisions. + +--- + +## Election + +Sugar Labs held its annual **Board of Directors election** in 2024. The results, announced on **December 19, 2024**, elected the following three individuals for the 2024–2025 term: + +- **Devin Ulibarri** +- **Sumit Srivastava** +- **Sebastian Silva** + +Learn more about the process and outcomes here: + +- [How to participate in board elections (Nov 8)](https://www.sugarlabs.org/community/2024/11/08/fall-board-elections-how-to-participate/) +- [Elections extension notice (Nov 22)](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) +- [Final election results (Dec 19)](https://www.sugarlabs.org/community/2024/12/19/election-results/) + +--- + +## Management and Board + +In 2024, [Devin Ulibarri was appointed Executive Director](https://www.sugarlabs.org/press/2024/05/08/Sugar-Labs-announces-nonprofit-status-new-executive-director/). Alongside his leadership, our membership also voted in three new board members, as noted in the section above, including one seat that had been previously vacant.`,Ka=Object.freeze(Object.defineProperty({__proto__:null,default:ye},Symbol.toStringTag,{value:"Module"})),we=`--- +title: "The Sweet Spot – Issue 003" +excerpt: "Recent news from Sugar Labs including Sugarizer v1.9 release, annual report for 2024, contributor stories, and more community updates." +category: "COMMUNITY NEWS" +date: "2025-03-31" +author: "Devin Ulibarri" +tags: "markdown,parser,test,education,post,aigenerated" +--- +<!-- markdownlint-disable --> + +*Recent news for March 31, 2025* + +Welcome to the third issue of *The Sweet Spot*, a newsletter for Sugar Labs-related news in development, student and teacher work, events, how to get involved, and other related news and information. + +## Contents of this issue + +- Sugarizer v1.9 is available for your device +- Annual report for 2024 +- From beginner to number one on the contributors chart: My open-source journey +- Devin Ulibarri: How Sugar Labs empowers education via FLOSS +- Enhancing Sampler widget with drag and drop +- Sugar Labs is a mentoring organization for GSoC 2025 +- Two new ways to donate: Every.org and Benevity +- My open-source journey with Sugar Labs +- Volunteers wanted +- Upcoming events and meetings +- About Sugar Labs +- Social and communication links +- Back issues of *The Sweet Spot* + +--- + +## Updates + +### Sugarizer v1.9 is available for your device +**March 25, 2025** + +Sugarizer maintainer Lionel Laské has announced a new release of the multi-platform clone to Sugar Learning Platform. This release includes: + +- A new 3D volume activity (developed during GSoC) +- Improved stability +- A new "direct launch" feature to auto-start an activity on Sugarizer launch + +Check out the full details: + [Release notes](https://lists.sugarlabs.org/archive/sugar-devel/2025-March/059881.html) + [Try it live](https://try.sugarizer.org/) + +[youtube: r5yamM5j7rk] + +--- + +### Annual report for 2024 +**March 24, 2025** + +The newly released **Annual Report for 2024** includes highlights of our work in: + +- Software development +- Sugar in classrooms worldwide +- Outreach and conferences +- Preliminary financials + +Read the report: [Annual report – 2024](https://www.sugarlabs.org/community/2025/03/24/annual-report/) + +--- + +### From beginner to #1 on the contributors chart +**March 21, 2025 – by Om Santosh Suneri** + +Om shares his incredible journey from being new to open source to topping the contributors chart for Music Blocks. In his blog, he discusses his contributions, early learnings, and advice to newcomers. + +Read the full article: + [My Open-Source Journey](https://medium.com/@omsuneri/from-beginner-to-1-on-the-contributors-chart-my-open-source-journey-a0c4d07e1818) + +--- + +### 🎓 Devin Ulibarri: How Sugar Labs empowers education via FLOSS +**March 12, 2025 – by Max Roveri** + +In an interview with Linux Professional Institute, Devin Ulibarri dives into: + +- Sugar Labs' mission +- FLO (Free/Libre/Open) values +- Challenges in scaling +- Future goals for growth and mentorship + + [Read the Interview](https://www.lpi.org/blog/2025/03/12/devin-ulibarri-how-sugar-labs-empowers-education-via-floss/) + +--- + +### Enhancing Sampler widget with drag and drop +**March 6, 2025 – by Harshit Verma** + +New contributor Harshit Verma upgraded the Music Blocks Sampler widget. You can now drag and drop sound samples directly into the browser to generate code. + + [Enhancement details](https://musicblocks.net/2025/03/06/enhancing-sampler-widget-with-drag-and-drop-support-to-add-samples-music-blocks/) + +--- + +### Sugar Labs is a mentoring organization for GSoC 2025 +**February 28, 2025** + +Sugar Labs will mentor students in this year's **Google Summer of Code**! + + Explore our project ideas + Submit proposals by **April 8th, 18:00 UTC** + + [Mastodon announcement](https://mastodon.social/@sugar_labs/114083771631725400) + [Project Ideas](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md) + [Mailing List post](https://lists.sugarlabs.org/archive/sugar-devel/2025-March/059892.html) + +--- + +## Volunteers wanted + +We're growing and need **volunteer support** in various areas—tech, outreach, design, documentation, and more. + +If you're curious and committed, email us: [info@sugarlabs.org](mailto:info@sugarlabs.org) + Learn more: [Volunteering at Sugar Labs](https://www.sugarlabs.org/volunteering) + +--- + +## Upcoming events and meetings + +### Special Event +**New website launch party** + April 25, 2025 at 13:00 EDT / 17:00 UTC + [YouTube Stream](https://www.youtube.com/watch?v=v76Mw9wqO6E) + +### Regular Meetings +**Music Blocks Weekly Meetups** + Every Sunday – 7:00 EDT / 11:00 UTC + [Join here](https://meet.jit.si/ResponsibleMasksForecastHastily) + +--- + +## About Sugar Labs + +Sugar Labs® is a US-based 501(c)(3) nonprofit dedicated to creating educational tools that promote technology exploration and learning for youth globally. + +Support our work: [Donate here](https://www.sugarlabs.org/donate/) + +--- + +## Social and Communication Links + +- Bluesky: [@sugarlabs.bsky.social](https://bsky.app/profile/sugarlabs.bsky.social) +- GitHub: [github.com/sugarlabs](https://github.com/sugarlabs) + +--- + +## Back issues of *The Sweet Spot* + +Find this and previous issues at: + [Sugar Labs Community News](https://www.sugarlabs.org/community-news/) +`,Va=Object.freeze(Object.defineProperty({__proto__:null,default:we},Symbol.toStringTag,{value:"Module"})),ve=`--- +title: "Live Session: Role of generative AI in education" +excerpt: "Join us with guest speaker Ken Kahn, PhD for a live session on the role of generative AI in education" +category: "EVENTS" +date: "2025-05-16" +slug: "role-of-generative-ai-education" +author: "Sugar Labs" +description: "Education Nonprofit" +tags: "gen-ai,education,live-session,guest-talk" +--- +<!-- markdownlint-disable --> + +**Join us live with researcher and author Ken Kahn, PhD for a live session on the role of generative AI in education. Watch live on Friday, May 16, 2025 at 13:00 EDT (17:00 UTC).** + +## Event information + +- **Title:** Live Session: Role of generative AI in education +- **Date:** May 16, 2025 +- **Time:** 13:00 EDT (17:00 UTC) +- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=nn1jeQgKTOA) +- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) + +## About Sugar Labs + +Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology to youth around the world. Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating the need for source code to be published publicly for study, licensed under a free/libre license for explicit permission to share and remix, and openly worked upon within a community where students are invited to make contributions, under guidance of experienced mentors. + +Support our work: [Donate here](https://www.sugarlabs.org/donate/) +`,Ja=Object.freeze(Object.defineProperty({__proto__:null,default:ve},Symbol.toStringTag,{value:"Module"})),ke=`--- +title: "JavaScript Editor Updates and Future Features" +excerpt: "Overview of changes being made to the JavaScript editor tool in MusicBlocks v3, and future plans" +category: "DEVELOPER NEWS" +date: "2025-05-20" +slug: "JSeditor-updates" +author: "@/constants/MarkdownFiles/authors/elwin-li.md" +description: "GSoC Contributor" +tags: "gsoc, javaScript editor, development, contribution, debugger" +--- + +This is the first update report on the MusicBlocks JavaScript editor enhancement project for +GSoC 2025. This and future reports will discuss the progress and future plans for the improvement +of user experience and features for the editor. + +## Contents +- Upcoming Features +- Motivation +- JavaScript to Music Blocks +- Debugger +- Syntax highlighting + +--- + +### Upcoming Features +This project aims to significantly enhance the JavaScript editor within Sugar Labs' +MusicBlocks environment. By implementing translation from JavaScript code to +MusicBlocks visual blocks, users will gain a powerful tool for iterative learning and code +exploration. Additionally, the project will introduce a JavaScript visualizer for step-by-step +debugging and syntax highlighting to improve the editor's usability and appeal to young +learners. This upgrade will bridge the gap between visual programming and text-based coding, +promoting a deeper understanding of real programming and empowering kids to debug +effectively. + +### Motivation +I believe that kids cannot learn to +code without coding. Although they can learn the concept of coding through MusicBlocks, they +still cannot learn text-based coding effectively. The JavaScript-to-MusicBlocks conversion feature +will enable them to better transition between visual block-based programming and +textual JavaScript coding. This promotes a deeper understanding of programming concepts and +has kids learn them more effectively. + +Even more important than learning how to code is learning how to problem solve. Debugging and +problem solving skills provide kids with the knowledge to overcome problems of any kind, not +just in programming. With the step by step debugger, kids will learn how to break a problem down, and +identify where problems are and track them. + +### JavaScript to Music Blocks +The JavaScript to Music Blocks feature is fairly simple as an end product: implementing the ability +for users to convert the JavaScript code in the editor to music blocks. The execution of this feature +is less simple. Currently, I have implemented support for all blocks from the rhythm, flow, number, and boolean palettes. There is also support for a few blocks from the pitch, tone, and action palettes. These implementations can be seen with the [first PR](https://github.com/sugarlabs/musicblocks/pull/4591) and the [second PR](https://github.com/sugarlabs/musicblocks/pull/4692). + +This was all done using the following process: + +1. Using the [acorn parser library](https://github.com/acornjs/acorn), convert the input code by the user in the editor into an +[**Abstract Syntax Tree**](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (AST) +2. Convert the AST into a custom intermediate representation + - In this case, it is a simpler tree consisting of all the different blocks that the code creates + - For each block in the intermediate tree, there is information on its type, arguments, children, and/or value if it has one +3. Convert the intermediate tree into a blocklist + - MusicBlocks generate blocks using the representation of a list of blocks, which are mostly in the form of + [id, name, x, y, [connections]] + - Carefully parsing through the intermediate tree and dealing with the connections produce a list of such blocks, + which MusicBlocks will then load into the visual programming blocks + - The connections are made during the process of creating the blocks. + - For each block, if it has arguments, they will be created and connected with the block + - Then its children are created and connected to each other + - Finally the first child is then connected back to the block itself + - During this process, vertical sizes of arguments are kept track of to insert the necessary amount of vertical spacers before the children + +Although this process is proven to work very well as shown by the [merged PR](https://github.com/sugarlabs/musicblocks/pull/4591), +adding future blocks is not yet as simple as it can be. + +Thus, I am currently working on refactoring the code to use JSON config files to store pairs of AST to block mappings, which would +make adding new blocks an extremely quick and trivial process. The next report may go into more details on this. + +### Debugger +The JavaScript editor debugger will be a tool located as a separate tab within the console space. I plan on implementing this tool as part of GSoC this summer. Although currently unavailable, I have created a simple design as to what it may look like. + + +The debugger will have the following functionalities: + - Ability to set one or multiple breakpoints + - Have the state of all variables at breakpoints + - Show function call frames + - User can run program all the way to the next breakpoint (stops in order until user goes to next one) + - User can step forward line by line or evaluate by unit + +### Syntax Highlighting +A good IDE or code editor will always have syntax highlighting. This makes the environment easier and more fun to work with. Thus, +this feature will also be added to the JavaScript editor in MusicBlocks. Although this also has not been implemented yet, I foresee this +part of the project being the fastest, as there are many established libraries that can provide syntax highlighting. Some candidates may include highlight.js, and CodeJar. + +--- + +This concludes the first report on the MusicBlocks JavaScript editor enhancement project for GSoC 2025. Thanks for reading, and more updates will come soon!`,Xa=Object.freeze(Object.defineProperty({__proto__:null,default:ke},Symbol.toStringTag,{value:"Module"})),Se=`--- +title: "GSoC ’25 Week 01 Update by Aditya Kumar Singh" +excerpt: "Refining human anatomy models and improving Sugarizer’s 3D Human Activity" +category: "DEVELOPER NEWS" +date: "2025-05-28" +slug: "2025-05-28-gsoc-25-AdityaKrSingh26-week01" +author: "@/constants/MarkdownFiles/authors/aditya-singh.md" +description: "GSoC'25 Contributor at SugarLabs (Sugarizer Human Activity Pack)" +tags: "gsoc25,sugarlabs,week01,AdityaKrSingh26" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Aditya Kumar Singh + +**Project:** [Sugarizer](https://github.com/llaske/sugarizer) +**Mentors:** [Lionel Laské](https://github.com/llaske) +**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) +**Reporting Period:** 2025-05-12 - 2025-05-18 + +--- + +## Goals for This Week + +- **Goal 1:** Identify missing human body assets in the current execution. +- **Goal 2:** Simplify models and increase spacing between organs. +- **Goal 3:** Remove redundant code from the current codebase and improve structure. + +--- + +## This Week’s Achievements + +1. **Identify missing human body assets in the current execution** + - Reviewed current assets and mapped out missing organs and systems (e.g., stomach, intestines, food pipe, kidneys, liver, eyes, brain, etc). + - This helps ensure educational completeness and anatomical accuracy for users. + +2. **Simplify Z-Anatomy models and increase spacing between organs** + - Removed mesh clutter and enhanced spacing between vital organs like heart, lungs, liver to improve visibility and user interaction. + - This change is aimed at improving user experience, especially on touch devices. +  +  + + +3. **Remove redundant code from the current codebase and improve structure** + - Removed redundant or deprecated functions, improved file modularity, and standardized naming across \`activities\\HumanBody.activity\\js\\activity.js\`. + - Resolved duplicate \`loader.load()\` usage: Consolidated the skeleton model loading logic into a reusable function and invoked it from both \`env.getEnvironment\` and \`onNetworkDataReceived\`, removing redundancy. + - Optimized \`env.getEnvironment\` call: Now invoked only once and the result is reused where needed + - Unified zoom functions: Replaced \`zoomInFunction\`, \`zoomOutFunction\`, \`zoomEqualFunction\`, and \`zoomToFunction\` with a single parameterized \`zoomCamera(type, targetFOV)\` function to streamline logic. + - Links : PR [#1794](https://github.com/llaske/sugarizer/pull/1794). + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Code duplication across multiple model load functions and zoom handlers. + **Solution:** Abstracted the model loading into one reusable function to reduce maintenance overhead. Similarly, created a generalized zoom function with parameters for FOV and zoom type to replace multiple similar methods. + +- **Challenge:** Finding suitable 3D models with the right level of mesh detail. + **Solution:** Spent time evaluating and testing various anatomy models and 3D datasets. Balanced between model quality and performance ensuring the mesh was detailed enough for educational use but light enough for smooth rendering in Sugarizer’s environment. + +--- + +## Key Learnings + +- Got hands-on with **3D modeling tools like Blender** for optimization and export for web use. +- Understood modular design and best practices for maintaining scalable code in large open-source projects. + +--- + +## Next Week’s Roadmap + +- Refine the 3D models ,remove and merge unecessary parts. +- Integrate Organs 3D models for the basic paint activity. +- Import and test Human Body model for visual alignment. + +--- + + +## Resources & References + +- **Repository:** [github.com/AdityaKrSingh26/sugarizer](https://github.com/AdityaKrSingh26/sugarizer) +- **3D models used:** + - "Human" (https://skfb.ly/6Z8LI) by aaron.kalvin, + - "Realistic Human Lungs" (https://skfb.ly/oBDWI) by neshallads, + - "Human heart, realistic anatomical model" (https://skfb.ly/oXBxZ) by 3d Eye Catcher, + - "human-brain" (https://skfb.ly/6YqDO) by Yash_Dandavate, + - Organs by Z-Anatomy (https://github.com/LluisV/Z-Anatomy) + + +--- + + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +## Connect with Me + +- GitHub: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) +- Gmail: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) +- LinkedIn: [Aditya Kumar Singh](https://www.linkedin.com/in/adityakrsingh26/) +- Twitter: [@AdityaKrSingh26](https://x.com/AdityaKrSingh26) + +--- +`,$a=Object.freeze(Object.defineProperty({__proto__:null,default:Se},Symbol.toStringTag,{value:"Module"})),Ie=`--- +title: "GSoC ’25 Week 02 Update by Aditya Kumar Singh" +excerpt: "Merging anatomical models and enhancing Sugarizer’s Human Body Activity" +category: "DEVELOPER NEWS" +date: "2025-05-29" +slug: "2025-05-29-gsoc-25-AdityaKrSingh26-week02" +author: "@/constants/MarkdownFiles/authors/aditya-singh.md" +description: "GSoC'25 Contributor at SugarLabs (Sugarizer Human Activity Pack)" +tags: "gsoc25,sugarlabs,week02,AdityaKrSingh26" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 02 Progress Report by Aditya Kumar Singh + +**Project:** [Sugarizer](https://github.com/llaske/sugarizer) +**Mentors:** [Lionel Laské](https://github.com/llaske) +**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) +**Reporting Period:** 2025-05-19 - 2025-05-22 + +--- + +## Goals for This Week + +- **Goal 1:** Merge required segmented models into a single unified mesh. +- **Goal 2:** Integrate 3D organ models required for the initial version of the paint activity. +- **Goal 3:** Refactor and clean up code to improve maintainability of the Human Body Activity. +- **Goal 4:** Import and test a Human body model. + +--- + +## This Week’s Achievements + +1. **Merged intestine models into a single mesh** + - Used Blender to unify multiple intestine segments into a single watertight mesh. + - Simplified mesh topology while preserving anatomical details for better performance in-browser. +  +  + + +2. **Integrated 3D organ models for the basic paint activity** + - Selected essential models: heart, brain, lungs, and kidneys. + - Positioned and scaled them within the scene for the interactive paint activity. + - Confirmed interactivity through raycasting and model selection using three.js. +  +  + + +3. **Refactored and cleaned up existing code for Human Body Activity** + - Improved component structure and naming conventions in \`activity.js\`. + - PR merged: PR [#1794](https://github.com/llaske/sugarizer/pull/1794). + +4. **Imported and tested a Human body model** + - Imported an external Human body model and tested visual alignment. + - Adjusted scale, rotation, and pivot points in Blender. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Organs weren’t interacting properly in the paint activity due to non-unified object hierarchies. + **Solution:** Used grouping and bounding box checks to establish correct hit detection zones. Re-anchored object origins for each model. + +--- + +## Key Learnings + +- Improved skills in 3D mesh merging. +- Learned how to optimize **paintable 3D object interactions** within a browser canvas. +- Gained experience in **codebase refactoring for open-source projects** to enhance maintainability. + + +--- + +## Next Week’s Roadmap + +- Create a \`credits.md\` file to document and attribute all third-party 3D models used, following proper open-source licensing guidelines. +- Integrate additional organ models into paint mode to enrich the educational interactivity. +- Bisect the human body model into appropriate anatomical sections (e.g., upper/lower torso, head, limbs) for easier interaction and labeling. +- (Optional) Begin integrating the full human body model into paint mode, allowing users to interact with and label the complete anatomy structure. + + +--- + + +## Resources & References + +- **Repository:** [github.com/AdityaKrSingh26/sugarizer](https://github.com/AdityaKrSingh26/sugarizer) +- **3D models used:** + - “Z-Anatomy Human Body” (https://github.com/LluisV/Z-Anatomy) + - "Human" (https://skfb.ly/6Z8LI) by aaron.kalvin. + - Human Heart ,Lungs, etc from Sketchfab (refer Week 01 for links) + + +--- + + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +## Connect with Me + +- GitHub: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) +- Gmail: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) +- LinkedIn: [Aditya Kumar Singh](https://www.linkedin.com/in/adityakrsingh26/) +- Twitter: [@AdityaKrSingh26](https://x.com/AdityaKrSingh26) + +--- +`,Ya=Object.freeze(Object.defineProperty({__proto__:null,default:Ie},Symbol.toStringTag,{value:"Module"})),Ae=`--- +title: "GSoC '25 Week 1 Update by Elwin Li" +excerpt: "Weekly progress report for JSEditor updates" +category: "DEVELOPER NEWS" +date: "2025-06-07" +slug: "2025-06-07-gsoc-25-Elwin-Li-week01" +author: "@/constants/MarkdownFiles/authors/elwin-li.md" +description: "GSoC Contributor" +tags: "gsoc25,sugarlabs,week1,javaScript editor" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 1 Progress Report by Elwin Li + +**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/gsoc-2025/elwin) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) + +**Reporting Period:** 2025-06-02 - 2025-06-07 + +--- + +## Goals for This Week + +- **Goal:** Complete and deploy code to blocks functionality. + +--- + +## This Week’s Achievements + +**Refactored code to be config driven** +I refactored my code for code to block conversion to use a JSON config file so that the logic behind the conversion is as generic as possible. +An example config for a block is shown below: + + { + "name": "repeat", + "comments": "Repeat block in the Flow palette", + "arguments": [ + { + "type": "NumberExpression" + } + ], + "ast": { + "identifiers": [ + { + "property": "type", + "value": "ForStatement" + } + ], + "argument_properties": [ + "test.right" + ], + "children_properties": [ + "body.body" + ] + }, + "blocklist_connections": [ + "parent_or_previous_sibling", + "argument", + "first_child", + "next_sibling" + ], + "default_vspaces": { + "argument": 1 + } + } + +This config is for the repeat block, as conveniently stated in the comments section for readability. +There are several pieces of information we need for a block for the conversion code to work: +- The name of the block +- The number of arguments, and their types +- The associated AST information + - The identifiers, or the path to that block (needed for matching) + - The paths to the argument and children properties from the AST +- The connections the block has in the blocklist [parent/previous sibling, argument(s), child(ren), next sibling] +- vspace information + +Based on these pieces of information, the conversion code is generic enough to parse through and translate into blocklist format. +This is very important because this means that adding a new block for support is now as simple as adding a config like this to the JSON file. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Coming up with the config format. + + **Solution:** Lots of trial and error, and using many different examples to make the code generic. + +- **Challenge:** Argument handling was not working with configuration. + + **Solution:** Added a separate section in the config file for argument blocks, but made it as close to other blocks as possible. + +--- + +## Key Learnings + +- Deepened understanding of JSON configuration files. +- Improved skills in **debugging**, **code design**, and **collaboration workflows**. + +--- + +## Next Week’s Roadmap + +- Fully add all blocks that we want to support for code to block conversion, with corresponding documentation and error handling. +- Move on to next phase of the JSeditor project, which is the debugger +- Familiarize myself with the necessary files I will need to work with for the debugger +- Work on getting breakpoints to work + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +## Connect with Me + +- GitHub: [@ebeetles](https://github.com/ebeetles) +- Gmail: [elwin.s.li@gmail.com](mailto:elwin.s.li@gmail.com) +- LinkedIn: [Elwin Li](https://www.linkedin.com/in/elwinsli/) + +--- +`,Qa=Object.freeze(Object.defineProperty({__proto__:null,default:Ae},Symbol.toStringTag,{value:"Module"})),Le=`--- +title: "DMP ’25 Week 1 Update by Aman Naik" +excerpt: "This week's focus was exploring the write-activity codebase, finding appropriate grammar correction models & understanding Abiword documentations." +category: "DEVELOPER NEWS" +date: "2025-06-08" +slug: "2025-06-08-dmp-25-AmanNaik-week01" +author: "@/constants/MarkdownFiles/authors/amannaik247.md" +description: "Member and DMP'25 Contributor at SugarLabs" +tags: "dmp25,writeactivity,write,sugarlabs,week01,amannaik247" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 1 Progress Report by Aman Naik + +**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) +**Reporting Period:** 2025-06-02 - 2025-06-08 + +--- + +## Goals for This Week + +- **Goal 1:** Understand write activity's codebase. +- **Goal 2:** Explore pertinent grammar correction models for real time grammar correction +- **Goal 3:** Understand the [Abiword](https://github.com/AbiWord) word-processor documentation + +--- + +## This Week’s Achievements + +1. **Understood the activity's codebase** + - Gained a clear understanding of the overall structure and logic of the Write activity's codebase. + - This includes identifying key components, data flow, and how the Abiword processor is leveraged for this activity. +2. **Explored pertinent grammar correction models** + - Shortlisted grammar correction models suitable for real time grammar correction and can be used with an open source software. + - Created API endpoints using Hugging Face spaces for quick testing in sugar. + +3. **Understood the Abiword processor** + - Abiword is an open source word processor, which is leveraged by the write activity. + - It has a parser called 'link-grammar' that was recently developed, which might be useful for grammar correction as well. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Difficulty in finding reliable grammar correction models on hugging face which can also be compatible open source software. +**Solution:** Found link-grammar that could be an option for reliable grammar correction feature. Also, found some hugging face models(relevant license) after rigorously searching. + +- **Challenge:** Testing hugging face models with no inference points and testing them inside Sugar. +**Solution:** Most Hugging Face models can’t be installed directly in Sugar because they require heavy dependencies like Torch and Transformers, which increase memory usage in a virtual machine. Therefore, I used hugging face spaces and ran the models there, which also provides API endpoints for quick testing inside Sugar. + +--- + +## Key Learnings + +- Gained a solid understanding of the Write activity's code structure and how it integrates the Abiword processor. +- Explored lightweight, open-source grammar correction models and successfully tested them using Hugging Face Spaces via API endpoints. +- Discovered that Abiword’s link-grammar parser might be leveraged for native grammar correction within the activity. + +--- + +## Next Week’s Roadmap + +- Finalise a grammar correction model and fine tune it if needed +- Create a FastAPI endpoint and upload the selected model on AWS for testing +- Integrate grammar correction into write-activity +- Explore better spelling correction models + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! + +--- + +## Connect with Me + +- GitHub: [@amannaik247](https://github.com/amannaik247) +- Gmail: [amancodes247@gmail.com](mailto:amancodes247@gmail.com) +- LinkedIn: [Aman Naik](https://www.linkedin.com/in/aman-naik/) + +--- +`,Za=Object.freeze(Object.defineProperty({__proto__:null,default:Le},Symbol.toStringTag,{value:"Module"})),Te=`--- +title: "DMP '25 Week 01 Update by Anvita Prasad" +excerpt: "Improving Synth and Sample Features in Music Blocks" +category: "DEVELOPER NEWS" +date: "2025-06-08" +slug: "2025-06-08-dmp-25-AnvitaPrasad-week01" +author: "Anvita Prasad" +description: "DMP'25 Contributor at SugarLabs (Music Blocks)" +tags: "dmp25,sugarlabs,week01,AnvitaPrasad" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Anvita Prasad + +**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) +**Mentors:** [Walter Bender](https://github.com/walterbender) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-02 - 2025-06-08 + +--- + +## Goals for This Week +- **Goal 1:** Update Tone.js to the latest version +- **Goal 2:** Begin tuner implementation with pitch detection +- **Goal 3:** Create basic tuner visualization + +--- + +## This Week's Achievements +1. **Updated Tone.js Library** + - Successfully upgraded from version 15.0.4 to 15.1.22 + - Verified compatibility with existing codebase + +2. **Implemented Pitch Detection** + - Integrated YIN algorithm for pitch detection + - Established foundation for note identification + +3. **Created Basic Tuner Interface** + - Implemented 11-segment tuner display + - Added initial cents adjustment UI + +--- + +## Key Learnings +- Gained familiarity with Tone.js API and audio processing +- Learned about pitch detection algorithms and their implementation + +--- + +## Next Week's Roadmap +- Complete tuner implementation with accurate visualization +- Implement cents adjustment calculations +- Add fine-tuning to pitch detection system +- Test with various audio sources +- Write Week 02 blog post summarizing progress and learnings + +--- + +## Acknowledgments +Thank you to my mentors, the Sugar Labs community, and fellow DMP contributors for ongoing support. Had a productive meeting with mentors this week to discuss the implementation approach. + +--- + +## Connect with Me +- GitHub: [@AnvitaPrasad](https://github.com/AnvitaPrasad) +- Email: [anvita.prasad1@gmail.com](mailto:anvita.prasad1@gmail.com) +- LinkedIn: [Anvita Prasad](https://www.linkedin.com/in/anvita-prasad) +`,eo=Object.freeze(Object.defineProperty({__proto__:null,default:Te},Symbol.toStringTag,{value:"Module"})),Pe=`--- +title: "DMP ’25 Week 01 Update by Justin Charles" +excerpt: "Week 01 focused on understanding and creating the path file to render the outlines for the SVG Paths for different brick types." +category: "DEVELOPER NEWS" +date: "2025-06-09" +slug: "2025-06-09-dmp-25-justin212407-week01" +author: "Justin Charles" +description: "Member and DMP'25 Contributor at SugarLabs" +tags: "dmp25,sugarlabs,week01,justin212407" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Justin Charles + +**Project:** [Music Blocks 4 Masonry Module](https://github.com/sugarlabs/musicblocks-v4/issues/430) +**Mentors:** [Anindya Kundu](https://github.com/meganindya/) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/), [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-02 - 2025-06-08 + +--- + +## Goals for This Week + +- **Goal 1:** Figure out the constants required for building the outline of the different brick SVGs. +- **Goal 2:** Find out formulae for creation of dynamic parts for the creation of the brick outlines. +- **Goal 3:** Creating functions for rendering different brick types given a set of parameters. + +--- + +## This Week’s Achievements + +1. **Identified core constants for SVG brick outlines** + - Analyzed existing functions to extract constants and segment lengths. + - Documented fixed edge sizes and arc parameters required for rendering base brick structure. Here is the doc regarding the same - https://docs.google.com/document/d/1AUlA2leDJIfV3ZXceLhCaITftExq6c5BcUBMZOtZBvE/edit?usp=sharing +2. **Derived dynamic formulae for brick segments** + - Broke down SVG path logic to understand variable-dependent segments (e.g., based on presence of notches or arguments). + - Reverse-engineered svg paths into configurable logic blocks. + +3. **Implemented param-based render logic for brick types** + - Created functions to output valid SVG paths. + - Ensured functions deliver the correct kind of brick based on the parameters given to it. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Understanding how fixed and dynamic SVG path parts interac + **Solution:** Visually inspected path output, compared it to expected segments, and mapped patterns to conditional logic. + +- **Challenge:** Ensuring proper rendering across all brick types + **Solution:** Used example bricks for side-by-side validation; gradually modularized logic to support extensibility. + +--- + +## Key Learnings + +- Gained clarity on **brick geometry constants** and their significance in SVG construction. +- Improved ability to **translate SVG paths into conditional logic functions**. +- Strengthened understanding of **segment chaining**, **arc-to-curve translations**, and **parametric shape rendering**. + +--- + +## Next Week’s Roadmap + +- Complete the path file to begin rendering bricks dynamically via input-driven SVG generation. +- Create React components for different brick types. +- Collaborate with mentors to refine design and implementation plans. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! + +--- + +## Connect with Me + +- GitHub: [@justin212407](https://github.com/justin212407) +- Gmail: [charlesjustin2124@gmail.com](mailto:charlesjustin2124@gmail.com) +- LinkedIn: [Justin Charles](https://www.linkedin.com/in/justin-c-663840297/) +`,no=Object.freeze(Object.defineProperty({__proto__:null,default:Pe},Symbol.toStringTag,{value:"Module"})),Ce=`--- +title: "DMP ’25 Week 01 Update by Harshit Verma" +excerpt: "Week 01 focused on understanding the Pippy codebase, testing Sugar-AI endpoints, and evaluating AI models for the debugger." +category: "DEVELOPER NEWS" +date: "2025-06-09" +slug: "2025-06-09-dmp-25-therealharshit-week01" +author: "@/constants/MarkdownFiles/authors/harshit-verma.md" +tags: "dmp25,sugarlabs,week01,therealharshit" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Harshit Verma + +**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-02 - 2025-06-08 + +--- + +## Goals for This Week + +- **Goal 1:** Study Pippy codebase. +- **Goal 2:** Explore Sugar AI and test its endpoints. +- **Goal 3:** Research suitable AI models for debugging. + +--- + +## This Week’s Achievements + +1. **Studied the Pippy codebase** + - Spent time navigating through the Pippy repository to understand how activities are structured and how debugging might integrate. + - Cloned and set up the development environment locally to test and experiment changes. +2. **Tested Sugar-AI API endpoints** + - Successfully ran the FastAPI server and tested endpoints like /ask and /ask-llm. + - Validated the flow from input to model response, which sets the stage for integrating custom prompts and debugging logic. + +3. **Evaluated model options for Pippy Debugger** + - Tested Codellama and Mistral locally using Ollama, which provided quick setup and testing on my local machine. + - After discussing with my mentor, I’ve shifted focus to using models directly from Hugging Face, as it aligns better with our deployment plans and integration goals. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Understanding the Pippy codebase and its dependencies. + **Solution:** Followed documentation and explored Sugar Labs learning resources. Used Ubuntu in a virtual machine to setup sugar desktop. + +- **Challenge:** Running Sugar AI locally to test endpoints. + **Solution:** Followed the documentation to run the sever but the default model was taking too long to download so I changed it to a smaller model. + +--- + +## Key Learnings + +- Gained familiarity with the **Pippy codebase and its structure.**. +- Learned to work with **FastAPI**, **Linux** and **Virtual Machine**. +- Developed better understanding of **LLM system requirements**, **quantization**, and **local model serving**. + +--- + +## Next Week’s Roadmap + +- Create a basic FastAPI server **(/debug endpoint)** that accepts Python code and suggests debugging steps. +- Integrate the **selected LLM** to respond to debugging prompts. +- Collaborate with mentors to refine design and implementation plans. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! + +--- +`,to=Object.freeze(Object.defineProperty({__proto__:null,default:Ce},Symbol.toStringTag,{value:"Module"})),Me=`--- +title: "GSoC ’25 Week 03 Update by Aditya Kumar Singh" +excerpt: "Organ integration, anatomical bisection, and open-source attributions in Sugarizer's Human Body Activity" +category: "DEVELOPER NEWS" +date: "2025-06-02" +slug: "2025-06-02-gsoc-25-AdityaKrSingh26-week03" +author: "@/constants/MarkdownFiles/authors/aditya-singh.md" +description: "GSoC'25 Contributor at SugarLabs (Sugarizer Human Activity Pack)" +tags: "gsoc25,sugarlabs,week03,AdityaKrSingh26" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 03 Progress Report by Aditya Kumar Singh + +**Project:** [Sugarizer](https://github.com/llaske/sugarizer) +**Mentors:** [Lionel Laské](https://github.com/llaske) +**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) +**Reporting Period:** 2025-05-23 - 2025-05-29 + +--- + +## Goals for This Week + +- **Goal 1:** Create a **credits.md** file to attribute and list licenses for all 3D assets used. +- **Goal 2:** Integrate organ models into the interactive paint mode. +- **Goal 3:** Bisect the full human body model into meaningful anatomical sections using Blender. +- **Goal 4:** Time-permitting, begin integration of the bisected full-body model into paint mode. + + +--- + +## This Week’s Achievements + +1. **Created credits.md file for 3D model attribution** + - Documented sources, authors, and licenses for each 3D model used in the activity. + - Ensured compliance with open-source licensing (CC, GPL, etc.) where applicable. + + +2. **Integrated additional organ models into paint mode** + - Added 3D human organs model containing: stomach, liver, intestines, etc to the interactive paint activity. + - Verified clickable regions and ensured raycasting targets are accurate and intuitive. + - Updated model hierarchy for smoother interactivity and better scene management. + - Refactored the existing click handler for better mesh selection using **screen-space testing**. +  + + +3. **Bisected full human body model into anatomical sections** + - Used Blender’s Bisect tool to separate the full mesh into functional regions: head, torso, arms, and legs. + - Cleaned geometry to avoid overlapping or orphaned faces. + - Exported and tested the segmented meshes in the Three.js scene. +  +  +  + + +4. **(Bonus) Partial integration of bisected model into paint mode** + - Imported segmented torso and head into paint mode as a pilot test. + - Validated paint interactions on new sections to ensure consistency. +  + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Bisecting the human body mesh led to artifacts and unclean separations. + **Solution:** Used high-precision knife and cleanup tools in Blender and manually adjusted vertex groups. + +--- + +## Key Learnings + +- Improved proficiency with Blender’s mesh slicing and cleanup tools. +- Learned proper practices for open-source asset attribution. + +--- + +## Next Week’s Roadmap + +- Write Weekly Blog Post summarizing progress, screenshots, and key learnings from Week 03. +- Implement a model selection palette that allows users to toggle between different anatomical models (e.g., organs, skeleton, full body). +- Integrate the full human body model into the paint activity to allow direct interaction and labeling across complete anatomy. +- Rename labels in the skeleton model to reflect accurate anatomical terminology and improve educational clarity. +- Add localization support for the 3D Human Body Activity to make it accessible in multiple languages. + + +--- + + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +## Connect with Me + +- GitHub: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) +- Gmail: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) +- LinkedIn: [Aditya Kumar Singh](https://www.linkedin.com/in/adityakrsingh26/) +- Twitter: [@AdityaKrSingh26](https://x.com/AdityaKrSingh26) + +--- +`,ao=Object.freeze(Object.defineProperty({__proto__:null,default:Me},Symbol.toStringTag,{value:"Module"})),xe=`--- +title: "GSoC ’25 Week 01 Update by Bishoy Wadea" +excerpt: "Bonding and Four Color Map puzzle" +category: "DEVELOPER NEWS" +date: "2025-06-07" +slug: "2025-06-07-gsoc-25-BishoyWadea-week01" +author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" +tags: "gsoc25,sugarlabs,week01,BishoyWadea" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Bishoy Wadea + +**Project:** [Four Color Map Puzzle](https://github.com/Bishoywadea/Four-Color-Map) +**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) +**Reporting Period:** 2025-06-01 - 2025-06-07 + +--- + +## Goals for This Week + +- **Goal 1:** Define game features and core mechanics. +- **Goal 2:** Design and plan a child-friendly, interactive game UI. +- **Goal 3:** Implement the core game logic for map coloring and rule enforcement. + +--- + +## This Week’s Achievements + +1. **Initial Game Implementation** + - Implemented the basic game loop, event handling, and win condition detection. This created the foundation for gameplay. + - Added support for checking that no two adjacent regions have the same color. + - commit: [Gameplay Base](https://github.com/Bishoywadea/Four-Color-Map/commit/91eabce38439fc08da652d1de309b556393fcee3) + +2. **UI Enhancements & Interaction Features** + - Designed and integrated colorful buttons, icons, and zoom functionalities to make the UI more appealing to children. + - Added menu navigation for selecting countries and levels. + - Added Undo, Erase, and Help buttons for better usability. + - commit: [UI Enhancment](https://github.com/Bishoywadea/Four-Color-Map/commit/4fe1c755c47696cc20e6dd757190ed1f3df98717) + +3. **Map Data Integration** + - Generated and added regional map data for Egypt, US, Nigeria, and India. + - Developed a script to convert GeoJSON files into game-ready polygon data. + - Screenshot of gameplay: + commit: [Data Integration](https://github.com/Bishoywadea/Four-Color-Map/commit/de018722d2d32d3ebd40429f8e59e1793cd34e9c) + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Generating accurate and clean polygon data from raw GeoJSON files. + **Solution:** Wrote a custom Python script to extract, simplify, and format the regions into usable coordinates while preserving geographical structure. + +- **Challenge:** Preventing adjacent regions from being colored the same. + **Solution:** Implemented an adjacency-check function that verifies constraints during each coloring action. + +--- + +## Key Learnings + +- Gained proficiency in using **Pygame** for interactive game development. +- Improved understanding of **map projections** and **GeoJSON** parsing. +- Learned about structuring a project for open-source collaboration (commits, PRs, README, file organization). +- Practiced test-driven logic development and clean UI design tailored for children. + +--- + +## Next Week’s Roadmap + +- Checking if any bugs appears +- develop broken calculator game + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for the warm support and constant feedback during this bonding period. + +---`,oo=Object.freeze(Object.defineProperty({__proto__:null,default:xe},Symbol.toStringTag,{value:"Module"})),Ge=`--- +title: "GSoC ’25 Week 01 Update by Shubham Singh" +excerpt: "Creating UIs and visuals for addition of Lego Bricks " +category: "DEVELOPER NEWS" +date: "2025-06-07" +slug: "2025-06-07-gsoc-25-FirePheonix-week01" +author: "Shubham Singh" +description: "Maintainer and GSoC'25 Contributor at SugarLabs" +tags: "gsoc25,sugarlabs,week01,FirePheonix" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Shubham Singh + +**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) +**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-06-01 - 2025-06-07 + +--- + +## Goals for This Week + +- **Goal 1:** Basic UI for Image Upload/Real time Video upload and adjust. +- **Goal 2:** Putting the developed UIs onto the widget blocks. +- **Goal 3:** Searching for exisiting audios in the phrase maker and note blocks. + +--- + +## This Week’s Achievements + +1. **Interface for Image upload for Lego Notations** + - Music Blocks has a feature to detect the color of pixels generated from drawing within the program, but it cannot detect the color of pixels from images that are either uploaded or from a webcam. + - By adding a feature to detect color from both uploaded images and a live webcam stream, users would be able to implement Lego music notation for the blind and similarly interactive programs. + +  + + +2. **Live webcam feed and editing options** + - The following feature helps to use a real time video(webcam) onto the Lego Notation detection interface. Also, you may freely edit and move it around the canvas. +  + + - Here's the reference video regarding lego bricks as musical notes: + [youtube: LOfrCPf3XJU] + + - Here's Devin's CMK project for color sensor project in music blocks: + [Reflections from constructing modern knowledge](https://medium.com/@sugarlabs/reflections-from-constructing-modern-knowledge-2024-1ce7d60fbb1c) + +3. **Identified methods to making a new widget block in music blocks** + - I read and went through a lot of documentation, searching for how we can add a new widget block in music blocks. I figured out a few flaws and how can the documentation be improved for future contributors. +  + - From what I've realized working on it, for adding a new block on the music blocks, I definitely think that for adding a new block, a lot of the code - UIs, features, etc. would already exist and you can just inherit those exisiting classes. And also, you'll have to edit and change a LOT of files and add new methods for your own new block. +  + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Getting started on features and UIs with a lot of doubts about how it should look like. +- **Solution:** Consulting my mentors, presenting variations of "How it could be" to them, refering to EXISTING UIs in Music Blocks. + +--- + +## Key Learnings + +- Gained familiarity with **making new blocks**. +- Deepened understanding of **inheritance and code modularity** +- Improved skills in **exports, imports, code reusability**, **documentation**, and **collaboration workflows**. + +--- + +## Next Week’s Roadmap + +- Implement **mapping of musical notes to lego bricks' colors**. +- Refine **UIs** based on mentor feedback. +- Inherit the exisiting code inside **WidgetBlocks.js** code as UI. +- Target: Completing the **core implementation** in the week number 2 and 3. + +--- + +## Acknowledgments + +Thanks to some old pull requests and documentation available in music blocks, I was able to figure out on a lot about how new blocks are created on the music blocks interface. Will definitely add on more. + +--- + +## Connect with Me + +- GitHub: [@FirePheonix](https://github.com/FirePheonix) +- Gmail: [shubhsoch@gmail.com](mailto:shubhsoch@gmail.com) +- LinkedIn: [Shubham Singh](https://www.linkedin.com/in/shubham-singh-8a5643198/) +- Twitter: [@DevNinjaShubham](https://x.com/DevNinjaShubham) + +--- +`,io=Object.freeze(Object.defineProperty({__proto__:null,default:Ge},Symbol.toStringTag,{value:"Module"})),_e=`--- +title: "GSoC ’25 Week 01 Update by Mebin J Thattil" +excerpt: "Experimenting, Benchmarking and Researching" +category: "DEVELOPER NEWS" +date: "2025-06-06" +slug: "2025-06-06-gsoc-25-mebinthattil-week1" +author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" +tags: "gsoc25,sugarlabs,week01,mebinthattil,speak_activity" +image: "assets/Images/GSOCxSpeak.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Mebin J Thattil + +**Project:** [Speak Activity](https://github.com/sugarlabs/speak) +**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-02 - 2025-06-06 + +--- +## Introduction & About Me +Hey, I'm Mebin 👋🏻! I'm a first year student at PES University, Bangalore, India, currently pursuing a BTech in Computer Science. I’ve had a deep passion for tech ever since I was 10, when I first learned in a CS class that you could write a couple of lines of code and build a (barely functional) website. That simple idea sparked something in me, and over the years, my love for computer science has only grown—especially while building a bunch of cool things along the way. + +About a month ago, I launched my personal portfolio website: [mebin.in](https://mebin.in/). It runs on an 8-year-old Raspberry Pi sitting at home 🤩, so apologies in advance if the site is occasionally slow or down (power cuts are a real pain). I'll be posting a copy of these blogs there as well. Go check 'em out and a bunch of other blogs I've written there! + +I'm also building a Bluesky client in the Nim programming language. I'm a strong advocate for education in technology. In the past, I built a web application aimed at connecting students in rural areas with those in urban areas to help foster a free and open peer-to-peer learning ecosystem. + +To say that I’m thrilled to be working on the Speak Activity would be an understatement. I can’t wait for an amazing summer filled with learning, collaboration and helping enhance educational journey for millions of learners world-wide. + +--- + +## Goals for This Week + +- **Goal 1:** Benchmark and test various models and architectures. +- **Goal 2:** Evaluate the feasibility and implementation approach based on project constraints such as hardware limitations and size requirements. + +--- + +## This Week’s Achievements + +1. **Created a Streamlit benchmark app** + - A simple streamlit app was made to compare responses of different Large Language Models (LLMs) & Small Language Models (SLMs). This was done to understand which models were a good fit for our requirements. + - Links: [Streamlit App](https://llm-benchmarking-sugar.streamlit.app/), [GitHub](https://github.com/mebinthattil/LLM-benchmarking). + + +--- + +## Selection Of Models and Challenges + +- The selection of the LLM was fairly easy, as all the models in the 30-ish billion parameter range performed reasonably well without any fine-tuning. These models were _smart_ but required significant resources to run. That was fine, since the model was intended to be hosted on AWS and accessed via an API endpoint managed by Sugar-AI. +- The selection of the SLM was a bit tricky. Initially, we looked at models under 1B parameters like the Qwen3-0.6B, and the responses were hilariously bad as expected. Later, I experimented with a dual-model architecture, where one model would generate the answer and another model (or the same model with a different system prompt) would refine the answer. I tried this with the Gemma3-1B model as the generating model and the same Gemma3-1B(with a different system prompt), as the evaluation/refinement model. The results were surprisingly good! This model generated answers that were up there with the 30B parameter models! The only caveat is that it technically takes twice the time for inference, but considering the model is pretty small, it wasn’t too bad. +- That said, Gemma3-1B Instruct even after 4-bit quantization is still around 1GB in size, which is much more than we can package with the Speak activity. So now I’m going to be looking into even lighter models like TinyBERT and will update the benchmarks soon. +- Fine-tuning in the next step should hopefully improve the performance of these models as well. Considering that we also need to package the TTS model, we really need to make sure the SLM is as lightweight as possible. + +**TLDR:** +LLM selection was easy — they all perform pretty well. SLM poses some challenges. Dual-model (generation + evaluation/refinement) seems to produce much better responses. Size of the SLM needs to be reduced further (hopefully under 100MB). + + + +--- + +## Key Learnings + +- Dual model architecture (generation model + evaluation/refinement model) produces some great results, even if the individual models are very small or perform bad individually! + +--- + +## Next Week’s Roadmap + +- Setup AWS for fine-tuning the model. +- Finalize on the model to go forward with. +- Finalize on the dataset to start fine-tuning SLM with. +- Include much smaller models like TinyBert in the benchmark. +- Start fine-tuning TinyBert or any other SLM on the agreed upon dataset in the hopes to improve performance. + + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +`,ro=Object.freeze(Object.defineProperty({__proto__:null,default:_e},Symbol.toStringTag,{value:"Module"})),Ee=`--- +title: "GSoC ’25 Week 01 Update by Nikhil" +excerpt: "Implemented repository creation via GitHub App, secure key generation, and metadata integration" +category: "DEVELOPER NEWS" +date: "2025-06-08" +slug: "2025-06-08-gsoc-25-Nikhil-Bhatt-week01" +author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" +tags: "gsoc25,sugarlabs,week01,Nikhil-Bhatt" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Nikhil Bhatt + +**Project:** [Git backend for Musicblocks](https://github.com/BeNikk/git-backend) +**Mentors:** [Walter Bender](https://github.com/walterbender) +**Assisting Mentors:** [Sumit Srivastava](https://github.com/sum2it) +**Reporting Period:** 2025-06-02 - 2025-06-08 + +--- + +## Goals for This Week + +- **Goal 1:** Implement GitHub App JWT + Installation Token Authentication +- **Goal 2:** Set Up Repository Creation from Backend +- **Goal 3:** Write Metadata and Content Files to Repository +- **Goal 4:** Design Backend Folder Structure for Scalability + + +--- + +## This Week’s Achievements + +1. **GitHub App JWT + Installation Token Auth Flow Implemented** + - Created a Github app and installed it on a separate organisation account. + - Implemented JWT generation using App ID and private key. + - Fetched installation token dynamically to create repositories securely within the GitHub organization. + + +2. **Created Repositories via Backend with Files** + - Built an Express-based controller to create repositories inside the organization. + - On repository creation, wrote three files: + - \`README.md\` + - \`projectData.json\` (from frontend) + - \`metaData.json\` (containing hashed key, theme, and timestamp) + + +3. **Implemented Unique Ownership via Hashed Keys** + - Generated a random project key and stored a hashed version in metadata. + - Only the original key holder (sent to frontend) can perform future edits, ensuring project ownership. + + +4. **Structured Clean Codebase for Scalability** + - Organized backend into proper folders: \`controllers\`, \`services\`, \`utils\`, \`routes\`, \`config\`, and \`types\`. + - Made the repo production-ready with readable service-based architecture. + - Check the project at [Link](https://github.com/benikk/musicblocks-backend) + +5. **Optimized Token Management & Project Creation** + - Validated rate limits (15,000 requests/hour for GitHub App installation tokens). + - Each request generates a fresh installation token, no collisions or race conditions observed so far. + + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Writing multiple files to a new GitHub repository using Octokit caused noticeable delays +- **Solution:** Batched file uploads with asynchronous control using a loop and base64-encoded content, I plan to imrove it + by exploring GitHub’s Create a tree and commit API to upload multiple files in a single commit for performance optimization. + +--- + +## Key Learnings + +- Deep understanding of GitHub App authentication using JWT + installation tokens. +- Secure project ownership enforcement using hashing and metadata tracking. +- Octokit’s repo/file handling APIs and best practices for GitHub integrations. + +--- + +## Next Week’s Roadmap + +- Add **edit project** functionality: Only owner (with original key) can update content. +- Implement **key-based ownership check middleware** to protect sensitive routes. +- Allow users to **open GitHub issues** on created repositories via the backend. + + +--- + + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +## Connect with Me + +- GitHub: [BeNikk](https://github.com/BeNikk) +- Gmail: [bhattnik442@gmail.com](mailto:bhattnik442@gmail.com) +- LinkedIn: [Nikhil](https://www.linkedin.com/in/nikhil-bhatt-3b37a0255/) +- Twitter: [Nikhil Bhatt](https://x.com/Be_Nikkk) + +--- +`,so=Object.freeze(Object.defineProperty({__proto__:null,default:Ee},Symbol.toStringTag,{value:"Module"})),De=`--- +title: "GSoC ’25 Week 1 Update by Safwan Sayeed" +excerpt: "Kickoff of Music Blocks 4 Program Engine development" +category: "DEVELOPER NEWS" +date: "2025-06-08" +slug: "2025-06-08-gsoc-25-sa-fw-an-week1" +author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" +tags: "gsoc25,sugarlabs,week1,sa-fw-an" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 1 Progress Report by Safwan Sayeed + +**Project:** Music Blocks 4 Program Engine +**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-06-02 - 2025-06-08 + +--- + +## A Blog-style Retrospective + +Last week marked the official start of the coding phase for the Music Blocks 4 Program Engine. I spent the first few days translating our planning sessions into a concrete technical specification. Crafting the spec helped me clarify the core constructs, their key properties, and how they will map to interfaces. The early draft already feels like a solid roadmap for the engine’s evolution. + +Midweek, I teamed up with Karan Palan to begin coding the skeleton of our abstract classes. We paired on Replit to code the classes. + +--- + +## Goals for This Week + +- Draft a comprehensive tech spec detailing engine constructs, class interfaces, and example workflows. +- Implement the initial set of abstract classes in TypeScript. +- Outline AST build steps and prepare a simple program example. + +--- + +## This Week’s Highlights + +1. **Tech Specification Draft** + - Wrote the first section of the tech spec covering . + - Link: [Tech Spec Document](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.otbw6ldsc32w) + +2. **Abstract Classes Implementation** + - Started coding the core abstract classes in TypeScript alongside [Karan Palan](https://github.com/Karan-Palan). + - Link: [Replit: Engine Abstract Classes](https://replit.com/@karanpalan007/engine-abstract-classes?v=1#README.md) + +3. **AST Discussion & Planning** + - Held discussions with Anindya on AST constructs, class instantiation workflow, and example program build. + - Outlined next steps for documenting AST examples in the tech spec. + +--- + +## Challenges & Solutions + +- **Syncing Edits on Replit:** + We initially clashed on file versioning. + *Solution:* Established a clear editing schedule and used commit comments to track changes. + +- **Defining Spec Scope:** + The broad set of music constructs felt overwhelming. + *Solution:* Prioritized a core subset to include in the first draft. + +--- + +## Key Learnings + +- Mastered TypeScript abstract classes and interface patterns. +- Reinforced the importance of early design documentation. +- Gained clarity on AST building workflows through Anindya's feedback. + +--- + +## Next Week’s Roadmap + +- Finalize abstract class implementations and interfaces. +- Expand the spec with AST examples and UML class diagrams if needed. + +--- + +## Resources & References + +- **Tech Spec:** [Google Docs](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.otbw6ldsc32w) +- **Code Skeleton:** [Replit Engine Abstract Classes](https://replit.com/@karanpalan007/engine-abstract-classes?v=1#README.md) + +--- + +## Acknowledgments + +Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their continual guidance and support. + +--- + +## Connect with Me + +- GitHub: [@sa-fw-an](https://github.com/sa-fw-an) +- Email: [isafwansayeed@gmail.com](mailto:isafwansayeed@gmail.com) +- LinkedIn: [Safwan Sayeed](https://www.linkedin.com/in/safwan-sayeed-6a3a482a9/) +- Twitter: [@safwan_say](https://twitter.com/safwan_say) + +--- +`,lo=Object.freeze(Object.defineProperty({__proto__:null,default:De},Symbol.toStringTag,{value:"Module"})),je=`--- +title: "GSoC ’25 Week 01 Update by Saumya Shahi" +excerpt: "Weekly Progress Report on the Masonry Module for GSoC '25" +category: "DEVELOPER NEWS" +date: "2025-06-08" +slug: "2025-06-08-gsoc-25-saumya-week01" +author: "Saumya Shahi" +description: "GSoC '25 Contributor at SugarLabs" +tags: "gsoc25,sugarlabs,masonry,week01,saumya-shahi" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Saumya Shahi + +**Project:** [Masonry Module - Music Blocks v4](https://github.com/sugarlabs/musicblocks-v4) +**Mentors:** [Anindya Kundu](https://github.com/meganindya/) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/), [Devin Ulibarri](https://github.com/pikurasa/) +**Reporting Period:** 2025-06-01 - 2025-06-08 + +--- + +## Goals for This Week + +- Understand the working of SVGs and path rendering logic. +- Create an exhaustive list of all configurations needed to render each visual brick type. +- Formulate the path rendering logic to dynamically generate each brick. +- Implement rendering logic for SVG bricks based on the provided configurations. +- Ensure each brick type renders correctly with various parameters. + +--- + +## This Week’s Achievements + +1. **Explored SVG-based Brick Rendering** + - Used [SVG Playground](https://yqnn.github.io/svg-path-editor/) to manually draw and style bricks. + - This helped me understand SVG path syntax, positioning, scaling, and how \`viewBox\` works for consistent rendering. + - Also referred to the [MDN SVG Docs](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorials/SVG_from_scratch/Getting_started) for deeper insights into SVG internals. + +2. **Compiled a Comprehensive List of Brick Types** + - Created a detailed list of all visually distinct brick types to be supported by the Masonry module. + - This helped identify variation across different bricks and how they interact in Music Blocks. + - [Brick Types Document](https://docs.google.com/document/d/1BswWHadyy4yC3_3vK6KHZnMn0u6jbbYiQ6JQWiqRMLw/edit?tab=t.0) + +3. **Mapped Configurations for Each Brick Type** + - Listed out all the necessary configurations (similar to React props) for each brick — including label size, number of arguments, shape flags, etc. + - This configuration map allows dynamic rendering logic per brick type. + - [Configurations Document](https://docs.google.com/document/d/1UJXh3734S138BoTsGulzeTlZXstyvWd6syJK2eclMKI/edit?usp=sharing) + +4. **Implemented SVG Brick Rendering** + - Successfully implemented dynamic SVG rendering logic. + - Given a configuration, each brick now generates an accurate path representation. + - The system supports variation in label length, slot types, and layout, making the rendering pipeline fully flexible. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Brick structures vary significantly, making a one-size-fits-all rendering approach difficult. + **Solution:** Broke down commonalities across bricks and created modular rendering components that dynamically adapt based on type and config. + +- **Challenge:** Path distortion with varying argument lengths and labels. + **Solution:** Used live preview tools and console-based debugging to isolate scaling issues. The SVG path editor was extremely useful in this phase. + +--- + +## Key Learnings + +- Gained strong understanding of **SVG path syntax** and dynamic drawing. +- Improved in building **config-driven rendering pipelines** with a clean separation of data and UI logic. +- Learned how to break down complex visual requirements into **reusable, parameterized components**. +- Realized that **explaining your thought process to mentors** is invaluable — it clarifies confusion and leads to better solutions. + +--- + +## Next Week’s Roadmap + +- Work on edge cases and introduce early validation of config inputs. +- Build a **basic layout logic** that dynamically generates a SVGs for a tree of bricks (Multiple bricks rendering). +- Begin implementing **connection logic** based on bounding box / collision detection. + +--- + +## Resources & References + +- [Brick Types Doc](https://docs.google.com/document/d/1BswWHadyy4yC3_3vK6KHZnMn0u6jbbYiQ6JQWiqRMLw/edit?tab=t.0) +- [Brick Configurations Doc](https://docs.google.com/document/d/1UJXh3734S138BoTsGulzeTlZXstyvWd6syJK2eclMKI/edit?usp=sharing) +- [SVG Path Editor](https://yqnn.github.io/svg-path-editor/) +- [MDN SVG Tutorial](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial) + +--- + +## Acknowledgments + +Grateful to my mentors Anindya, Walter, and Devin for their constant guidance and insightful feedback. Thanks to the Sugar Labs community for their welcoming support! + +--- + +## Connect with Me + +- GitHub: [@saumyashahi](https://github.com/saumyashahi) +- Gmail: [saumyashahi05@gmail.com](mailto:saumyashahi05@gmail.com) +- LinkedIn: [Saumya Shahi](https://www.linkedin.com/in/saumya-shahi/) + +--- +`,co=Object.freeze(Object.defineProperty({__proto__:null,default:je},Symbol.toStringTag,{value:"Module"})),We=`--- +title: "GSoC ’25 Week 01 Update by Diwangshu Kakoty" +excerpt: "Deploying a Streamlit app for testing" +category: "DEVELOPER NEWS" +date: "2025-06-04" +slug: "2025-06-04-gsoc-25-Diwangshu-week01" +author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" +tags: "gsoc25,sugarlabs,week01,AI" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Diwangshu Kakoty + +**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [ Ajeet Pratap Singh](https://github.com/apsinghdev) +**Reporting Period:** 2025-06-01 - 2025-06-07 + +--- + +## Goals for This Week + +- **Goal 1:** Refine prompt templates and instructions for the LLM. +- **Goal 2:** Host the project on Streamlit Cloud. +- **Goal 3:** Develop Fast API endpoints. +- **Goal 4:** Find an alternative cloud-based vector database. + +--- + +## This Week’s Achievements + +1. **Fast API Endpoints** + - Although I kept this task later in my proposal but it became necessary when I wanted to deploy the project for testing purposes. The endpoints /chat and /summary are used by the client-side app when having a conversation with the user. It is working perfectly in my local development environment, but it caused an issue when I tried to host the Fast API server on [Render](https://render.com/). After several trials, I found that the embedding model I am using - 'all-MiniLM-L6-v2' is a bit heavy, and the RAM usage given by the free service is not enough. + But anyway, this is a success as we will need Fast API during the final deployment. + + +2. **Cloud based vector database - Qdrant** + - For development, I have been using ChromaDB, which is pretty good for testing and developing RAG applications locally. I have now opted to use Qdrant, which provides cloud-based vector database. It is working well with the Streamlit app. + - [Qdrant](https://qdrant.tech/documentation/) + +3. **Hosted Streamlit App** + - Because the Fast API server was not deployed, I simply wrote the RAG code in the Streamlit code itself. Now that it is hosted, mentors and contributors can test it and give feedback. + - [Streamlit app](https://reflectionapp-2yoxtvn6sknvktme2zorvq.streamlit.app/) + +4. **Refined Prompts** + - Prompt Engineering is the key to get a well structured and quality response from any LLM. I improved the instructions for the LLM to ask follow up questions to get quality answers from users. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Fast API deployment fails. + **Solution:** The overall goal was to deploy the project so that mentors can test it and give me feedback for the summer period. Therefore, I modified the streamlit code to handle the RAG application by itself. Hence, I tackled the problem by avoiding server deployment. + +--- + +## Key Learnings + +- I learned new technologies: Fast API and Streamlit. I watched tutorials on YouTube and read their documentations as well. +- Learned how API endpoints work and how to manage API keys while deploying it. + +--- + +## Next Week’s Roadmap + +- Work on things suggested by mentors. +- Improve the analysis phase. This phase of the reflection learning cycle is suppose to compare and contrast user development over a period of time. Currently it uses a hardcoded summary but it needs to be dynamic. +- Write documentation for Music Blocks. Some topics still needs to get covered. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,uo=Object.freeze(Object.defineProperty({__proto__:null,default:We},Symbol.toStringTag,{value:"Module"})),Oe=`--- +title: "GSoC '25 Community Bonding and First Week by Krish" +excerpt: "A deep dive into the GTK4 migration journey for Sugar Labs - exploring the challenges, progress, and tooling setup" +category: "DEVELOPER NEWS" +date: "2025-06-04" +slug: "2025-06-04-gsoc-25-mostlyk-community-bonding" +author: "@/constants/MarkdownFiles/authors/krish-pandya.md" +description: "GSoC'25 Contributor working on GTK4 migration for Sugar Labs" +tags: "gsoc25,sugarlabs,gtk4,mostlyk,community-bonding" +image: "assets/Images/GSOC.png" +--- + + +<!-- markdownlint-disable --> + +# Community Bonding Period Progress Report by Krish Pandya + +**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) +**Mentors:** [Walter Bender](https://github.com/walterbender) , [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky) +**Organization:** Sugar Labs +**Reporting Period:** May 15, 2025 till June 4, 2025 + +--- + +## Introduction & About Me + +Hey everyone! This is probably going to be my biggest blog post of the GSoC journey haha — and I'm excited to share my thoughts on the GTK4 migration project during the community bonding period and some work done till the first week. I will just give a short introduction— + +I'm Krish Pandya aka MostlyK, a B.Tech student in Electronics and Communication Engineering at IIITH. While my degree says ECE, I've found myself gravitating toward robotics, graphics, software , and most imporatant of them all open source development. When I'm not debugging ~~C++~~ (Rust/Python now) code or setting up new linux systems, you'll find me reading philosophy (currently juggling reading Sartre's Nausea and Red Rising), creating music, or tinkering with RISC-V processors. I believe in doing things properly , whether it's writing neat code, understanding the philosophy behind API changes, or setting up development workflows that actually make sense. And writing stuff so coming back , anyone can just give a glance and thank me for writing this, I know my future self is going to read this a lot! + +The Sugar desktop environment currently relies on GTK3, which is approaching end-of-life. My mission? Modernize Sugar by completing its migration to GTK4, ensuring long-term sustainability, improved performance, and access to modern UI features. This involves porting the core toolkit (sugar-toolkit-gtk3), porting an activity to GTK4 and making a new activity along with the new features that will be added and testing the changes. + +--- + +## My Approach & Tooling Setup + +Before diving into the actual porting work, I spent considerable time setting up an efficient development workflow. Coming from other projects, I knew that having quick way to test my changes, that is currently I just have to build the toolkit first but later on testing , it helps to have a faster way to test stuff, I may even bring out some tmux scripts later down the weeks but as of now the following is enough: + +### Development Scripts That Saved My Sanity + +I created a couple of shell snippets that became essential during this period: + +\`\`\`bash +# Replace system sugar3 with development version +# This ensures activities use the modified toolkit instead of the old system version +sudo rm -rf /usr/lib/python3.13/site-packages/sugar3;sudo cp -r ./src/sugar3 /usr/lib/python3.13/site-packages/sugar3 + +# Complete rebuild and install cycle +sudo ./autogen.sh;sudo make clean;sudo make;sudo make install +\`\`\` + +The first script is particularly crucial - it replaces the system's sugar3 package with my development version. Without this, Sugar activities would continue using the old GTK3 toolkit, making it impossible to test the GTK4 migration properly. The second command handles the full build cycle, all these small changes help a lot in the long run. I also knew that because I had to write a lot, I developed my own espanso setup and added stuff like em dashes , en dashes, some template code, and a bunch of stuff that come useful while writing. + +### The Work Begins + +1. **Started with the obvious**: Updated all \`gi.require_version\` calls from GTK 3.0 to 4.0 +2. **Build system updates**: Modified GIR includes to use Gtk-4.0 and Gdk-4.0 +3. **The part to work around**: Dealing with GTK4's opaque structures and API changes + +--- + +## The Challenges & My Thought Process + +### 1: GdkEvent Becomes Opaque + +This was my first real "welcome to GTK4" moment. In GTK3, you could directly access event fields like \`event->type\` or \`event->grab_broken.keyboard\`. GTK4 said "nope!" and made GdkEvent structures completely opaque. + +**My approach:** +- Systematically went through each event controller file +- Replaced direct field access with proper accessor functions +- \`event->type\` became \`gdk_event_get_event_type()\` +- \`event->touch.x/y\` became \`gdk_event_get_position(event, &x, &y)\` + +**The human moment:** I'll be honest, this felt tedious at first. But then I realized GTK4's approach actually makes the code more maintainable and future-proof. The accessor functions provide better type safety and clearer intent. + +### 2: GDK_GRAB_BROKEN Disappears + +The \`GDK_GRAB_BROKEN\` event type just... vanished. After diving into GTK4 documentation, I learned that GTK4 handles grab management automatically now. + +**Solution:** Removed the grab broken handling entirely. Well I am not sure if that's a good choice , let's see what happens next week, if we have to come here! +### 3: Goodbye GdkPoint, Hello Custom Structures + +GTK4 removed the \`GdkPoint\` structure that Sugar was using. So naturally, I created a custom \`SugarPoint\` structure: + +\`\`\`c +typedef struct { + double x; + double y; +} SugarPoint; +\`\`\` + +**The learning:** Sometimes migration isn't just about updating APIs, it's about understanding when to create your own abstractions. + +--- + +## Current Progress Snapshot + +Here's where things stand after the community bonding period: + +### Completed +- Updated all \`gi.require_version\` calls to 4.0 in Python files +- Updated import statements across the codebase +- Fixed build system GIR includes (Gtk-4.0, Gdk-4.0) +- **Fixed GdkEvent opaque struct access** in sugar-event-controller.c +- **Migrated all event controllers** to GTK 4 event handling +- **Created and implemented SugarPoint** structure to replace GdkPoint + +### In Progress +- Hunting down remaining 3.0 version references (they're sneaky!) +- Fixing eggaccelerator errors (legacy code is fun, right?) + +### Next on the Roadmap +- Replace GtkToolbar with GtkBox +- Migrate GtkEventBox to GtkWidget + EventControllers +- Update GtkContainer usage to new child management APIs +- Convert draw() methods to snapshot() +- Update size request/allocation APIs + +--- + +## Key Learnings & Insights + +This period taught me that migration projects are as much about understanding the philosophy behind changes as they are about updating code. GTK4 isn't just GTK3 with new version numbers, it represents this shift toward: + +- Better memory safety with opaque structures +- Cleaner event handling with dedicated controllers +- Modern rendering with the snapshot model + + The most valuable skill I've developed is learning to read the porting doc, and understand where to add my own implementation or follow the documentation. I try to reason my changes, so most of the time I am trying to argue to myself why this change compared to something else. + +--- + +## Resources & References + +- Project Page – [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) +- Sugar Toolkit Repository(original) – [sugar-toolkit-gtk3](https://github.com/sugarlabs/sugar-toolkit-gtk3) +- Draft PR ( on the gtk4 repository ) – [Initial GTK4 Migration Work](https://github.com/sugarlabs/sugar-toolkit-gtk4/pull/1/) +- GTK4 Migration Guide – [docs.gtk.org/gtk4/migrating-3to4.html](https://docs.gtk.org/gtk4/migrating-3to4.html) + +--- + +## Acknowledgments + +Huge thanks to Walter Bender for the guidance during this exploration phase, and to the Sugar Labs community for maintaining such well-documented code. I will be contacting other Mentors for their guidance as well and to know their thoughts!. + +--- + +Looking forward to sharing more updates, + + +--- +`,ho=Object.freeze(Object.defineProperty({__proto__:null,default:Oe},Symbol.toStringTag,{value:"Module"})),Be=`--- +title: "GSoC ’25 Week 01 Update by Om Santosh Suneri" +excerpt: "Refining the JSON to text convertor code and creating a basic streamlit debugger app UI" +category: "DEVELOPER NEWS" +date: "2025-06-07" +slug: "2025-06-07-gsoc-25-omsuneri-week01" +author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" +tags: "gsoc25,sugarlabs,week01,Debugger,AI,Music Blocks" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Om Santosh Suneri + +**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) +**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) +**Reporting Period:** 2025-06-02 - 2025-06-07 + +--- + +## Goals for This Week + +- **Goal 1:** To refine the JSON to text convertor code. +- **Goal 2:** To convert the convertor's Javascript code to Python. +- **Goal 3:** To create a basic Streamlit debugger app UI. + +--- + +## This Week’s Achievements + +1. **JSON to Text Converter Refinement** + - I focused on refining the JSON to Text Converter for Music Blocks. I improved the metadata representation of the "start" block to make it more accurate and readable in the text format. Additionally, I added support for more block types, ensuring that their text representations are consistent with the design format. + - This refinement is important because the JSON to Text Converter is a core part of our AI-powered Debugger. A clear and structured text format makes it easier for both the AI model and human users to understand the program logic. + +2. **Javascript to Python Conversion** + - Following suggestions from mentors Walter and Devin, I began creating a Streamlit-based debugger interface. Since Streamlit is a Python framework, my first step was to convert the existing JSON to Text Converter—originally written in JavaScript—into Python. This involved translating the logic and formatting rules to ensure the output remained consistent. + - This conversion is crucial because it enables seamless integration of the converter into the Streamlit app, which will serve as the initial interface for our debugger. By moving the code to Python, I ensured compatibility with the app’s backend, allowing further development like live user queries, debugging and feedback—all in one cohesive Python environment. + +3. **Streamlit Debugger App UI Creation** + - As a beginner to Streamlit, I started building the UI for the debugger app. I successfully created a basic Streamlit interface that allows users to input text queries. To handle these queries, I integrated the free Google Gemini API, enabling the app to return LLM-generated responses. Currently, the app supports simple user input and displays the corresponding Gemini response. + - This is an important first step in building an interactive AI-powered debugger. Even though it’s still in an early stage, this app lays the foundation for integrating core features like JSON-to-text conversion, error analysis, and user feedback. The goal is to evolve this into a fully functional debugging tool that enhances the Music Blocks experience. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Learning the Streamlit framework and creating a basic UI app as a complete beginner. + **Solution:** To overcome this, I referred to the official Streamlit documentation, followed beginner tutorials, and experimented with small components to understand the structure. This hands-on approach helped me build a working basic UI that takes user input and integrates it with the Gemini API. + +- **Challenge:** Converting all methods and functions from JavaScript to Python was time-consuming and introduced several errors. + **Solution:** I carefully mapped the logic from JavaScript to Python, using Pythonic alternatives where necessary. I used print-based debugging and Python’s error messages to identify issues. Although some minor bugs remain, I have a clear plan to fix them in the coming days and will be testing each function thoroughly for accurate output. + +--- + +## Key Learnings + +- I gained an understanding of Streamlit’s basic architecture and learned how to build and deploy a Streamlit app +- I explored advanced Python techniques to effectively translate the JavaScript code into Python for smoother integration. + +--- + +## Next Week’s Roadmap + +- My goal for the next week is to fully convert the JSON to Text Converter, originally written in JavaScript, into Python. +- I also plan to integrate this Python version directly into the Streamlit debugger app to enable seamless JSON conversion within the app interface. +- Additionally, I aim to make the basic functionality of the app usable so that users can begin interacting with it and provide initial feedback. This feedback will help identify usability issues early and guide further improvements in the UI and debugging workflow. + +--- + +## Resources & References + +- **Repository:** [AI-powered-Debugger-for-MB(JSON convertor)](https://github.com/omsuneri/AI-powered-Debugger-for-MB/blob/main/Convertor/converting-json-txt.js) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,go=Object.freeze(Object.defineProperty({__proto__:null,default:Be},Symbol.toStringTag,{value:"Module"})),Re=`--- +title: "SSoC ’25 Week 01 Update by Muhammad Haroon" +excerpt: "Kick off Generative AI Instrument Sample Generation for Music Blocks" +category: "DEVELOPER NEWS" +date: "2025-06-08" +slug: "2025-06-08-ssoc-25-MuhammadHaroon-week01" +author: "@/constants/MarkdownFiles/authors/muhammad-haroon.md" +tags: "ssoc25,sugarlabs,week01,GenAI,MusicBlocks,Music" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Muhammad Haroon + +**Project:** [Generative AI Instrument Sample Generation for Music Blocks](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md#Generative-AI-Instrument-Sample-Generation-for-Music-Blocks) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-02 - 2025-06-08 + +--- + +## Progress + +I am excited to announce that I have been selected for Sugar Summer of Code 2025. This summer I would be working on creating a Generative AI tool that would create endless sound samples that can be then used in Music Blocks. + +This week I kicked off my project, I had a meeting with my mentors, and discussed my approach with them. For the next week, it was decided to create a basic frontend using streamlit and for the backend will be using [MusicGen](https://audiocraft.metademolab.com/musicgen.html). + +I will begin by testing some prompts and generating some samples from it, to test whether they can be used in Music Blocks or further refinement of the pipeline is needed. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,mo=Object.freeze(Object.defineProperty({__proto__:null,default:Re},Symbol.toStringTag,{value:"Module"})),ze=`--- + +title: "Community Bonding & Week 1 Update by Karan Palan" +excerpt: "From compiler theory deep-dives to brick-rendering math—mentoring the 2025 Music Blocks Masonry & Engine cohorts." +category: "DEVELOPER NEWS" +date: "2025-06-09" +slug: "2025-06-09-KaranPalan-week01" +author: "Karan Palan" +description: "GSoC 2024 mentee, now volunteering and peer-mentoring on Music Blocks 4" +tags: "gsoc25,sugarlabs,communitybonding,week1,karanpalan" +--- + +<!-- markdownlint-disable --> + +# Community Bonding + Week 1 Progress Report + +**by Karan Palan** + +**Projects:** Music Blocks 4 **Masonry** & **Program Engine** +**Role:** Volunteer & Peer-Mentor (GSoC 2024 alumnus) +**Mentor:** [Anindya Kundu](https://github.com/meganindya/) +**Mentees:** [Justin Charles](https://github.com/justin212407), [Saumya Shahi](https://github.com/saumyashahi) (Masonry) • [Safwan Sayeed](https://github.com/sa-fw-an) (Engine) +**Reporting Period:** 2025-05-20 → 2025-06-08 + +--- + +Community bonding this year felt less like “hello world” and more like an accelerated CS grad course. Anindya flipped the script: before writing a single line of code we dissected *how* languages work, explored compiler pipelines, and compared micro-compilers. + +### Mapping Bricks to LLVM IR + +Armed with that theory, each of us reverse-mapped **Music Blocks bricks → LLVM intermediate representation** to ground our designs in real compiler constructs. My early spreadsheet of brick vs. IR became a north star for future optimizations. + +### Defining Music Blocks Grammar + +After digesting JavaScript’s formal grammar, we drafted a Music Blocks-specific one that is lean, kid-friendly, but still transpilable to JS. This fed directly into the Engine tech spec. + +### Meeting with Andres + +Anindya set up a fireside chat with his former manager **Andrés**, giving us a crash-course in real-world engineering. Andrés drilled home that *“quick fixes live for 18 months,”* scope must be ruthlessly trimmed, and the true mark of a pro is writing code a stranger can maintain five years later, all while treating teammates (coders or not) with respect. + +### Two Tracks, One Vision + +We split weekly calls: + +| Track | Focus | Key Doc | +| ------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| Masonry | SVG brick generation & formulae | [Brick Sides & Formulae](https://docs.google.com/document/d/1AUlA2leDJIfV3ZXceLhCaITftExq6c5BcUBMZOtZBvE/) | +| Engine | AST, runtime, class hierarchy | [Engine Tech Spec + AST](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/) | + +--- + +## Highlights So Far + +1. **Project-wide Knowledge Base** + *Spreadsheet* of compiler concepts & Music Blocks parallels—anchors every design choice. + Link ➜ [Mentor Context Sheet](https://docs.google.com/spreadsheets/d/1LFuIlzRiMlEfeLr21x8_SYnVIQ5baVQv8tz2GWN9PfU/) + +2. **Brick Taxonomy Drafted** + Classified each brick against LLVM constructs for easy reasoning about side-effects and type constraints. + Link ➜ [Brick ↔️ LLVM Mapping](https://docs.google.com/document/d/1BswWHadyy4yC3_3vK6KHZnMn0u6jbbYiQ6JQWiqRMLw/) + +3. **Brick Geometry Formulae** + With Justin & Saumya, derived parametric equations for every brick edge—vital for responsive SVG. + Link ➜ [Brick Formulae Doc](https://docs.google.com/document/d/1AUlA2leDJIfV3ZXceLhCaITftExq6c5BcUBMZOtZBvE/) + +4. **Engine Class Skeleton** + Safwan and I scaffolded core *abstract* and initial *concrete* classes in TypeScript. + Code ➜ [Replit Workspace](https://replit.com/@karanpalan007/engine-abstract-classes?v=1) + + + +## Key Learnings + +* **Teach, then build:** A solid mental model of compilers made later coding decisions friction-less. +* **Visual specs pay off:** Equation-driven SVG means less pixel-pushing, more deterministic rendering. +* **Peer-mentoring ≠ lecturing:** Guiding Justin, Saumya, and Safwan taught me to ask leading questions instead of prescribing answers. + +--- + +## Next Week’s Roadmap + +* **Masonry:** Finish implementing '_generateLeft()' so *all* brick types respect left-side notches. +* **Engine:** Flesh out 'Expression' subclasses and prototype a minimal AST → JS transpile step. +* **Docs & CI:** Auto-publish rendered SVG examples in PR previews to catch geometry regressions early. + +--- + +## Resources & References + +* Mentor Notes → [Spreadsheet](https://docs.google.com/spreadsheets/d/1LFuIlzRiMlEfeLr21x8_SYnVIQ5baVQv8tz2GWN9PfU/) +* Brick ↔️ LLVM Mapping → [Google Doc](https://docs.google.com/document/d/1BswWHadyy4yC3_3vK6KHZnMn0u6jbbYiQ6JQWiqRMLw/) +* Engine Tech Spec → [Google Doc](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/) +* Brick Geometry → [Formulae Doc](https://docs.google.com/document/d/1AUlA2leDJIfV3ZXceLhCaITftExq6c5BcUBMZOtZBvE/) +* Code Skeleton → [Replit](https://replit.com/@karanpalan007/engine-abstract-classes?v=1) + +--- + +## Acknowledgments + +Huge thanks to **Anindya** for the deep-dive lectures and mentoring, and to **Justin, Saumya, and Safwan** for matching my energy sprint-for-sprint. SugarLabs’ culture of mentoring forward keeps the snowball rolling. + +--- + +## Connect with Me + +* GitHub: [@Karan-Palan](https://github.com/Karan-Palan/) +* Email: [karanpalan007@gmail.com](mailto:karanpalan007@gmail.com) +* LinkedIn: [karan-palan-476472289/](https://www.linkedin.com/in/karan-palan-476472289/) +* Twitter: [Karan_Palan7](https://x.com/Karan_Palan7) + +--- +`,po=Object.freeze(Object.defineProperty({__proto__:null,default:ze},Symbol.toStringTag,{value:"Module"})),Ue=`--- +title: "GSoC ’25 Week 04 Update by Aditya Kumar Singh" +excerpt: "localization for 3D Human Activity in Sugarizer, palette switcher, and skeletal improvements." +category: "DEVELOPER NEWS" +date: "2025-06-10" +slug: "2025-06-10-gsoc-25-AdityaKrSingh26-week04" +author: "@/constants/MarkdownFiles/authors/aditya-singh.md" +description: "GSoC'25 Contributor at SugarLabs (Sugarizer Human Activity Pack)" +tags: "gsoc25,sugarlabs,week04,AdityaKrSingh26" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 04 Progress Report by Aditya Kumar Singh + +**Project:** [Sugarizer](https://github.com/llaske/sugarizer) +**Mentors:** [Lionel Laské](https://github.com/llaske) +**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) +**Reporting Period:** 2025-05-30 - 2025-06-05 + +--- + +## Goals for This Week + +- **Goal 1:** Add a model selection palette UI to toggle between models. +- **Goal 2:** Integrate the Human-body model into the paint activity and set the Human-body human model as the default view. +- **Goal 3:** Refactor and improve naming conventions for bones in the skeleton model. +- **Goal 4:** Localize the Human Body Activity using i18next.js, supporting English and French. + + +--- + +## This Week’s Achievements + +1. **Model Palette Implementation** + - Developed a new model selection palette in the UI allowing users to switch between: + - Human body + - Skeleton + - Organs + - Set the Human body as the default model loaded on activity start. + - Palette updates the 3D scene dynamically without requiring a full reload. +  + + +2. **Human-Body Model Paint Integration** + - Integrated the Human body model with the interactive paint activity. + - Ensured hierarchical structure for smooth interactivity and logical mesh grouping +  + + +3. **Improved Bone Naming in Skeleton Model** + - Refactored the skeletal model for accurate and educational naming: + - Replaced generic labels like “Lower Leg” with specific names like **Tibia** and **Fibula**. + - Split forearm into **Radius** and **Ulna**, adjusting geometry and mesh positions. + + + +4. **Implemented i18next.js to support internationalization.** + - Implemented **i18next.js** to support internationalization. + - Completed full translation of Human Body Activity in **English** and **French**. + - Translation files follow standard .json structure for easy future expansion. + - Example image for French: +  + + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Naming skeleton bones accurately without anatomical overlap. + **Solution:** Cross-referenced medical diagrams and validated model mesh mapping manually in Blender. + +--- + +## Key Learnings + +- Deepened understanding of scene management in Three.js and optimized mesh rendering for performance. +- Gained experience in internationalization using i18next.js +- Developed more precise anatomical terminology awareness and importance of educational clarity. + +--- + +## Next Week’s Roadmap + +- Write Weekly Blog Post summarizing progress, screenshots, and key learnings. +- Fix Organs model. Distance between eyes and mouth seems to be more than required, reduce that and see if there is some alignment issue. +- Integrate the full human body model into the paint activity to allow direct interaction and labeling across complete anatomy. +- Merge Paint and Learn mode to show a popup at bottom of screen when user click a part + +--- + + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +## Connect with Me + +- GitHub: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) +- Gmail: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) +- LinkedIn: [Aditya Kumar Singh](https://www.linkedin.com/in/adityakrsingh26/) +- Twitter: [@AdityaKrSingh26](https://x.com/AdityaKrSingh26) + +--- +`,bo=Object.freeze(Object.defineProperty({__proto__:null,default:Ue},Symbol.toStringTag,{value:"Module"})),Fe=`--- +title: "GSoC '25 Week 2 Update by Elwin Li" +excerpt: "Weekly progress report for JSEditor updates" +category: "DEVELOPER NEWS" +date: "2025-06-14" +slug: "2025-06-14-gsoc-25-Elwin-Li-week02" +author: "@/constants/MarkdownFiles/authors/elwin-li.md" +tags: "gsoc25,sugarlabs,week2,javaScript editor" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 2 Progress Report by Elwin Li + +**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/config_driven_conversion/elwin) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) + +**Reporting Period:** 2025-06-07 - 2025-06-14 + +--- + +## Goals for This Week + +- **Goal:** Complete and deploy code to blocks functionality with full documentation and begin work on debugger. + +--- + +## This Week’s Achievements + +**Added All Blocks for Code to Blocks Support** + +I added all blocks that are supported for block to code conversion to be supported for code to blocks conversion. I also added all necessary unit tests, and very [detailed documentation](https://github.com/sugarlabs/musicblocks/blob/master/js/js-export/CONVERSION_GUIDE.md) on how to add new blocks for support. + +**Optimized Files** + +I added a script to minify the JSON config so that musicblocks doesn't need to load the entire large file. I also merged many blocks that have the same path in the AST so that the config looks cleaner, and adding new blocks of the same path is even easier. + +**Deployed Project** + +The code to blocks project has been complete and deployed, as seen in this [merged PR](https://github.com/sugarlabs/musicblocks/pull/4707). To test, simply write your musicblocks program in Javascript in the editor and press the convert button. Note that the only blocks supported are those supported by block to code conversion, so it won't work on every single block possible, but will work on most of them. + +<a href="https://ibb.co/qLNNyH8W"><img src="https://i.ibb.co/V0ggjFGQ/Screenshot-2025-06-14-at-2-25-05-PM.png" alt="Conversion Example"></a> + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Minimizing file size of config file + + **Solution:** Merging configs, and using minified JSON for loading. + +- **Challenge:** Never-seen-before git errors when trying to push commit + + **Solution:** Image size as part of the documentation was too large, had to compress it. + +--- + +## Key Learnings + +- Deepened understanding of git. +- Improved skills in **debugging**, **code design**, and **collaboration workflows**. + +--- + +## Next Week’s Roadmap + +- Begin debugger project +- Being able to set breakpoints in the code +- Add ability to trigger status block in the code as the debugger + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,fo=Object.freeze(Object.defineProperty({__proto__:null,default:Fe},Symbol.toStringTag,{value:"Module"})),Ne=`--- +title: "GSoC ’25 Week 02 Update by Mebin J Thattil" +excerpt: "Fine-Tuning, Deploying, Testing & Evaluations" +category: "DEVELOPER NEWS" +date: "2025-06-14" +slug: "2025-06-14-gsoc-25-mebinthattil-week2" +author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" +tags: "gsoc25,sugarlabs,week02,mebinthattil,speak_activity" +image: "assets/Images/GSOCxSpeak.png" +--- + +<!-- markdownlint-disable --> + +# Week 02 Progress Report by Mebin J Thattil + +**Project:** [Speak Activity](https://github.com/sugarlabs/speak) +**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-08 - 2025-06-14 + +--- + +## Goals for This Week + +- **Goal 1:** Setup AWS for Fine-Tuning. +- **Goal 2:** Fine-Tune a small model on a small dataset. +- **Goal 3:** Deploy the model on AWS and create an API endpoint. +- **Goal 4:** Test the endpoint using a python script. +- **Goal 5:** Evaluate the model responses and think about next steps. + +--- + +## This Week’s Achievements + +1. **Setup AWS for Fine-Tuning** + - Setup AWS SageMaker. + - Provisioned GPUs on AWS SageMaker to fine-tune Llama3-1B foundation model. + +2. **Dataset & Cleaning** + - Used an open dataset. It was a dataset about conversations between a student and a teacher. + - The dataset was cleaned and converted into a format that Llama needed for fine-tuning. + - Wrote a small script to convert the dataset into a format that Llama can understand. + - The dataset along with the script is available [here](https://github.com/mebinthattil/Education-Dialogue-Dataset). + +3. **Fine-tuning** + - Fine-tuned the model on a small set of the dataset, just to see how it performs and to get familar with AWS SageMaker. + - The training job ran on a \`ml.g5.2xlarge\` instance. + - The hyperparameters that were set so as to reduce memory footprint and mainly to test things. I'll list the hyperparameters, hoping this would serve as documentation for future fine-tuning. + + **Hyperparameters**: + + | Name | Value | + |----------------------------------|----------------------------------------------------| + | add_input_output_demarcation_key | True | + | chat_dataset | True | + | chat_template | Llama3.1 | + | enable_fsdp | False | + | epoch | 5 | + | instruction_tuned | False | + | int8_quantization | True | + | learning_rate | 0.0001 | + | lora_alpha | 8 | + | lora_dropout | 0.08 | + | lora_r | 2 | + | max_input_length | -1 | + | max_train_samples | -1 | + | max_val_samples | -1 | + | per_device_eval_batch_size | 1 | + | per_device_train_batch_size | 4 | + | preprocessing_num_workers | None | + | sagemaker_container_log_level | 20 | + | sagemaker_job_name | jumpstart-dft-meta-textgeneration-l-20250607-200133| + | sagemaker_program | transfer_learning.py | + | sagemaker_region | ap-south-1 | + | sagemaker_submit_directory | /opt/ml/input/data/code/sourcedir.tar.gz | + | seed | 10 | + | target_modules | q_proj,v_proj | + | train_data_split_seed | 0 | + | validation_split_ratio | 0.2 | + +4. **Saving the model** + - The safetensors and other model files were saved in an AWS S3 bucket. The URI of the bucket is: \`\`\` s3://sagemaker-ap-south-1-021891580293/jumpstart-run2/output/model/ \`\`\` + +5. **Deploying the model** + - The model was deployed on AWS SageMaker and an API endpoint was created. + +6. **Testing the model** + - A python script was written to test the model using the API endpoint. + +7. **Evaluation** + - The model responses were tested using the same questions used in my [benchmark](https://llm-benchmarking-sugar.streamlit.app/) done before. + + +--- + +## Unexpected Model Output + +- After fine-tuning the model, I noticed that the model was producing some unexpected output. I expected the model to behave like general chatbot but in a more friendly and teacher-like manner. While the model's responses did sound like a teacher, the model would often try to create an entire chain of conversations generating the next response from a students perspective and then proceeed to answer itself. +- This behaviour was becaues of the way the dataset was strucutred. The dataset was enssentially a list of back and forth conversations between a student and a teacher. So it makes sense that the model would try to create a chain of conversations. But this is not what we need from the model. +- The next step is to change the strucutre of the dataset to make it just answer questions, but also to make it more conversational and understand the nuaces of a chain of conversations. +- The temporary fix was the add a stop statement while generating responses and also tweaking the system prompt. But again, this is not the right way to go about it. The right was is to change the dataset structure. + +--- + +## Sample model output with stop condition + + + +--- + +## Key Learnings + +- Structure of dataset needs to be changed, in order to make it more conversational and understand the nuances of a chain of conversations. + +--- + +## Next Week’s Roadmap + +- Re-structure the dataset +- Re-Train and Fine-Tunethe model on the new dataset +- Deploy, create endpoint and test the model on the new dataset +- Evaluate the model on the new dataset and add to benchmarks + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +`,yo=Object.freeze(Object.defineProperty({__proto__:null,default:Ne},Symbol.toStringTag,{value:"Module"})),qe=`--- +title: "GSoC '25 Week 2 Update by Shubham Singh" +excerpt: "Adding the entire prototyped interface ON TO the music blocks" +category: "DEVELOPER NEWS" +date: "2025-06-14" +slug: "2025-06-14-gsoc-25-firepheonix-week02" +author: "@/constants/MarkdownFiles/authors/shubham-singh.md" +tags: + - gsoc25 + - sugarlabs + - week02 + - firepheonix +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 2 Progress Report by Shubham Singh + +**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) +**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-06-08 – 2025-06-15 + +--- + +## Goals for This Week + +- Basic UI for Image Upload/Real-time Video upload and adjustment. +- Integrating the developed UIs onto the widget blocks within Music Blocks. +- Researching existing audio integration patterns in the phrase maker and note blocks. + +--- + +## This Week's Achievements + +1. **Interface Implementation for Lego Notations** + - Successfully integrated the LegoBricks block directly onto the Music Blocks canvas. + - Modified 6 different files to implement an entirely new block type. + - Music Blocks already has sophisticated color detection for internal pixels, but couldn't detect colors from external sources like uploaded images or webcam feeds — this limitation was addressed. + - The codebase proved beautifully encapsulated and thoroughly documented, making the learning curve smoother. +  + +2. **Real-time Video Integration** + - Implemented real-time video functionality through webcam integration. + - Added full editing capabilities and canvas manipulation for live video feeds. + - Interface provides seamless interaction between video feed and detection algorithms. +  + +3. **Export Mechanism Research** + - Conducted extensive research into existing export mechanisms within Music Blocks. + - Deep-dived into Phrase Maker widget documentation and codebase. + - Studied how different blocks export output as both MIDI files and action blocks. +  + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** UI integration complexity — getting the UI integrated into Music Blocks proved more challenging than expected due to intricate dependencies and specific implementation patterns required by the block system. +**Solution:** Leveraged multiple resources including mentor consultations, existing documentation on "how to add new blocks," and analyzed previous implementations for reference patterns. + +- **Challenge:** User workflow design — determining optimal user workflow for the Lego Bricks block required careful consideration of user interaction patterns and integration with existing functionality. +**Solution:** Scheduled focused discussion with mentor during regular meeting to analyze phrase maker export functionality, gaining crucial insights into user experience patterns and technical approaches. + +--- + +## Key Learnings + +- Gained comprehensive understanding of **output mechanisms** and how different blocks handle their output generation and processing. +- Deepened appreciation for **code architecture** including inheritance patterns, code modularity, and custom return types within the Music Blocks ecosystem. +- Improved skills in **development workflow** including exports, imports, code reusability, documentation practices, and collaborative development workflows. + +--- + +## Next Week's Roadmap + +- Implement comprehensive mapping of musical notes to Lego brick colors. +- Complete the core implementation during weeks 2 and 3, ensuring robust functionality and thorough testing. +- Focus on algorithmic challenges for note-to-color mapping system. + +--- + +## Resources & References + +- **Project Issue:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) +- **Music Blocks Repository:** [sugarlabs/musicblocks](https://github.com/sugarlabs/musicblocks) +- **Documentation:** Music Blocks Developer Guide + +--- + +## Acknowledgments + +Thank you to my mentors [Walter Bender](https://github.com/walterbender) and [Devin Ulibarri](https://github.com/pikurasa) for invaluable guidance throughout this development phase. Special thanks to Walter for his advice during our biweekly meeting on how the phrase maker exports output as ACTION blocks. + +---`,wo=Object.freeze(Object.defineProperty({__proto__:null,default:qe},Symbol.toStringTag,{value:"Module"})),He=`--- +title: "GSoC '25 Week 2 Update by Krish Pandya" +excerpt: "From initial GTK4 porting to building a solid foundation with separate C and Python libraries" +category: "DEVELOPER NEWS" +date: "2025-06-14" +slug: "2025-06-14-gsoc-25-mostlyk-week02" +author: "@/constants/MarkdownFiles/authors/krish-pandya.md" +tags: "gsoc25,sugarlabs,week02,mostlyk" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 2: Strategic Pivot and Foundation Building + +**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky), [Juan Pablo Ugarte](https://github.com/xjuan) +**Reporting Period:** June 06, 2025 till June 14, 2025 + +--- + + +## The Meeting that changed everything + +On Friday(06-06-2025), we had a pivotal video call with Juan Pablo Ugarte and Ibiam Chihurumnaya that completely reshaped the porting approach. +What started as a discussion about my initial porting work evolved into something much more strategic and forward-thinking. + +> While the time of writing this, another meet that happened on 13-06-2025 , we discussed about the API versioning and updating with pytest, ideas about testing, more porting golden advice, more about this on next week's blog. + +### The New Architecture Vision + +The mentors introduced a brilliant modular approach that addresses the core challenges of the GTK4 migration: + +**1. Two Separate Libraries Strategy** +- C Library 'sugar-ext': Core objects and reusable GTK widgets +- Python Wrapper Library: Python widgets and wrapper functions + + + +> Subject to change + +**2. Independent Development & Testing** +Each library will be developed in its own repository with simple Python example scripts. This approach offers several advantages: +- Clear separation of concerns between C and Python components +- Easier debugging and testing +- Better CI/CD pipeline management +- Modular, incremental development that reduces complexity + +**3. Meson Build System Foundation** +We'll use Meson's shared library template from GNOME Builder as our base. This gives us: +- Modern build system designed for GTK4 +- Better dependency management +- Cleaner project structure + +### Why This Approach Made Sense + +The more I thought about this strategy, the more I realized how elegant it is. Instead of trying to port everything at once (my initial approach, by changing the orignal toolkit and it's systems), we're building a solid foundation that can support the entire Sugar ecosystem. This modular approach means: + +- Maintainability — Each component can be updated independently +- Testing — Smaller, focused libraries are easier to test thoroughly +- Future-proofing — The architecture can adapt as GTK continues to evolve +- Support — Due to the new build system, we would have more support and we can also remove things we find deprecated. +--- + +## Implementation + +Following the meeting – I immediately got to work implementing. +The result that came out was [Pull Request #1](https://github.com/sugarlabs/sugar-ext/pull/1) in the new 'sugar-ext' repository. + +### What I Built + +**Project Structure:** +- Complete Meson build system setup +- GObject Introspection integration for seamless Python bindings +- Initial API implementation (starting with XO Colors for testing) +- Comprehensive documentation and development tools + +**Key Technical Decisions:** +\`\`\`c +// API versioning strategy +api_version = '1.0' // Maintaining compatibility with existing SugarExt +package_version = '0.122.0' // Following Sugar's versioning convention + +// GIR configuration for Python bindings +symbol_prefix: 'sugarext' +identifier_prefix: 'SugarExt' +\`\`\` + +> This was discussed later in the meet and we decided to keep the packages version 2.0 or 4.0 because GTK4. Will be confirmed by the next blog, + +- Included comprehensive build and test scripts + +### Testing Framework + +The project includes a robust testing setup: +\`\`\`bash +meson test -C builddir +\`\`\` + +This runs the test suite, validating that the C library builds correctly and the test written should pass. + +--- + +### To my Fellow Devs + +- I have few files that can help you get your setup right. If you like clangd and use it as your LSP. Here's the .clangd configuration I used for sugar-ext. + +\`\`\`yaml +CompileDatabase: ./builddir + +If: + PathMatch: .*\\.(c|h)$ +CompileFlags: + Add: [ + -I./src, + -I./builddir, + -I/usr/include/gtk-4.0, + -I/usr/include/glib-2.0, + -I/usr/lib/glib-2.0/include, + -I/usr/include/pango-1.0, + -I/usr/include/harfbuzz, + -I/usr/include/fribidi, + -I/usr/include/gdk-pixbuf-2.0, + -I/usr/include/cairo, + -I/usr/include/freetype2, + -I/usr/include/libpng16, + -I/usr/include/pixman-1, + -I/usr/include/graphene-1.0, + -I/usr/lib/graphene-1.0/include, + -I/usr/include/libmount, + -I/usr/include/blkid, + -I/usr/include/sysprof-6, + -I/usr/local/include/sugar-ext, + -D_FILE_OFFSET_BITS=64 + ] + +Diagnostics: + ClangTidy: + Add: [ + readability-*, + bugprone-*, + performance-*, + misc-* + ] + Remove: [ + modernize-*, + readability-isolate-declaration, + readability-function-cognitive-complexity + ] + UnusedIncludes: Strict + +InlayHints: + Enabled: Yes + ParameterNames: Yes + DeducedTypes: Yes + +Hover: + ShowAKA: Yes + +Index: + Background: Build + +Completion: + AllScopes: Yes + +Format: + Style: GNU +\`\`\` + +- And if you are using VSCode and the C/C++ extension, here's the c_cpp_properties.json. +\`\`\`json +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "\${workspaceFolder}/**", + "\${workspaceFolder}/builddir", + "/usr/include/gtk-4.0", + "/usr/include/pango-1.0", + "/usr/include/fribidi", + "/usr/include/harfbuzz", + "/usr/include/gdk-pixbuf-2.0", + "/usr/include/cairo", + "/usr/include/freetype2", + "/usr/include/libpng16", + "/usr/include/pixman-1", + "/usr/include/graphene-1.0", + "/usr/lib/graphene-1.0/include", + "/usr/include/glib-2.0", + "/usr/lib/glib-2.0/include", + "/usr/include/libmount", + "/usr/include/blkid", + "/usr/include/sysprof-6" + ], + "defines": [ + "_FILE_OFFSET_BITS=64" + ], + "cStandard": "gnu11", + "cppStandard": "c++17", + "intelliSenseMode": "linux-gcc-x64", + "compilerPath": "/usr/bin/gcc", + "compileCommands": "\${workspaceFolder}/builddir/compile_commands.json" + } + ], + "version": 4 +} +\`\`\` + +## Lessons from the PR Review Process + +- To be added on week 3 as it gets merged! + + +# Migration List + +- Here Use as-is means if we decide to keep it we use it or it's newer version or alternatives. Port meaning we would have to change stuff, and whenever I have mentioned GTK4 we will use the new API directly rather than implementing from scratch. +## C Objects Migration List + +| Object | Dependencies | Purpose | Port/Use GTK4 | +|--------|--------------|---------|---------------| +| sugar-grid.c/h | GLib + GDK | Grid-based layout calculations | Port | +| sugar-fatattr.c/h | Pure C, sys headers | FAT filesystem attribute utilities | Use as-is | +| acme-volume.c/h | GLib, ALSA | Audio volume control | Use as-is | +| acme-volume-alsa.c/h | GLib, ALSA | ALSA backend for volume control | Use as-is | +| sugar-wm.c/h | GLib, GDK, X11 | Window manager interaction utilities | Port | +| sugar-clipboard.c/h | GLib, GTK3 | Clipboard helper functions | Port (GdkClipboard) | +| eggdesktopfile.c/h | GLib, GTK3, GDK | Desktop file parsing and launching | Port | +| sugar-key-grabber.c/h | GLib, GDK, X11 | Global key binding system | Port (GTK4 shortcuts) | +| sugar-cursor-tracker.c/h | GLib, GDK, X11, XInput2 | Mouse cursor visibility tracking | Port (GTK4 events) | +| sugar-gesture-grabber.c/h | GLib, GDK, X11, XInput2 | Global gesture capture system | Port (GTK4 gestures) | +| sugar-event-controller.c/h | GLib, GTK4 | Base event controller | Port | +| sugar-long-press-controller.c/h | GLib, GTK4 | Long press gesture detection | Port | +| sugar-swipe-controller.c/h | GLib, GTK4 | Swipe gesture detection | Port | +| sugar-touch-controller.c/h | GLib, GTK4 | Touch event handling | Port | +| sugar-zoom-controller.c | GLib, GTK4 | Zoom gesture detection | Port | +| sugar-rotate-controller.c | GLib, GTK4 | Rotation gesture detection | Port | +| eggaccelerators.c/h | GLib, GTK3, GDK, X11 | Keyboard accelerator handling | Port | +| eggsmclient.c/h | GLib | Session management client | Use as-is | +| eggsmclient-xsmp.c/h | GLib, X11, ICE, SM | XSMP session management backend | Use as-is | +| gsm-app.c/h | GLib | Session management application handling | Use as-is | +| gsm-client.c/h | GLib | Session management client base | Use as-is | +| gsm-client-xsmp.c/h | GLib, X11, ICE, SM | XSMP client implementation | Use as-is | +| gsm-session.c/h | GLib | Session management core | Use as-is | +| gsm-xsmp.c/h | GLib, X11, ICE, SM | XSMP protocol implementation | Use as-is | + + + +## Next Steps: Building the Foundation + +### Immediate Priorities (Week 3) + +1. Finalize C Library Scaffold +- Address remaining PR feedback +- Implement proper copyright and licensing +- Add core Sugar widgets starting with \`sugar-grid\` +- Sugar-Grid was added on 14-June-2025 while I am writing this. + +2. Begin Python Wrapper Development +- Set up the Python-side repository +- Create example scripts demonstrating usage + + + +--- + + +## Resources & References + +- Project Page – [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) +- New C Library - [sugar-ext repository](https://github.com/sugarlabs/sugar-ext) +- Active PR - [Establish C library base template with Meson for GTK4](https://github.com/sugarlabs/sugar-ext/pull/1) +- Sugar Toolkit Repository(original) – [sugar-toolkit-gtk3](https://github.com/sugarlabs/sugar-toolkit-gtk3) +- GTK4 Migration Guide – [docs.gtk.org/gtk4/migrating-3to4.html](https://docs.gtk.org/gtk4/migrating-3to4.html) + + +--- + +## Acknowledgments + +Huge thanks to Juan Pablo Ugarte first of all for being the official mentor and Ibiam Chihurumnaya for the guidance that that changed this project's direction. Their architectural vision has transformed porting into a comprehensive modernization effort. Thanks also to Walter Bender for mentorship. + +--- + +THe architecture is building itself, and I'm excited to lay down the foundations! + +`,vo=Object.freeze(Object.defineProperty({__proto__:null,default:He},Symbol.toStringTag,{value:"Module"})),Ke=`--- +title: "GSoC '25 Week 02 Update by Saumya Shahi" +excerpt: "This week focused on documenting the brick tree structure, refining SVG path generation, and learning testing tools like Storybook." +category: "DEVELOPER NEWS" +date: "2025-06-14" +slug: "2025-06-14-gsoc-25-saumya-shahi-week02" +author: "@/constants/MarkdownFiles/authors/saumya-shahi.md" +tags: "gsoc25,sugarlabs,week02,saumya-shahi" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 02 Progress Report by Saumya Shahi + +**Project:** [Masonry Module - Music Blocks v4](https://github.com/sugarlabs/musicblocks-v4) +**Mentors:** [Anindya Kundu](https://github.com/meganindya/) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-08 – 2025-06-14 + +--- + +## Goals for This Week + +- Refine and complete configuration-driven rendering logic. +- Test rendering of multiple brick types and validate correctness using sample input. +- Document how brick configurations and connections should be modeled. +- Start building foundational elements for brick tree rendering. + +--- + +## This Week's Achievements + +1. **Dynamic SVG Brick Rendering** + - Finalized implementation for rendering SVG paths dynamically based on type-specific configurations. + - Different bricks (e.g., nested bricks, simple bricks, expression bricks) now render accurately according to their label sizes, scale, and other config props. + - Output adjusts responsively with different numbers of arguments, notches, and labels. + +2. **Rendered Output Validation & Screenshots** + - Verified each visual brick against expected path geometry. + - Screenshots below show rendered bricks: +  +  +  + +2. **Bug Fix: Left SVG Path Issue** + + * Fixed a critical error in path rendering for bricks — the left edge generation wasn’t calculating offsets correctly. + * Cleaned up related path logic to improve readability and scalability for future nested structures. + +3. **Storybook & Testing Familiarization** + + * Understood how Storybook is used for visual component testing. + * Learnt how to set up unit tests and component test files. + * Setup groundwork for adding future test cases. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Mapping the brick tree vs AST was initially confusing. +**Solution:** Spent focused time breaking down what each structure is supposed to represent and clarified use cases. + +- **Challenge:** SVG left path errors were hard to trace visually. +**Solution:** Used visual diffing and debugger to narrow down bounding box and stroke-width miscalculations. + +--- + +## Key Learnings + +- Improved understanding of **SVG rendering logic** and path construction. +- Got hands-on exposure to **Storybook**, and how visual tests can improve modular development. +- Understood the **difference between data representations** for view (brick tree) and logic (AST). + + +--- + +## Next Week's Roadmap + +- Start implementing **multi-brick layout rendering**: bricks with children rendered as a tree in the workspace. +- Introduce bounding box calculation utilities for each rendered brick. +- Plan initial strategy for brick connection detection and snapping logic. + +--- + +## Resources & References + +- **Brick Rendering:** [Google Doc](https://docs.google.com/document/d/1UJXh3734S138BoTsGulzeTlZXstyvWd6syJK2eclMKI/edit?tab=t.dxoea5urpxyl#heading=h.wa29sjgrasfn) +- **SVG Path Reference:** [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) +- **Playground for Manual SVG Paths:** [SVG Path Editor](https://yqnn.github.io/svg-path-editor/) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for support and insightful feedback throughout the week. + +--- +`,ko=Object.freeze(Object.defineProperty({__proto__:null,default:Ke},Symbol.toStringTag,{value:"Module"})),Ve=`--- +title: "DMP ’25 Week 2 Update by Aman Naik" +excerpt: "This week's focus was on creating a story builder feature in such a way that it engages creativity of the children." +category: "DEVELOPER NEWS" +date: "2025-06-15" +slug: "2025-06-15-dmp-25-AmanNaik-week02" +author: "@/constants/MarkdownFiles/authors/amannaik247.md" +tags: "dmp25,writeactivity,write,sugarlabs,week01,amannaik247" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 2 Progress Report by Aman Naik + +**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) +**Reporting Period:** 2025-06-09 – 2025-06-15 + +--- + +## Goals for This Week + +- **Goal 1:** Design a story builder feature to help children write stories +- **Goal 2:** Explore ways to integrate AI into the feature +- **Goal 3:** Document the architecture and workflow +- **Goal 4:** Focus on developing creative features that support learning + +--- + +## This Week’s Achievements + +1. **Explored Engaging Approaches to Story Writing** + - Through guidance from mentors in biweekly and one-on-one meetings, I explored effective ways to encourage children to write creatively. This included analyzing architecture ideas that support active participation in storytelling. + +2. **Finalized the Architecture for the Story Builder Feature** + - After research and discussions, I finalized an architecture that aids students in story writing while ensuring that the AI guides rather than writes the story for them. + +  + +  + +3. **Created Documentation for Future Reference** + - I’ve documented the feature's flow and design so it can be referred to later. [Link](https://docs.google.com/document/d/14V_FreatUU-gGgiHRdlvNDUXUgmBTWIeFyDaap38RnA/edit?usp=sharing) + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** The grammar correction feature was too strict for learning environments. + **Solution:** Since the goal is to foster creativity, I decided to shift focus from strict grammar correction to more engaging, story-focused features. Grammar support can be introduced later as an enhancement. + +- **Challenge:** Stories don’t always follow a fixed pattern (e.g., not every story has a villain). + **Solution:** I designed the AI to categorize responses into typical story elements automatically. This adaptive framework allows story parts like “villain” or “sidekick” to remain optional and dynamically appear based on user input. + +- **Challenge:** Prevent the AI from writing the story directly. + **Solution:** Due to the resource constraints of Sugar’s environment, I couldn’t run large models locally. I used Hugging Face Spaces to host the models externally and used their APIs inside Sugar for lightweight testing. This also helped keep the feature lightweight and modular. + +--- + +## Key Learnings + +**Developed Engaging Pedagogical Strategies for Story Writing** + - Mentors helped me explore interactive ways to encourage children’s creativity, shifting from passive AI responses to more guided interactions. + +**Designed and Finalized a Guided AI Architecture** + - I developed a modular design that prompts students to build stories step by step, ensuring they stay involved and learn narrative structure. + +**Learned Effective Student-AI Interaction Techniques** + - I realized that giving the AI a playful personality that gently prompts students can make the writing process more enjoyable and educational. + +--- + +## Next Week’s Roadmap + +- Begin coding the designed architecture +- Develop a basic Streamlit application to test the feature outside Sugar +- Work on feedback provided by mentors + +--- + +## References + +Here’s an insightful video shared by Walter Bender: +[CBS: The Thinking Machine (MIT Film, 1961)](https://www.youtube.com/watch?v=HCl19WKrfeg) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for their continued support and encouragement! + +--- +`,So=Object.freeze(Object.defineProperty({__proto__:null,default:Ve},Symbol.toStringTag,{value:"Module"})),Je=`--- +title: "DMP’25 Week 02 Update by Justin Charles" +excerpt: "Completed SVG path logic for all brick types and documented props and rendering states" +category: "DEVELOPER NEWS" +date: "2025-06-15" +slug: "2025-06-15-dmp-25-justin212407-week02" +author: "@/constants/MarkdownFiles/authors/justin-charles.md" +tags: "dmp25,sugarlabs,week2,justin212407" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 2 Progress Report by Justin Charles + +**Project:** Music Blocks 4 Masonry +**Mentors:** [Anindya Kundu](https://github.com/meganindya/) +**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Reporting Period:** 2025-06-09 - 2025-06-15 + +--- + + +## Goals for This Week + +- Finalize SVG path logic for all three types of bricks +- Categorize and document all props passed into bricks +- Identify all visual states a brick can be rendered in +- Differentiate props and states across brick types +- Write comprehensive tests to verify correctness + +--- + +## This Week’s Highlights + +### 1. Full SVG Path Generation Logic + +- Completed \`generatePath\` support for all three brick types (Simple, Expression and Compound) +- Rendering now properly reflects scaling, argument slots, top/bottom notches, and label widths +- Edge cases such as bricks with long labels or stacked arguments handled correctly + +### 2. Brick Input Prop Categorization + +- Catalogued all props across types (\`strokeWidth\`, \`scaleFactor\`, \`bBoxLabel\`, \`bBoxArgs\`, etc.) +- Documented their role in layout computation and how they influence final SVG shape + +### 3. Brick State Documentation + +- Mapped out all possible states a brick can be rendered in (e.g. with/without label, multiple args, missing notches) +- This will help improve clarity for both debugging and future features + +### 4. Type-wise Prop/State Differentiation + +- Clearly separated the logic for how each brick type handles its props and rendering states +- This abstraction allows brick-specific customizations without breaking general rendering flow + +### 5. Unified Brick Test File + +- Created a comprehensive Jest test file to validate path generation against expected output +- Covers edge cases like empty arguments, multiple stacked args, and variable heights + +📄 Reference: [Props & States Document – Tab 3](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.99d6uc7vheda) + +--- + +## Challenges & Solutions + +**Challenge: Mismatched Bounding Box Heights in Some Brick Types** +In initial tests, actual brick heights didn’t match the combined heights of \`bBoxLabel\` and \`bBoxArgs\`. +**Solution:** Identified a calculation flaw in vertical layout stacking. Corrected it by properly summing scaled heights and applying consistent spacing logic in path computation. + +**Challenge: Supporting All Brick Variants with Shared Logic** +Bricks share many layout rules, but also diverge in rendering. +**Solution:** Broke down \`generatePath\` into side-specific functions (\`_generateLeft\`, \`_generateRight\`, etc.) with override support depending on brick type and features like notches. + +--- + +## Key Learnings + +- Improved understanding of scalable vector graphics and path-based layout systems +- Gained hands-on experience in building testable, modular rendering logic +- Developed systematic thinking around UI state modeling and prop-driven rendering behavior + +--- + +## Next Week’s Roadmap + +- Create React Components(View) to render the bricks with all its properties. +- Create the Model components for the different Brick Types. + +--- + +## Resources & References + +- [Props & States Document](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.99d6uc7vheda) +- [musicblocks-v4 Repository](https://github.com/sugarlabs/musicblocks-v4) + +--- + +## Acknowledgments + +Thanks to my mentors for helping review the rendering logic and for encouraging a structured approach to SVG layout systems. Their early feedback made the path code significantly more robust and maintainable. + +--- +`,Io=Object.freeze(Object.defineProperty({__proto__:null,default:Je},Symbol.toStringTag,{value:"Module"})),Xe=`--- +title: "DMP ’25 Week 02 Update by Harshit Verma" +excerpt: "To develop a basic FastAPI server and integrate it with Pippy." +category: "DEVELOPER NEWS" +date: "2025-06-15" +slug: "2025-06-15-dmp-25-therealharshit-week02" +author: "@/constants/MarkdownFiles/authors/harshit-verma.md" +tags: "dmp25,sugarlabs,week02,therealharshit" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 02 Progress Report by Harshit Verma + +**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-09 - 2025-06-15 + +--- + +## Goals for This Week + +- **Goal 1:** Set up a basic FastAPI server. +- **Goal 2:** Integrate a Hugging Face model. +- **Goal 3:** Add 'Run and Debug' buttons to Pippy UI. +- **Goal 4:** Connect Pippy to the FastAPI Server. + +--- + +## This Week’s Achievements + +1. **Built FastAPI Server with \`/debug\` Endpoint** + - Created a simple FastAPI app that listens for POST requests at \`/debug\`. + - The endpoint accepts raw Python code, forwards it to the model, and returns debug tips. + +2. **Integrated Hugging Face Model** + - Loaded a lightweight model (Qwen/Qwen2.5-1.5B-Instruct) from Hugging Face using \`transformers\`. + - Connected the model with the \`/debug\` endpoint to generate relevant debugging suggestions. + +3. **Updated Pippy UI with Debugging Controls** + - Added 'Run and Debug' buttons to the Pippy interface. +  + - This was designed to trigger actions like execute code and get debugging feedback. + +4. **Connected Pippy to the FastAPI Server** + - Implemented functionality to extract code from the Pippy editor. + \`\`\`Python + #To extract the source code + + def _get_current_code(self): + pippy_tmp_dir = '%s/tmp/' % self.get_activity_root() + current_file = os.path.join( + pippy_tmp_dir, + self._source_tabs.get_current_file_name() + ) + + try: + with open(current_file, 'r') as f: + return f.read() + except Exception as e: + print(f"Error reading file {current_file}: {e}") + return None + \`\`\` + - Successfully set up an API call from Pippy to the FastAPI server when the 'Run and Debug' button is clicked. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Running the model locally on CPU. + **Solution:** Faced performance limitations due to lack of GPU support. I resolved this by selecting a small, efficient model from Hugging Face. + +- **Challenge:** Using GTK for Pippy UI integration. + **Solution:** Since GTK was new to me, adding buttons and handling events required exploring GTK documentation and existing Sugar activity patterns. With guidance and trial-and-error, I successfully added and wired up the 'Run and Debug' button to Pippy’s interface. + +--- + +## Key Learnings + +- Learned how to build and structure an API with FastAPI. +- Gained experience integrating Hugging Face models programmatically. +- Understood how to bridge frontend (Pippy) with backend (FastAPI) effectively. +- Improved at working across virtual machines, ports, and networking setups. + +--- + +## Next Week’s Roadmap + +- Improve prompt engineering for better debugging tips. +- Add visual display of debug tips in the Pippy interface. +- Integrate sugar-ai with Pippy. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! + +--- +`,Ao=Object.freeze(Object.defineProperty({__proto__:null,default:Xe},Symbol.toStringTag,{value:"Module"})),$e=`--- +title: "GSoC ’25 Week 02 Update by Bishoy Wadea" +excerpt: "Broken Calculator" +category: "DEVELOPER NEWS" +date: "2025-06-15" +slug: "gsoc-25-BishoyWadea-week01" +author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" +tags: "gsoc25,sugarlabs,week02,BishoyWadea" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Bishoy Wadea + +**Project:** [Broken Calculator](https://github.com/Bishoywadea/Broken-Calculator) +**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) +**Reporting Period:** 2025-06-08 - 2025-06-15 + +--- + +## Goals for This Week + +- **Goal 1:** Define game features and core mechanics. +- **Goal 2:** Design and plan a child-friendly, interactive game UI. +- **Goal 3:** Implement the core game logic. + +--- + +## This Week’s Achievements – *Broken Calculator Game* + +1. **Initial Setup & Core Functionality** + - Added starter files and project structure. + - Implemented basic game manager functionality to handle state, inputs, and equation validation. + - commit: [Initial Commit](https://github.com/Bishoywadea/Broken-Calculator/commit/9615fe64467e538e4b2d3df2ba6a0059177d31a7) + +2. **UI Foundation and Target Display** + - Created basic UI layout with the target number display. + - Integrated equation panel and on-screen keyboard for child-friendly input. + - commit: [UI Target + Equation Panel](https://github.com/Bishoywadea/Broken-Calculator/commit/fb52777a698d0846b3012140a796024edef5e577) + +3. **Button Logic and Interaction** + - Added calculator buttons and implemented event handling logic. + - Created class-based structure for reusable buttons and interactions. + - commit: [Calc Buttons Logic](https://github.com/Bishoywadea/Broken-Calculator/commit/f5201b9cf17c37fb70502fda55fd190b2143bca2) + +4. **Gameplay Enhancements** + - Added scoring system and validation logic for player input. + - Implemented completion message upon solving the puzzle correctly. + - commit: [Game Logic & Completion](https://github.com/Bishoywadea/Broken-Calculator/commit/2f985799faab59d590adae38b349c20dc0b432f9) + +5. **Visual & UX Improvements** + - Introduced dark theme palette for better visual experience. + - Added menu buttons, teacher image, and stars animation for child appeal. + - Relocated help button for better accessibility. + - commit: [UI/UX Polish](https://github.com/Bishoywadea/Broken-Calculator/commit/c97ade0610d606672a99522b944ed4ec24018c02) + +--- + +## Challenges & Solutions + +- **Challenge:** Handling math equation input using only a restricted set of digits/operators. + **Solution:** Wrote logic to dynamically validate inputs and compute results with constraints. + +- **Challenge:** Making the interface engaging for children. + **Solution:** Added animations, character images, and accessible visual elements. + +--- + +## Key Learnings + +- Gained proficiency in using **Pygame** for interactive game development. +- Improved understanding of **map projections** and **GeoJSON** parsing. +- Learned about structuring a project for open-source collaboration (commits, PRs, README, file organization). +- Practiced test-driven logic development and clean UI design tailored for children. + +--- + +## Key Learnings + +- Enhanced skills in **Pygame** UI design and interaction patterns. +- Practiced breaking down UI into components (buttons, input panels, layout regions). +- Understood how to make gameplay intuitive without written instructions—especially for kids. + +## Next Week’s Roadmap + +### Soma Cubes Game: Initial Insights & Exploration +- Begin designing core mechanics and gameplay flow for a Soma Cubes puzzle activity. +- Prototype user interactions: piece manipulation, rotation, and snapping into place. +- Investigate how to integrate puzzle constraints and feedback for users. +- Sketch out UI layout and controls tailored for children. + +--- + +### Fix Open Issues + +#### Four-Color Map Activity +- **[#1 Move buttons on the activity canvas to the activity toolbar](https://github.com/Bishoywadea/Four-Color-Map/issues/1)** + Adjust UI so that control buttons (e.g., Undo, Help, Menu) are relocated from the map canvas into a consistent toolbar above or beside it. +- **[#2 Sugarize activity icon](https://github.com/Bishoywadea/Four-Color-Map/issues/2)** + Update the icon to conform with Sugar activity design standards—ensure correct dimensions, transparency, and consistency with Sugar's visual language. + +#### Broken Calculator +- **[#1 Make calculator fill activity canvas](https://github.com/Bishoywadea/Broken-Calculator/issues/1)** + Refactor layout to scale the calculator panel to full canvas size at any screen resolution or window rescaling. +- **[#2 Improve UI](https://github.com/Bishoywadea/Broken-Calculator/issues/2)** + Polish button styles, spacing, theme consistency (light/dark), and overall visual clarity based on user feedback. + +--- +`,Lo=Object.freeze(Object.defineProperty({__proto__:null,default:$e},Symbol.toStringTag,{value:"Module"})),Ye=`--- +title: "GSoC '25 Week 02 Update by Nikhil Bhatt" +excerpt: "Implemented edit functionality for project repositories and introduced a forking mechanism for collaborative workflows." +category: "DEVELOPER NEWS" +date: "2025-06-10" +slug: "2025-06-10-gsoc-25-nikhilbhatt-week02" +author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" +tags: "gsoc25,sugarlabs,week02,nikhilbhatt" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 02 Progress Report by Nikhil Bhatt + +**Project:** [Git backend for Musicblocks](https://github.com/benikk/musicblocks-backend) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Reporting Period:** 2025-06-7 – 2025-06-14 + +--- + +## Goals for This Week + +- **Implement an edit route** to allow users to update project data securely using hashed keys. +- **Design and implement a forking mechanism** where users can fork existing project repositories into new independent ones. +- **Integrate project origin tracking** in forked repos through metadata. + +--- + +## This Week's Achievements + +1. **Edit Project Functionality** + - Created a secure API endpoint that allows users to update their project repository content using a key-authenticated system. + - The backend checks the key hash stored in the \`metaData.json\` before applying any updates. + - PR: [Edit Project API](https://github.com/BeNikk/musicblocks-backend/commit/1f61a089de7d8dbede2d46a101611133a1190bf6) + +2. **Fork Project Repository** + - Developed a new feature that enables students to fork other students' public projects into their own repositories under the same organization. + - Forked repositories retain original content (\`projectData.json\`, \`metaData.json\`) and include the original repository link in the metadata (\`forkedFrom\` field). + - PR: [Fork Feature](https://github.com/BeNikk/musicblocks-backend/commit/d1b7220476dc1fd58c1b38dc59c8a4991871ac45) + +3. **Project Metadata Enhancements** + - Updated the metadata structure to support fork tracking and improve key validation. + - Ensured consistency between project ownership, fork source, and editing rights. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Understanding and handling GitHub’s \`SHA\` and \`Base64\` requirements when editing file content through the API. + **Solution:** Read GitHub API docs and integrated \`Buffer.from(...).toString('base64')\` and used file \`sha\` to ensure proper file overwrites. + +- **Challenge:** Unsure if re-initializing Octokit and generating a new installation token per request was optimal. + **Solution:** Kept this approach for now as each request is stateless and works correctly. Optimization will be explored after baseline features are stable. + +--- + +## Key Learnings + +- Learned how to **authenticate and authorize edits** to GitHub repos using hashed keys and GitHub’s content API. +- Understood the internal structure of GitHub forks and metadata handling. +- Improved knowledge of **Octokit**, GitHub APIs, and best practices for writing file content (\`projectData.json\`, \`metaData.json\`) to a repo. + +--- + +## Next Week's Roadmap + +- Add **pull request functionality** between forked and original projects. +- Improve project listing UI with fork indicators. +- Begin planning for collaborator permissions and PR review workflow. + +--- + +## Resources & References + +- **GitHub API Docs:** [REST Reference](https://docs.github.com/en/rest) +- **Octokit:** [octokit/rest.js](https://github.com/octokit/rest.js) +- **MetaData Example:** \`metaData.json\` includes \`hashedKey\`, \`theme\`, and \`forkedFrom\`. + +--- + +## Acknowledgments + +Thank you to my mentors and the Sugar Labs community for guidance and feedback, and to the GitHub community for their detailed API documentation and tooling support. + +--- +`,To=Object.freeze(Object.defineProperty({__proto__:null,default:Ye},Symbol.toStringTag,{value:"Module"})),Qe=`--- +title: "GSoC '25 Week 2 Update by Safwan Sayeed" +excerpt: "Memory Module Architecture and CRUD Operations Development" +category: "DEVELOPER NEWS" +date: "2025-06-15" +slug: "2025-06-15-gsoc-25-sa-fw-an-week2" +author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" +tags: "gsoc25,sugarlabs,week2,sa-fw-an" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 2 Progress Report by Safwan Sayeed + +**Project:** Music Blocks 4 Program Engine +**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-06-09 - 2025-06-15 + +--- + +## A Blog-style Retrospective + +This week was all about diving deep into the memory architecture for the Music Blocks program engine. After completing our comprehensive AST framework in week 1, we shifted focus to building the foundational memory management system that will power program execution. The challenge was designing a three-scope memory hierarchy (Global, Thread, Local) with full CRUD operations while keeping the implementation clean and focused. + +Working alongside Karan Palan, we expanded our tech spec to include detailed memory module specifications. The mentors provided crucial guidance on scope requirements, emphasizing the need for thread isolation, and multi-level local scope support. + +--- + +## Goals for This Week + +- Complete the memory module technical specification with three-scope architecture details. +- Develop full CRUD operations for global variables accessible from any scope. +- Implement it with tests. + +--- + +## This Week's Highlights + +1. **Memory Module Tech Specification** + - Expanded the tech spec with comprehensive memory architecture documentation covering three-scope system. + - Detailed CRUD operation requirements for global, thread, and local scope variables. + - Link: [Tech Spec Document - Memory Section](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.3xe7coiooljb#heading=h.s3q9swsg3ifd) + + +2. **Memory Module CRUD Operations** + - Started Implementing the CRUD Operations for the Scopes + +--- + +## Challenges & Solutions + +- **Understanding Scope Hierarchy Complexity:** + The three-scope system (Global, Thread, Local) with proper variable shadowing was conceptually challenging. + *Solution:* Studied the existing reference implementation and created detailed diagrams to visualize scope relationships. + + +--- + +## Key Learnings + +- Mastered hierarchical data structure design with proper encapsulation and scope isolation. +- Gained deep understanding of variable shadowing and scope resolution mechanisms. +- Enhanced collaboration skills working on complex architecture with multiple contributors. + +--- + +## Next Week's Roadmap + +- Begin symbol table implementation building on the memory module foundation. +- IR Implementation +- Write comprehensive unit tests for all memory module CRUD operations. + +--- + +## Resources & References + +- **Tech Spec:** [Memory Module Architecture](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.3xe7coiooljb#heading=h.s3q9swsg3ifd) +- **Repository:** [musicblocks-v4](https://github.com/sugarlabs/musicblocks-v4) +- **Reference Implementation:** [For conceptual guidance](https://github.com/sugarlabs/musicblocks-v4-lib/tree/develop/src/execution/scopeexecution/scope) + +--- + +## Acknowledgments + +Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their detailed guidance on memory architecture design and scope management. Their clarification on keeping the focus on memory module fundamentals was crucial for this week's progress. + +---`,Po=Object.freeze(Object.defineProperty({__proto__:null,default:Qe},Symbol.toStringTag,{value:"Module"})),Ze=`--- +title: "GSoC ’25 Week 02 Update by Diwangshu Kakoty" +excerpt: "Multi-AI Agent Chat Model" +category: "DEVELOPER NEWS" +date: "2025-06-15" +slug: "diwangshu-kakoty" +author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" +tags: "gsoc25,sugarlabs,week02,AI" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 02 Progress Report by Diwangshu Kakoty + +**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) +**Reporting Period:** 2025-06-08 - 2025-06-14 + +--- + +## Goals for This Week + +- **Goal 1:** Develop a chat model consisting of multiple AI agents/mentors. +- **Goal 2:** Improve the 'Analysis' generation. +- **Goal 3:** Try and test different embedding models. +- **Goal 4:** Fix bugs occured by these changes. + +--- + +## This Week’s Achievements + +1. **AI Mentors** + - From the last meeting with my mentor, I received feedback on having specialised AI mentors for areas of expertise, such as music and coding. Hence, I have implemented a way to have conversations with mentors in music, code, and meta. + + - *Music Mentor* : Handles reflection for music learning. + + - *Code Mentor* : Handles programming concepts and debugging reflection. Users can paste their simplified project code for better feedback and guidance. + + - *Meta Facilitator* : Guides general reflective thinking (learning goals, struggles, progress). + +2. **Improve Analysis Generation** + - As mentioned in the last report, the analysis was inaccurate. I have refined the instructions, and now it functions effectively. It did not take much time. + +3. **Tested various Embedding Model** + - Embedding models are machine learning models that convert complex data such as text, images, or audio into numerical representations called embeddings. I am using \`all-MiniLM-L6-v2\`, which is lightweight and fast. Although it is lightweight, it is still quite effective. I have not found better models than this, so I will stick with this model for now. + +--- + +## Challenges & How I Overcame Them + +- **Challenge 1 :** The LLM needs to be invoked with the user query, retrieved context, and message history. Since this project involves multiple AI agents, it is somewhat tricky to decide what kind of memory space to use. Possible ways to store messages: + + i) Shared memory space: Each agent will use one common message history with named tags to differentiate among themselves. This way, the AI agents won't repeat questions. + + ii) Separate memory space: Each agent will have their own space. This way, we can prevent confusion for the LLM. However, the trade-off is space. Additionally, we need to pass these message histories separately for summary generation. + + **Solution:** I first implemented the second option because it is simple and works fine, but the summary generation needs to be done separately for each agent, which I don't think is ideal. Therefore, I have decided to try the first option. I have already started working on it. I need to fix some bugs, and it will be completed by tomorrow (2025-06-16). + +- **Challenge 2 :** Retrieved context is irrelevant when the project code is passed. The retriever component returns three chunks arranged in priority. However, a project code can contain many keywords, making the retriever not particularly useful. + + **Solution:** I am considering scanning all the keywords (like block names) first and passing their information to the LLM. This data will be stored in a dictionary. Example: + +\`\`\`python +blocks = { + "Action": "An Action block contains a sequence of actions that will only be executed when the block is referred to by something else, such as a start block.", + "Start": "A Start Block is an Action that will automatically be executed once the start button is pressed." +} +\`\`\` +This way the LLM can understand block structure and their meaning as well. + +--- + +## Key Learnings + +- The prototype for this project is developing in Streamlit, and I am learning Streamlit a lot. +- Also gainig experience in LangChain as this is the primary tool of development. + +--- + +## Next Week’s Roadmap + +- Work on things suggested by mentors. +- Fix challenge no. 2 as mentioned above. +- Start preparing for the frontend interface. + +--- + +## Resources & References + +- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) + + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,Co=Object.freeze(Object.defineProperty({__proto__:null,default:Ze},Symbol.toStringTag,{value:"Module"})),en=`--- +title: "GSoC ’25 Week 02 Update by Om Santosh Suneri" +excerpt: "To Develop a Basic RAG Debugger for Music Blocks" +category: "DEVELOPER NEWS" +date: "2025-06-14" +slug: "2025-06-14-gsoc-25-omsuneri-week02" +author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" +tags: "gsoc25,sugarlabs,week02,Debugger,AI,Music Blocks" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 02 Progress Report by Om Santosh Suneri + +**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) +**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) +**Reporting Period:** 2025-06-08 - 2025-06-14 + +--- + +## Goals for This Week + +- **Goal 1:** Enhance and Polish the Converter code +- **Goal 2:** To Make the JSON to Text Converter Publicly Accessible +- **Goal 3:** To Develop a Basic RAG Debugger for Music Blocks + +--- + +## This Week’s Achievements + +1. **Enhance and Polish the Converter code** + - I refined the output of the JSON to Text Converter by improving how blocks, parameters, and nested structures are represented. I also optimized the formatting and added clearer visual symbols to make the structure easier to follow. + - A well-structured and readable output is critical for debugging and learning. These enhancements make the converter not only functional but truly useful, especially for beginners who may be overwhelmed by raw JSON. The clarity improvements bridge the gap between raw code and conceptual understanding. + - GitHub Repository: [JSON to Text representation](https://github.com/omsuneri/JSON-to-Text-representation) + +2. **To Make the JSON to Text Converter Publicly Accessible** + - I deployed the Music Blocks JSON to Text Converter as a static web tool using GitHub Pages. This involved setting up the project structure for deployment, ensuring browser compatibility, and verifying that the tool works seamlessly for any user without needing local installation. + - By making the converter publicly accessible, I’ve removed a major barrier for non-technical users who want to understand or debug Music Blocks projects. Now, anyone can paste their JSON and instantly see a human-readable text format, making it easier to interpret the project logic, especially for educators and learners. + - JSON to Text Converter: [Live Demo](https://omsuneri.github.io/JSON-to-Text-representation/) + +3. **To Develop a Basic RAG Debugger for Music Blocks** + - I created the initial version of a Retrieval-Augmented Generation (RAG) app that acts as a debugger for Music Blocks. It uses Google Gemini (free API) for natural language responses and Qdrant as a vector database to search over relevant Music Blocks documentation and sample project data. + - This is the first step toward an AI-powered assistant that can help users understand errors, debug project files, and learn concepts interactively. It lays the groundwork for a smarter, more accessible debugging experience tailored specifically to the Music Blocks environment. + - GitHub Repository: [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) + +--- + + +## Challenges & How I Overcame Them + +- **Challenge:** Error 99 – Deployment Failure due to Network Binding + **Solution:** I updated the Gemini API implementation to avoid explicitly binding to a local address and ensured it followed the correct networking model for serverless deployment. I also verified that no hardcoded host values (like 127.0.0.1) were used and that the requests use standard internet routes. + +- **Challenge:** Reducing Container Size from 7.1 GB to Under 4 GB + **Solution:** I explored two approaches: + - Optimization: I removed redundant or unused files from the embedding directory and ensured the vector database stored only the most relevant documents. + - Cloud-based Embeddings: I evaluated storing the embeddings externally (e.g., by using a hosted Qdrant instance or remote storage) so that the app could load them at runtime, rather than bundling them in the container.These optimizations brought the container size within limits and made the app deployable on Railway. + +--- + +## Key Learnings + +- Deployment environments have strict constraints that require optimization and flexibility +I learned that successful deployment isn’t just about writing functional code — it's equally about managing resources (like container size) and handling platform-specific limitations, such as networking and storage. +- Early-stage AI apps benefit greatly from clear modularity and cloud-ready design +While building the RAG debugger, I realized the importance of designing components (like embeddings, API logic, and vector search) to be loosely coupled and scalable, which helps avoid technical roadblocks during cloud deployment. + +--- + +## Next Week’s Roadmap + +- Deploy the AI-Powered Debugger App to a Cloud Hosting Platform. +- Create Embeddings from Music Blocks Project Text Representations. +- Improve LLM Response Language for Kids and Junior Learners. + +--- + +## Resources & References + +- **Repository:** [JSON to Text representation](https://github.com/omsuneri/JSON-to-Text-representation) +- **Repository:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,Mo=Object.freeze(Object.defineProperty({__proto__:null,default:en},Symbol.toStringTag,{value:"Module"})),nn=`--- +title: "SSoC ’25 Week 02 Update by Muhammad Haroon" +excerpt: "Setting up AudioGen locally and building a simple user interface using Streamlit for generating audio from text." +category: "DEVELOPER NEWS" +date: "2025-06-15" +slug: "2025-06-15-ssoc-25-MuhammadHaroon-week02" +author: "@/constants/MarkdownFiles/authors/muhammad-haroon.md" +tags: "ssoc25,sugarlabs,week02,GenAI,MusicBlocks,Music" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 02 Progress Report by Muhammad Haroon + +**Project:** [Generative AI Instrument Sample Generation for Music Blocks](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md#Generative-AI-Instrument-Sample-Generation-for-Music-Blocks) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-09 - 2025-06-15 + +--- + +## Goals for This Week + +- **Goal 1:** Set up AudioGen locally. +- **Goal 2:** Create a UI using streamlit. + +--- + +## This Week's Achievements + +1. **Set up AudioGen locally** + - I was able to set up AudioGen locally for that I followed [AudioGen docs](https://github.com/facebookresearch/audiocraft/blob/main/docs/AUDIOGEN.md). I also created a virtual environment and a requirements.txt file to make the project easier to run. + +2. **Create a UI using streamlit** + - I also created a UI using streamlit with the help of the [Streamlit docs](https://docs.streamlit.io/). + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** The challenge I actually faced was due to limited resources. AudioCraft (which provides AudioGen) requires a GPU with at least 16 GB of memory for running inference with the medium-sized models (~1.5B parameters). For generating 5 minutes duration of audio, it took around 15-20 minutes. +- **Solution:** I ran the model and used the waiting time to complete other tasks. I plan to deploy the model on AWS, where I expect significantly better performance. + +--- + +## Key Learnings + +- Gained familiarity with **Streamlit** + +--- + +## Next Week's Roadmap + +- Generate more samples using AudioGen and save them in Google Drive. +- Experiment with temperature and top_p parameters in AudioGen. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,xo=Object.freeze(Object.defineProperty({__proto__:null,default:nn},Symbol.toStringTag,{value:"Module"})),tn=`--- +title: "GSoC ’25 Week 05 Update by Aditya Kumar Singh" +excerpt: "UI improvements, model fixes, skeletal updates, and continued localization work for the 3D Human Activity in Sugarizer." +category: "DEVELOPER NEWS" +date: "2025-06-17" +slug: "2025-06-17-gsoc-25-AdityaKrSingh26-week05" +author: "@/constants/MarkdownFiles/authors/aditya-singh.md" +description: "GSoC'25 Contributor at SugarLabs (Sugarizer Human Activity Pack)" +tags: "gsoc25,sugarlabs,week05,AdityaKrSingh26" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 05 Progress Report by Aditya Kumar Singh + +**Project:** [Sugarizer](https://github.com/llaske/sugarizer) +**Mentors:** [Lionel Laské](https://github.com/llaske) +**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) +**Reporting Period:** 2025-05-06 - 2025-06-12 + +--- + +## Goals for This Week + +- **Goal 1:** Fix and enhance model selection palette to reflect current selection. +- **Goal 2:** Refine and divide bones in the skeleton model for improved clarity and continue localization efforts for Human Activity. +- **Goal 3:** Improve organ model proportions (eye-mouth distance). +- **Goal 4:** Update UI layout for model filter (mode selector). +- **Goal 5:** Merge Paint and Learn mode to show a popup at bottom of screen when user click a part + +--- + +## This Week’s Achievements + +1. **Model Selection Palette Fix** + - Resolved issue where the palette UI did not reflect the currently selected model. + - Now dynamically highlights the active selection across Human, Skeleton, and Organs views. +  +  + +2. **Skeleton Bone Naming and Splitting Update** + - Expanded the skeletal model by splitting compound bones and renaming: + - For example, **“Arm”** is now divided into **Humerus**, **Radius**, and **Ulna**. + - Ensured correct orientation and geometry alignment across these divisions. + + +3. **Localization Progress** + - Continued translation integration using **i18next.js**. + - Initiated support for dynamically changing labels based on selected language. + + +4. **Organ Model Alignment Fix** + - Reduced the gap between eyes and mouth in the 3D organ model. + - Realigned surrounding features to maintain anatomical accuracy. +  + + +6. **Vertical Mode Selector UI Implementation** + - Reworked the mode selection UI to display vertically. + - Inspired by Dollar Street UI design, this improves accessibility. + - Earlier : +  + - Now : +  + + +7. **Merged Paint and Learn mode** + - Implemented a modal system that appears in the bottom-right corner when users click on body parts in paint mode. + - Added fade-in/fade-out transitions with CSS transforms for better user experience and added duplicate prevention system that removes existing modals before showing new ones. +  + + + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Maintaining proper alignment while modifying 3D organ models. + **Solution:** Used Blender’s measurement tools to iteratively adjust spacing, followed by live testing in the Sugarizer environment. + +- **Challenge:** Creating paint mode notifications that don't interfere with 3D interaction. + **Solution:** Developed bottom-right positioned modals with smooth animations and automatic cleanup to maintain workflow continuity while providing clear user feedback. + + +--- + +## Key Learnings + +- Gained experience in internationalization using i18next.js +- Learned UI layout best practices for improving accessibility across devices. +- Gained practical Blender experience for precision model editing. +- Developed more precise anatomical terminology awareness and importance of educational clarity. + +--- + +## Next Week’s Roadmap + +- Write Weekly Blog Post summarizing progress, screenshots, and key learnings. +- Reduce file size of the organ model to improve load time and performance across devices (optimize meshes, reduce texture resolution). +- Add an onboarding tutorial for users +- Create and integrate .json files containing metadata (name, position, mesh reference) for body parts and organs to simplify mesh mapping and future i18n support. +- Begin developing shared logic for **Paint Mode** and **Tour Mode**. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +## Connect with Me + +- GitHub: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) +- Gmail: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) +- LinkedIn: [Aditya Kumar Singh](https://www.linkedin.com/in/adityakrsingh26/) +- Twitter: [@AdityaKrSingh26](https://x.com/AdityaKrSingh26) + +--- +`,Go=Object.freeze(Object.defineProperty({__proto__:null,default:tn},Symbol.toStringTag,{value:"Module"})),an=`--- +title: "GSoC ’25 Week 06 Update by Aditya Kumar Singh" +excerpt: "Model optimizations, onboarding tutorial, adding json for body parts, and Shared mode enhancements in Paint Mode for the 3D Human Activity in Sugarizer." +category: "DEVELOPER NEWS" +date: "2025-06-20" +slug: "2025-06-20-gsoc-25-AdityaKrSingh26-week06" +author: "@/constants/MarkdownFiles/authors/aditya-singh.md" +tags: "gsoc25,sugarlabs,week06,AdityaKrSingh26" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 06 Progress Report by Aditya Kumar Singh + +**Project:** [Sugarizer](https://github.com/llaske/sugarizer) +**Mentors:** [Lionel Laské](https://github.com/llaske) +**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) +**Reporting Period:** 2025-05-12 - 2025-06-18 + +--- + +## Goals for This Week + +- **Goal 1:** Optimize organ model to reduce file size and improve performance. +- **Goal 2:** Add a onboarding tutorial for users. +- **Goal 3:** Improve organ model proportions (eye-mouth distance). +- **Goal 4:** Create and integrate \`.json\` file for body parts and organs. +- **Goal 5:** Enhancing shared mode logic for **Paint Mode**. + +--- + +## This Week’s Achievements + +1. ***Organ Model Optimization** + - Reduced the organ model size from **19MB to 5.92MB** by applying **Merge Vertices by Distance** and **Mesh Decimation** in Blender. + - These steps simplified mesh geometry while retaining anatomical accuracy. + - Resulted in faster loading on low-end devices and web platforms without compromising visual quality. + +2. **Onboarding Tutorial Integration** + - Implemented an interactive onboarding experience using the **Intro.js** library, following Sugarizer's developer tutorial guidelines. + - Integrated a custom help button in the toolbar (\`help.svg\`) to trigger the tutorial on demand. + - Defined tutorial steps in a dedicated \`tutorial.js\` module using \`introJs().setOptions()\` to guide users through the UI. + - Customized the UI using Sugarizer-themed CSS classes for a consistent visual style. + - Enabled full localization support using \`l10n.get()\` to adapt tutorial text based on the user’s language settings. +  +  + + +3. **Body Parts Metadata via JSON** + - Introduced a new \`.json\` file structure to define: + - **Name** + - **Mesh name** + - **Position (x, y, z)** + - Enables simpler mapping between UI and 3D model meshes. + - Supports future work on localization, click handling, and performance enhancements. + \`\`\`json + { + { "name": "Hair", "mesh": "Hair_mesh", "position": [-0.01, 7.03, -0.32] }, + { "name": "LeftEyebrow", "mesh": "Mesh0207_1", "position": [0.06, 6.69, 0.63] }, + { "name": "RightEyebrow", "mesh": "Mesh0207_3", "position": [0.06, 6.69, 0.63] }, + { "name": "Left Ear", "mesh": "leftear_mesh", "position": [0.62, 6.42, -0.13] }, + { "name": "Right Ear", "mesh": "righear_mesh", "position": [-0.53, 6.4, -0.13] }, + { "name": "Face", "mesh": "Face_mesh", "position": [0.05, 6.35, 0.36] }, + { "name": "Neck", "mesh": "Neck_mesh", "position": [0.04, 5.54, -0.23] }, + { "name": "Chest", "mesh": "Chest_mesh", "position": [0.04, 4.55, 0.11] }, + { "name": "Back", "mesh": "back_mesh", "position": [0.04, 3.78, -0.83] }, + { "name": "Stomach", "mesh": "stomach_mesh", "position": [0.04, 2.41, 0.2] }, + ... + } + + +4. **Shared Mode enhancements for Paint Mode** + - **Model sync:** when any participant switches to a different anatomical model, the client now emits a \`switchModel\` event; all connected users load the same model instantly. + - **Shared painting:** a \`paintPart\` broadcast (object name, color, body-part name, painter ID) lets everyone see the newly painted part in real time. A modal on each peer shows **“<user> painted: <part>”** for clear attribution. +  + + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Displaying context-aware feedback for painting actions without breaking UX flow. + **Solution:** Built a shared modal system that shows **“User X painted: Part Y”** without interrupting interactions. Ensured consistent color application using hex values and mesh IDs. + +- **Challenge:** Keeping the tutorial visually aligned with Sugarizer UI guidelines while supporting localization. + **Solution:** Customized Intro.js with Sugarizer-style buttons, icons, and tooltips. Integrated \`l10n.get()\` to provide multilingual support across tooltips, button labels, and descriptions. + + +--- + +## Key Learnings + +- Gained practical experience in implementing **real-time collaboration** using socket-based event broadcasting for 3D interactions. +- Learned how to **synchronize complex state changes** (like model switching, paint actions, and UI mode transitions) across multiple clients in a shared environment. +- Deepened understanding of **modular and scalable architecture** by separating shared logic into dedicated handlers and avoiding code duplication. + +--- + +## Next Week’s Roadmap + +- Write Weekly Blog Post summarizing progress, screenshots, and key learnings. +- Reduce file size of the organ model to improve load time and performance across devices (optimize meshes, reduce texture resolution). +- Add an onboarding tutorial for users +- Create and integrate .json files containing metadata (name, position, mesh reference) for body parts and organs to simplify mesh mapping and future i18n support. +- Begin developing shared logic for **Paint Mode** and **Tour Mode**. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,_o=Object.freeze(Object.defineProperty({__proto__:null,default:an},Symbol.toStringTag,{value:"Module"})),on=`--- +title: "DMP ’25 Week 3 Update by Aman Naik" +excerpt: "This week's focus was developing a working demo for the Story Builder feature using Streamlit and gathering mentor feedback for further improvements." +category: "DEVELOPER NEWS" +date: "2025-06-21" +slug: "2025-06-21-dmp-25-AmanNaik-week03" +author: "@/constants/MarkdownFiles/authors/amannaik247.md" +tags: "dmp25,writeactivity,write,sugarlabs,week03,amannaik247" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 3 Progress Report by Aman Naik + +**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) +**Reporting Period:** 2025-06-16 – 2025-06-21 + +--- + +## Goals for This Week + +- **Goal 1:** Develop a working demo of the Story Builder feature +- **Goal 2:** Implement the demo using Streamlit +- **Goal 3:** Gather feedback from mentors and plan improvements + +--- + +## This Week’s Achievements + +1. **Developed a Demo of the Story Builder Feature** + - Created a functional web application using Streamlit to demonstrate how the story builder AI guides students through storytelling. The demo mimics the question-and-answer-based flow and simulates an AI companion. + - Find the demo [here](https://story-builder-ai.streamlit.app/) + +  + +  + +2. **Presented the Demo to Mentors** + - Shared the working version with my mentors. I received positive feedback and valuable suggestions on what could be improved and how the feature can be enhanced with new ideas. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Designing a feedback loop where the AI accumulates all context from the student’s responses + **Solution:** After repeated iterations and research, I realized that assigning a distinct personality to the LLM helps it collect and remember context more naturally. This personality-driven approach ensures a more engaging and coherent interaction throughout the story-building process. + +--- + +## Key Learnings + +**Built and Deployed a Streamlit Demo to Simulate Story Interaction** + - Gained practical experience in using Streamlit to build and deploy web apps that demonstrate AI interaction flow for educational use cases. + +**Learned the Importance of AI Personality in Context Retention** + - Discovered that crafting an AI assistant with a personality improves its ability to retain context and makes the storytelling experience more relatable and fun for children. + +--- + +## Next Week’s Roadmap + +- Begin fine-tuning a language model using AWS +- Build a system where the AI recommends books similar to the student's story at the end of the conversation + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for their continuous guidance and valuable feedback! + +--- +`,Eo=Object.freeze(Object.defineProperty({__proto__:null,default:on},Symbol.toStringTag,{value:"Module"})),rn=`--- +title: "GSoC '25 Week 3 Update by Elwin Li" +excerpt: "Weekly progress report for JSEditor updates" +category: "DEVELOPER NEWS" +date: "2025-06-21" +slug: "2025-06-21-gsoc-25-Elwin-Li-week03" +author: "@/constants/MarkdownFiles/authors/elwin-li.md" +tags: "gsoc25,sugarlabs,week3,javaScript editor" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 3 Progress Report by Elwin Li + +**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/config_driven_conversion/elwin) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) + +**Reporting Period:** 2025-06-14 - 2025-06-21 + +--- + +## Goals for This Week + +- **Goal:** Start on debugger for musicblocks and JS editor. + +--- + +## This Week’s Achievements + +**Made Working Debugger** + +This week, I made a working debugger tool for Music Blocks JS editor. I added a button in the JS editor that is a toggle for the debug mode. On debug mode, users are able to add a breakpoint in any line of the code using buttons on the side of the line numbers. When the user then converts the code back to blocks, there are new debugger statement blocks that shows up. + +Then, when the user runs their code, execution will be paused at every debugger statement, and a status block with all the user defined and musicblocks defined variables up till that point will appear, showing the user those values, making it easy to debug. The user can then choose which variables they want to keep, and continue execution. This tool works perfectly with the run slowly and run step by step buttons, in order for more careful debugging. + +Also, I made block highlights contrast much more from original block colors, for easier tracking of which block is being executed. + +[youtube: jEJuXpyQbS8] + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Status blocks default to a set macro of variables + + **Solution:** Was able to go through the blocklist and single out needed variables to put in the status block instead + +--- + +## Key Learnings + +- Deepened understanding of how music blocks execution works +- Improved skills in **debugging**, **code design**, and **collaboration workflows**. + +--- + +## Next Week’s Roadmap + +- Finish debugger project (fix bugs) +- Add syntax highlighting to JSeditor code + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,Do=Object.freeze(Object.defineProperty({__proto__:null,default:rn},Symbol.toStringTag,{value:"Module"})),sn=`--- +title: "GSoC ’25 Week 03 Update by Mebin J Thattil" +excerpt: "Re-thinking training dataset structure" +category: "DEVELOPER NEWS" +date: "2025-06-21" +slug: "2025-06-21-gsoc-25-mebinthattil-week3" +author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" +tags: "gsoc25,sugarlabs,week03,mebinthattil,speak_activity" +image: "assets/Images/GSOCxSpeak.png" +--- + +<!-- markdownlint-disable --> + +# Week 03 Progress Report by Mebin J Thattil + +**Project:** [Speak Activity](https://github.com/sugarlabs/speak) +**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-14 - 2025-06-21 + +--- + +## Goals for This Week + +- **Goal 1:** Fix the issue for continious generation of chain of responses from model + +--- + +## This Week’s Achievements + +Note: _I'm officially on leave for this week and the next week, but I have however been taking calls and attending meetings, and did some light work in the background._ + +1. **Re-formatted the dataset to avoid generating chain of responses** + - Before the dataset had a records of conversations between a student and a teacher. Each record would have around 5-10 back-and-forth questions and interactions between the student and teacher. + - Since we were training on this dataset format, the model would also try to replicate this format - ie. it would start generating a chain of question-answer back and forths between the student and teacher. This is obviously something that we don't want. + - I initially kept it this way to teach the model better conversational flow, but this approach does more harm than help. + - So I have broken up the conversations and re-structured the conversations. + - I will now fine-tune it again on a subset of the dataset and deploy just to test it (_this is yet to be done_) + + +--- + +## Key Learnings + +- Structure of dataset needs to be changed, in order to make it more conversational and understand the nuances of a chain of conversations. + +--- + +## Next Week’s Roadmap + +- Train the model and evaluate it +- Also try to run [my model](https://huggingface.co/MebinThattil/FT-Llama3.2-1B/tree/main) that is on HF via Sugar-AI. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +`,jo=Object.freeze(Object.defineProperty({__proto__:null,default:sn},Symbol.toStringTag,{value:"Module"})),ln=`--- +title: "GSoC '25 Week 3 Update by Krish Pandya" +excerpt: "From initial GTK4 porting to building a solid foundation with separate C and Python libraries" +category: "DEVELOPER NEWS" +date: "2025-06-21" +slug: "2025-06-21-gsoc-25-mostlyk-week03" +author: "@/constants/MarkdownFiles/authors/krish-pandya.md" +tags: "gsoc25,sugarlabs,week03,mostlyk" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 3: Development on the C estabhlishment + +**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky), [Juan Pablo Ugarte](https://github.com/xjuan) +**Reporting Period:** June 14, 2025 till June 21, 2025 + +--- + + +## Following the meet of big change + +> On last to last Friday(06-06-2025), we had a pivotal video call with Juan Pablo Ugarte and Ibiam Chihurumnaya that completely reshaped the porting approach. +What started as a discussion about my initial porting work evolved into something much more strategic and forward-thinking. + +As discussed about these changes in the past week's blog, I have been continuing to update the C library. I have ported + +### Commited: + +- Sugar File Attributes ( in discussion of do we need to modernize or no) +- Event Controllers for Sugar ( handles clicks, movement etc. ) +- Long Press Controllers + +### Local: + +- Sugar Touch Controllers +- Building on top of them, zoom, swipe and rotate. + + +## Demonstration of the Controllers: + +<iframe width="560" height="315" src="https://www.youtube.com/embed/m0gwwo_0ZDE?si=M0ljKFFGuwAqAzrf" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> + +This video shows working example of Event Controller and Long Press controller. + +--- + +## PR Deep Dive + +### Review & Iteration + +The review process was thorough and collaborative, with mentors providing feedback on: + +- API and Versioning: Ensuring symbol and identifier prefixes followed conventions, and clarifying versioning strategy to align with Sugar’s release cycle. +- Code Structure: Moving away from including XO Colors in the C library (to be handled in Python). +- Licensing: Correctly attributing copyright and following LGPL-2.1. ( As discussed in last week's blog for the versioning ). +- Formatting: Retaining original code formatting for readability, and avoiding unnecessary changes from auto-formatters. +- Build System: Making examples optional in the build, and keeping the project modular. + +### Modernization Decisions + +A key discussion was around modernizing the file attributes utility using GLib APIs. My rationale was to unify the codebase under a modern standard, leveraging GLib for better error handling and maintainability. However, Ibiam and James highlighted the importance of compatibility with filesystems like FAT32, and the need to test on real hardware. I will be formatting my USB to test this soon. I will keep it as a TODO for now. + +### Testing + +Every ported module includes comprehensive tests. Just do the following to test: + +\`\`\`bash +meson test -C builddir +\`\`\` + +The tests cover attribute creation, setting/getting values, and simulating real-world activity workflows. I plan to continue this rigorous testing approach for all future modules as always , yours truly Krish. + +### Lessons Learned + +- Consistency matters - Unifying the codebase under GLib/GTK4 improves maintainability, but must be balanced with legacy compatibility. +- Testing is critical - Automated and example-based tests are essential for safe modernization. +- Documentation and commit messages - Clear explanations of why changes are made (not just what) are crucial for future maintainers. + + _I am still learning on how to improve all of these , especially commit messages_ + +--- + +# Apart from Porting + +Outside of the core Sugar porting work, I also spent some time tinkering (_I love music_) some side projects for MusicBlocks and SL: + +- AWS & SoundScape: I continued working on [SoundScape](https://soundscape.streamlit.app/), the audio processing web app. +This week, I wanted to update the platform to include an SheetMusic-To-MusicXML model in addition to existing Audio-to-Sheet-Music model and Audio-to-MIDI functionality. +I sadly was using Oemer and my own system rqreuiement were not capable enough to run it . + +- Machine Learning Experiments: I tried running [Oemer](https://github.com/BreezeWhite/oemer), an open-source Optical Music Recognition tool.So I’m planning to set up a dedicated AWS instance for further testing and integration. And if that works out I can deploy by dockerizing SoundScape. + +Overall, I like tinkering with these kinds of projects and learn more about foundational models. + +To someone who is interested in research and wants a tool to have beside reading papers you can check [Dread-Rising](https://dread-rising.streamlit.app/). It can also be used for someone who just wants to read a book , or an article, you can get highlighted version of the PDF, multiple understanding and can do in-depth. + +These small problems that I tackle using my pre-existing knowledge on LLMs and Python help me in porting as well, even though it's a completely different side of project which is writing a C library right now, the skills and thinking translate a lot and I have fun! + +## Resources & References + +- Project Page – [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) +- New C Library - [sugar-ext repository](https://github.com/sugarlabs/sugar-ext) +- Active PR - [Establish C library base template with Meson for GTK4](https://github.com/sugarlabs/sugar-ext/pull/1) +- Sugar Toolkit Repository(original) – [sugar-toolkit-gtk3](https://github.com/sugarlabs/sugar-toolkit-gtk3) +- GTK4 Migration Guide – [docs.gtk.org/gtk4/migrating-3to4.html](https://docs.gtk.org/gtk4/migrating-3to4.html) + + +--- + +## Acknowledgments + +Huge thanks to Juan Pablo Ugarte first of all for being the official mentor and Ibiam Chihurumnaya for the guidance that that changed this project's direction. Their architectural vision has transformed porting into a comprehensive modernization effort. Thanks also to Walter Bender for mentorship. +`,Wo=Object.freeze(Object.defineProperty({__proto__:null,default:ln},Symbol.toStringTag,{value:"Module"})),dn=`--- +title: "DMP’25 Week 03 Update by Justin Charles" +excerpt: "Completed SVG path logic for all brick types and documented props and rendering states" +category: "DEVELOPER NEWS" +date: "2025-06-22" +slug: "2025-06-22-dmp-25-justin212407-week03" +author: "@/constants/MarkdownFiles/authors/justin-charles.md" +tags: "dmp25,sugarlabs,week3,justin212407" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 3 Progress Report by Justin Charles + +**Project:** Music Blocks 4 Maosonry +**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-06-15 - 2025-06-22 + +--- + + +## Goals for This Week + +- Design an algorithm for parsing and rendering the brick tree via React components +- Expose bounding box and connection point data from the model layer +- Create a prop interface for passing this spatial data into the rendering layer + +--- + +## This Week’s Highlights + +### 1. **Visual Tree Parsing and Rendering Algorithm** + +Developed a clean, maintainable algorithm to traverse and render the brick tree structure: +- Each tree node is transformed into a React component, preserving parent-child and neighbor relationships +- Recursive traversal ensures dynamic rendering of nested bricks +- Designed to integrate seamlessly with \`BrickTreeManager\` and individual brick models + +### 2. **Exposed Geometric Metadata in Brick Models** + +Implemented structured public getters and setters to handle: +- **Bounding Box (bbox)**: x, y, width, and height of each rendered brick +- **Connection Point Coordinates**: Vary based on brick type (Simple, Expression, Compound) +- Enables precise layout, collision detection, and advanced interaction logic downstream + +### 3. **Visual Data Propagation via React Props** + +Added a new prop to the core brick rendering components: +- Accepts a callback function +- Receives \`bbox\` and connection point data as arguments after render +- Supports future enhancements like: + - Overlay-based debugging + - Adaptive layout reflows + - External visualization tools + +📄 Reference for parsing algorithm: [Tab 5](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.99d6uc7vheda) + +--- + +## Challenges & Solutions + +**Challenge: Finding the right parsing algorithm for parsing the tree** +**Solution:** Implemented stack based traversal with visited node tracking and component key management + +**Challenge: The tree parsing algorithm struggled to correctly identify and maintain parent-child relationships when bricks had multiple connection points or nested expressions** + +**Solution:** Implemented a two-pass algorithm - first pass builds the node structure, second pass establishes parent-child references and validates connection integrity + +--- + +## Key Learnings + +- Algorithm Design + +Recursive Patterns: Learned how to structure recursive algorithms for tree traversal that map cleanly to React component hierarchies +Data Structure Mapping: Understanding how to translate tree data structures into renderable React components + +--- + +## Next Week’s Roadmap + +- Render the tree upon the storybook given any configuration of bricks. +- List down all the bricks and their configurations. +- Create the pallete UI with all types of bricks present in it. + +--- + +## Resources & References + +- [musicblocks-v4 Repository](https://github.com/sugarlabs/musicblocks-v4) +- [musicblocks-v4 Tech Spec Document](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.0#heading=h.gtbrgbbwfht3) +--- + +## Acknowledgments + +Thanks to my mentors for helping review the algorithm logic for rendering the tree. Their early feedback made the path code significantly more robust and maintainable. + +--- +`,Oo=Object.freeze(Object.defineProperty({__proto__:null,default:dn},Symbol.toStringTag,{value:"Module"})),cn=`--- +title: "DMP '25 Week 03 Update by Anvita Prasad" +excerpt: "Implementation of tuner visualization system and dual-mode interface" +category: "DEVELOPER NEWS" +date: "2025-06-22" +slug: "2025-06-22-DMP-25-AnvitaPrasad-week03" +author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" +tags: "dmp25,sugarlabs,week03,AnvitaPrasad" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 03 Progress Report by Anvita Prasad + +**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) +**Mentors:** [Walter Bender](https://github.com/walterbender) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-16 - 2025-06-22 + +--- + +## Goals for This Week +- **Goal 1:** Implement dual-mode tuner interface +- **Goal 2:** Complete basic cents adjustment UI implementation +- **Goal 3:** Enhance tuner visualization system +- **Goal 4:** Test with various audio sources and instruments + +--- + +## This Week's Achievements + +1. **Dual-Mode Tuner Implementation** + - Successfully implemented a toggle button interface for switching between two tuner modes + - Developed chromatic mode where target pitch moves based on input pitch + - Implemented logic for finding closest chromatic pitch within +/- 50 cents + - Added cent deviation value display under the tuner + - Started work on specific target pitch mode implementation + - Gathered feedback for further refinements + +2. **Cents Adjustment UI Development** + - Implemented basic cents adjustment interface + +3. **Tuner Visualization Enhancements** + - Made refinements to last week's visualization system + - Added clear visual feedback for cent deviation + - Enhanced visual clarity for pitch detection feedback + +4. **Testing Progress** + - Conducted initial testing with various audio sources + - Identified areas for improvement in pitch detection + - Created a test suite for tuner accuracy verification + +5. **Audio Processing Improvements** + - Implemented low-pass filtering to handle high-frequency noise + - Enhanced pitch detection accuracy using parabolic interpolation + - Optimized signal processing for better performance + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Creating an intuitive UI for mode switching + **Solution:** Implemented a clear toggle interface with visual indicators for current mode + +- **Challenge:** Dealing with high-frequency noise in audio signal + **Solution:** Implemented low-pass filtering to improve signal quality and enhance pitch detection accuracy + +--- + +## Key Learnings + +- Learned about signal processing techniques like low-pass filtering and its impact on audio quality +- Gained insights into sub-cent accuracy through parabolic interpolation in pitch detection + +--- + +## Next Week's Roadmap + +- Complete and refine target pitch mode implementation +- Implement manual cent adjustment functionality +- Finalize design for cent adjustment interface +- Conduct comprehensive testing with various audio sources and instruments +- Deliverable: Fully functional tuner with cents adjustment + +--- + +## Resources & References + +- [Web Audio API Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) +- [Audio Filters Guide](https://blog.native-instruments.com/audio-filters-guide/) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support. + +--- `,Bo=Object.freeze(Object.defineProperty({__proto__:null,default:cn},Symbol.toStringTag,{value:"Module"})),un=`--- +title: "GSoC ’25 Week 03 Update by Bishoy Wadea" +excerpt: "Broken Calculator" +category: "DEVELOPER NEWS" +date: "2025-06-22" +slug: "gsoc-25-BishoyWadea-week03" +author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" +tags: "gsoc25,sugarlabs,week03,BishoyWadea" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 03 Progress Report by Bishoy Wadea + +**Project:** [Broken Calculator](https://github.com/Bishoywadea/Broken-Calculator) +**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) +**Reporting Period:** 2025-06-22 - 2025-06-28 + +--- + +## Goals for This Week + +- **Goal 1:** Fix issues in Four Color Map game opened by ibiam [Move buttons from canvas to tool bar](https://github.com/Bishoywadea/Four-Color-Map/issues/1), [Sugarize activity icon](https://github.com/Bishoywadea/Four-Color-Map/issues/2), [adding lisence to activity](https://github.com/Bishoywadea/Four-Color-Map/issues/3). + + + +- **Goal 2:** Fix issues in Broken Calculator game opened by ibiam [change UI to be more focused](https://github.com/Bishoywadea/Broken-Calculator/issues/2). + + +--- + +## This Week’s Achievements + +### *Goal 1: Fix Issues in Four Color Map Activity* + +1. **Moved Control Buttons to Toolbar** + - Relocated in-canvas buttons (Undo, Help, Menu) to a proper activity toolbar for a more intuitive UI layout. + - PR: [Move Buttons to Toolbar](https://github.com/Bishoywadea/Four-Color-Map/pull/5) + +2. **Sugarized the Activity Icon** + - Designed and applied a new icon that follows Sugar activity standards in shape, color, and transparency. + - PR: [Sugarized Icon](https://github.com/Bishoywadea/Four-Color-Map/pull/6) + +3. **Added License File** + - Included a standard open-source license file in the repo, ensuring compliance with FOSS guidelines. + - PR: [Add License](https://github.com/Bishoywadea/Four-Color-Map/pull/7) + +--- + +### *Goal 2: Improve Broken Calculator UI & UX* + +1. **Redesigned UI for Focused Gameplay** + - Refactored layout to fill the canvas with the calculator interface and decluttered extra elements. + - commit: [Canvas Layout Update](https://github.com/Bishoywadea/Broken-Calculator/commit/7ec076475ae1c7e77c96a6ae155b151681fa724a) + +--- + +## Challenges & Solutions + +- **Challenge:** Migrating control elements from canvas to toolbar in Four Color Map. + **Solution:** Familiarized myself with the Sugar toolbar API and successfully relocated buttons, improving UI consistency. + +- **Challenge:** Making the interface engaging for children. + **Solution:** Added animations, character images, and accessible visual elements. + +--- + +## Key Learnings + +- Deepened experience working with **Sugar activity design standards**, including toolbars and icon sugarization. +- Gained hands-on experience applying **open-source contribution practices**—issue tracking, commit hygiene, licensing, and documentation. +- Practiced creating UI/UX for young learners, focusing on minimalism, feedback clarity, and visual accessibility. + +--- + +## Next Week’s Roadmap + +### Soma Cubes Game: Initial Insights & Exploration +- Begin designing core mechanics and gameplay flow for a Soma Cubes puzzle activity. +- Prototype user interactions: piece manipulation, rotation, and snapping into place. +- Investigate how to integrate puzzle constraints and feedback for users. +- Sketch out UI layout and controls tailored for children. + +--- + +### Fix Open Issues + +#### Four-Color Map Activity +- **[#4 Make activity pep8 compliant](https://github.com/Bishoywadea/Four-Color-Map/issues/4)** + The activity isn't pep8 compliant. + +--- +`,Ro=Object.freeze(Object.defineProperty({__proto__:null,default:un},Symbol.toStringTag,{value:"Module"})),hn=`--- +title: "GSoC '25 Week 03 Update by Nikhil Bhatt" +excerpt: "Set up backend routes for creating and viewing pull requests on MusicBlocks project repositories." +category: "DEVELOPER NEWS" +date: "2025-06-17" +slug: "2025-06-17-gsoc-25-nikhilbhatt-week03" +author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" +tags: "gsoc25,sugarlabs,week03,nikhilbhatt" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 03 Progress Report by Nikhil Bhatt + +**Project:** [Git backend for MusicBlocks](https://github.com/benikk/musicblocks-backend) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Reporting Period:** 2025-06-15 – 2025-06-21 + +--- + +## Goals for This Week + +- Add backend support for creating pull requests when someone edits a forked project. +- Allow project maintainers to view all incoming pull requests to their original project repo. +--- + +## This Week's Achievements + +1. **Created Pull Request Route** + - Built a route where students who forked a project can submit updates. + - The backend automatically creates a **new branch on the original repository**, updates the \`projectData.json\`, and creates a pull request from that branch to the main branch. + - We use the original repository info stored in \`metaData.json\` of the forked project. + - Only two values are required from the frontend: the name of the fork repo and the updated \`projectData\`. + +2. **View All Pull Requests Route** + - Added another route that **lists all open pull requests** for a given repository. + - Maintainers can use this to preview incoming contributions. + - In the future, clicking “merge” on the frontend will trigger the same \`edit\` route we already have, safely updating the project. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** GitHub’s API does not allow opening pull requests between two repos in the **same organization** (which is our setup for MusicBlocks). + **Solution:** Instead of trying to PR from a forked repo to the original, we create a **new branch directly in the original repo** and update content from the backend. Then we make a PR from that new branch to \`main\`. + +- **Challenge:** Figuring out the cleanest flow with the least frontend involvement. + **Solution:** Used the backend to handle metadata extraction, branch creation, commit, and PR creation automatically, so the frontend only needs to pass minimal data. + +--- + +## Key Learnings + +- Understood GitHub's limitations when working with forks in the same organization. +- Learned how to manage pull request creation with custom branches and automated commits. +- Improved backend architecture by centralizing logic and reducing frontend responsibility. + +--- + +### An interesting problem to solve + +Currently, since all project repositories (original and forks) are created under the same GitHub organization using a central GitHub App, all commits and pull requests appear to be made by the original repo,and since our setup is such that we create Pull request through a branch in the original repository (We cannot do that from a repo in the same org account) we cannot keep a track of which fork's commit was merged. + +Workaround + +As a workaround, fork project's details can now be stored in the \`metaData.json\` of each forked project. When viewing pull requests via the custom route, this data can be used to show who contributed what. + + +## Next Week's Roadmap + +- **Start frontend development**: Add interfaces for users to view, submit, and merge pull requests. +- Add UI indicators for forked projects and pull request status. +- Improve display of \`projectData\` in pull request previews. + +--- + +## Resources & References + +- **GitHub PR API Docs:** [docs.github.com/rest/pulls](https://docs.github.com/en/rest/pulls/pulls) +- **Octokit REST Library:** [github.com/octokit/rest.js](https://github.com/octokit/rest.js) +- **Backend Repo:** [musicblocks-backend](https://github.com/benikk/musicblocks-backend) + +--- + +## Acknowledgments + +Big thanks to my mentors and the Sugar Labs community for their guidance and patience. Also grateful to GitHub’s documentation which helped solve tricky API issues. + +--- +`,zo=Object.freeze(Object.defineProperty({__proto__:null,default:hn},Symbol.toStringTag,{value:"Module"})),gn=`--- +title: "GSoC '25 Week 3 Update by Safwan Sayeed" +excerpt: "AST to IR Compilation Logic and Pseudocode Implementation" +category: "DEVELOPER NEWS" +date: "2025-06-22" +slug: "2025-06-22-gsoc-25-sa-fw-an-week3" +author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" +tags: "gsoc25,sugarlabs,week3,sa-fw-an" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 3 Progress Report by Safwan Sayeed + +**Project:** Music Blocks 4 Program Engine +**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-06-16 - 2025-06-22 + +--- + +## A Blog-style Retrospective + +This week marked a significant milestone in our Music Blocks program engine development as we transitioned from the foundational memory architecture to the core compilation logic. The focus shifted to implementing the AST-to-IR (Intermediate Representation) translation layer - the crucial bridge between our abstract syntax tree representation and executable code. + +The challenge was designing a static compilation system that converts AST nodes into a linear sequence of IR instructions, following the three-address code format. Working with complex expression hierarchies and statement blocks required careful consideration of instruction ordering and variable management. + +Our mentors provided invaluable guidance on maintaining the static nature of the compilation process, emphasizing that we're translating program structure rather than executing runtime calculations. This distinction was crucial for keeping our implementation focused and efficient. + +--- + +## Goals for This Week + +- Complete the AST-to-IR compilation logic technical specification with detailed pseudocode patterns. +- Implement evaluate() methods for all expression classes returning instruction lists. +- Develop pseudocode for simple statements following the established IR generation patterns. +- Design the instruction chaining mechanism for complex nested expressions. + +--- + +## This Week's Highlights + +1. **IR Compilation Logic Specification** + - Expanded the tech spec with comprehensive AST-to-IR translation documentation covering expression and statement compilation patterns. + - Detailed instruction list generation requirements and variable management strategies. + - Link: [IR Compilation Logic](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.i655udul8zuq) + +2. **AST-to-IR Pseudocode Implementation** + - Implemented evaluate() methods for all expression classes (Literal, Binary/Unary Operators, Arrays, Dictionaries, etc.) + - Developed instruction list generation patterns following three-address code format + - Created symbol table integration using sym_query, sym_declare, and sym_assign operations + - Link: [Tech Spec Document - AST to IR Methods](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.87123fra3s4#heading=h.gqjcwrtkdgvq) + +3. **Simple Statements Compilation Logic** + - Implemented pseudocode for VariableDeclarationStatement, VariableAssignmentStatement, FunctionCallStatement, and JumpStatement + - Established parameter passing patterns for evaluate() methods ensuring proper instruction dependency chains + +--- + +## Challenges & Solutions + +- **Understanding Static vs Runtime Compilation:** + Initially confused about whether we were performing runtime calculations or static code translation. + *Solution:* Mentors clarified that this is purely static AST-to-IR conversion with no runtime execution, helping focus the implementation approach. + + +--- + +## Key Learnings + +- Mastered the distinction between static compilation and runtime execution in compiler design. +- Gained deep understanding of three-address code generation and instruction dependency management. +- Enhanced skills in designing clean pseudocode patterns that can be translated to actual implementation. +- Learned the importance of maintaining consistent parameter passing patterns across class hierarchies. + +--- + +## Next Week's Roadmap + +- Implement pseudocode for compound statements. +- Design basic block generation logic for control flow structures. +--- + +## Resources & References + +- **Tech Spec:** [IR Compilation Logic](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.i655udul8zuq) +- **Tech Spec:** [AST to IR Methods](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.87123fra3s4#heading=h.gqjcwrtkdgvq) +- **Repository:** [musicblocks-v4](https://github.com/sugarlabs/musicblocks-v4) + +--- + +## Acknowledgments + +Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their crucial guidance on compiler design principles and static compilation concepts. Their clarification on the AST-to-IR translation approach and emphasis on maintaining clean instruction generation patterns was essential for this week's successful progress. + +---`,Uo=Object.freeze(Object.defineProperty({__proto__:null,default:gn},Symbol.toStringTag,{value:"Module"})),mn=`--- +title: "GSoC ’25 Week 03 Update by Diwangshu Kakoty" +excerpt: "AI with Reasoning Capabilities" +category: "DEVELOPER NEWS" +date: "2025-06-22" +slug: "2025-06-22-gsoc-25-diwangshu-week03" +author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" +tags: "gsoc25,sugarlabs,week03,AI" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 03 Progress Report by Diwangshu Kakoty + +**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) +**Reporting Period:** 2025-06-15 - 2025-06-21 + +--- + +## Goals for This Week + +- **Goal 1:** Implement streaming response by LLM. +- **Goal 2:** Improve context passing for project code. +- **Goal 3:** Experiment and test different Gemini models and their capabilities. +- **Goal 4:** Fix bugs occured by these changes. +- **Goal 5:** Test the multi-agent chat model. + +--- + +## This Week’s Achievements + +1. **Implemented streaming response by LLM** + - I have implemented streaming responses from the LLM. This allows the model to send partial responses as they are generated, which is particularly useful for long responses. The implementation is straightforward and works well with the current setup. + +2. **Improved context passing for project code** + - As mentioned in the last report, the retrieved context was not particularly useful when passing project code. + + - I have improved this by scanning all keywords (like block names) first and passing their information to the LLM. This data is stored in a dictionary, which allows the LLM to understand the block structure and their meanings better. + +3. **Experiment and test different Gemini models and their capabilities** + - I have experimented with various Gemini models, including \`gemini-1.5-flash\`, \`gemini-2.0-flash\`, \`gemini-2.0-flash-lite\` and \`gemini-2.5-flash\`. + + - The most interesting one is \`gemini-2.5-flash\`, because of its 'thinking' capability. I did not know that Gemini models had this feature. The 'thinking' capability provides quality responses by breaking down complex queries into smaller, manageable parts. This could be very useful for the LLM to understand the project code or any other complex queries. + + - The RPM (Requests per minute) of \`gemini-2.5-flash\` is 10 and TPM (Tokens per minute) is 250,000. When 'thinking\` is enabled a different token is used called 'thinking token'. We can specify the number of thinking tokens to be used or it can be set to auto. Threrefore, the thinking capability should be used for complex queries only, as it consumes more tokens and is slower than the regular response. + +--- + +## Challenges & How I Overcame Them + +- **Challenge :** I am trying to implement the 'thinking' capability of the Gemini model, but I am facing some issues with the response format. The model is not returning the expected structured response when 'thinking' is enabled. Their are not many resources on this topic. + + **Solution:** I found that the official Gemini documentation is the best resource for understanding how to implement this feature. I am currently working on it and hope to resolve the issue soon. + +--- + +## Key Learnings + +- I have realised one thing for sure, that a developer has to rely on the official documentation of any technology or library they are owrking on. As a student I often tend to look for tutorials or blog posts, but they are not always reliable or up-to-date. The official documentation is the most accurate and comprehensive resource. + +--- + +## Next Week’s Roadmap + +- Work on things suggested by mentors. This could include: + - Improving the multi-agent chat model. + - Testing the multi-agent chat model with different Gemini models. +- Discuss with mentors about the 'thinking' capability of the Gemini model. On what kind of queries it can be used. +- Implement the 'thinking' capability in the multi-agent chat model. + +--- + +## Resources & References + +- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,Fo=Object.freeze(Object.defineProperty({__proto__:null,default:mn},Symbol.toStringTag,{value:"Module"})),pn=`--- +title: "GSoC’25 Week 03 Update by Om Santosh Suneri" +excerpt: "To Develop a Basic RAG Debugger for Music Blocks" +category: "DEVELOPER NEWS" +date: "2025-06-22" +slug: "2025-06-22-gsoc-25-omsuneri-week03" +author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" +tags: "gsoc25,sugarlabs,week03,Debugger,AI,Music Blocks" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 03 Progress Report by Om Santosh Suneri + +**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) +**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) +**Reporting Period:** 2025-06-15 - 2025-06-21 + +--- + +## Goals for This Week + +- **Goal 1:** Deploy the AI-Powered Debugger App to a Cloud Hosting Platform +- **Goal 2:** Create Embeddings from Music Blocks Project Text Representations +- **Goal 3:** Improve LLM Response Language for Kids and Junior Learners + +--- + +## This Week’s Achievements + +1. **Deploy the AI-Powered Debugger App to a Cloud Hosting Platform** + - This week, I successfully deployed the AI-Powered Debugger application on Streamlit Cloud, making it publicly accessible to anyone interested in testing it. The deployment process included optimizing the app structure for cloud compatibility, setting up environmental variables securely, and ensuring a smooth user experience. The live deployment now allows users—especially educators, learners, and developers—to interact with the debugger without needing to set up anything locally. + - Making the debugger accessible via the web marks a major step in making AI tools more usable and available to the community. It enables initial-stage testing by real users, which is essential for collecting feedback and observing how the debugger performs across different user behaviors. This helps build a feedback loop that will guide future improvements and robustness of the tool, making it more valuable in the long term. + +2. **Create Embeddings from Music Blocks Project Text Representations** + - After performing some minor improvements to the Music Blocks JSON-to-text converter, I selected 14 representative projects from the Music Blocks examples directory. These projects span across a range of tags and categories—such as music composition, transcription, games, utilities, and miscellaneous projects. I then generated vector embeddings for the textual representations of these projects and stored them in a Qdrant vector database cluster. + - These embeddings serve as the foundation for teaching the LLM about the structure and semantics of real-world Music Blocks projects. By creating a searchable knowledge base of real examples, we are equipping the LLM with contextual understanding of how blocks are logically connected and used in different domains. This will significantly improve the LLM’s ability to understand, explain, and debug Music Blocks code based on actual use cases, making it more intelligent and helpful in practice. + +3. **Improve LLM Response Language for Kids and Junior Learners** + - To make the debugger more inclusive and approachable for younger audiences, I updated the LLM prompt with additional guidance that instructs the model to assume the user is a child or junior learner. This involved reworking how queries are framed when sent to the LLM, prompting it to respond in a simpler, clearer, and more encouraging language style suitable for kids. + - Music Blocks is widely used in educational environments, especially among school-age children learning to code. By making the language of AI responses more kid-friendly, we ensure that young learners can better understand and learn from the debugger’s suggestions. This step plays a key role in increasing the educational value, accessibility, and inclusivity of the project, ultimately making learning more fun and effective for our target audience. + +--- + + +## Challenges & How I Overcame Them + +- **Challenge:** Improving ingest.py to Create Embeddings Efficiently + **Solution:** I enhanced the ingest.py script to process the improved text representations generated from various Music Blocks projects. I created and configured a Qdrant cluster to store the generated embeddings. This allowed me to index 14 representative projects across different categories. The modified script now supports smoother ingestion of data into Qdrant, and the embeddings are successfully retrievable for use by the LLM. This improvement lays the foundation for more intelligent, context-aware search and reasoning by the debugger. + +- **Challenge:** Handling Environment Variables in Streamlit Cloud + **Solution:** After some thorough research and trial-and-error, I realized that Streamlit Cloud requires environment variables to be set via their Secrets Manager, not directly via .env files or code. I restructured the way the debugger reads sensitive values like API keys, moving everything into Streamlit's secure secrets.toml configuration. Once set properly, the application worked as expected in the cloud environment. This not only solved the deployment issue but also ensured better security practices moving forward. + +--- + +## Key Learnings + +- Deploying the AI debugger to Streamlit Cloud taught me the importance of environment-specific configurations, especially handling environment variables securely using platform-specific methods like Streamlit’s Secrets Manager. It highlighted how even small deployment details can significantly impact the usability and accessibility of an application. +- Creating embeddings from Music Blocks project representations and integrating them into a Qdrant vector database deepened my understanding of how LLMs can be enhanced with contextual knowledge. I also learned how to structure data ingestion pipelines effectively for scalable and meaningful semantic search. +- Tweaking the LLM prompt to generate child-friendly responses helped me appreciate the importance of audience-aware design in educational tools. It reinforced the idea that technology should be not just functional, but also inclusive, approachable, and aligned with the learning level of its users. + +--- + +## Next Week’s Roadmap + +- Integrate the JSON convertor directly into the Debugger Streamlit app +- Testing the Debugger with Intensive Prompting +- Improving the Quality of LLM Responses + +--- + +## Resources & References + +- **Repository:** [JSON to Text representation](https://github.com/omsuneri/JSON-to-Text-representation) +- **Repository:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) +- **Debugger Streamlit App:** [Music Blocks Debugger](https://debuggmb.streamlit.app/) +- **Directory for Projects:** [Embedding Project Set](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks/tree/main/data/docs) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,No=Object.freeze(Object.defineProperty({__proto__:null,default:pn},Symbol.toStringTag,{value:"Module"})),bn=`--- +title: "GSoC '25 Week 03 Update by Saumya Shahi" +excerpt: "This week focused on implementing a comprehensive brick tree model with hierarchical connections, graph-like notch connections, and robust tree management for the Masonry module." +category: "DEVELOPER NEWS" +date: "2025-06-21" +slug: "2025-06-21-gsoc-25-saumya-shahi-week03" +author: "@/constants/MarkdownFiles/authors/saumya-shahi.md" +tags: "gsoc25,sugarlabs,week03,saumya-shahi" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 03 Progress Report by Saumya Shahi + +**Project:** [Masonry Module - Music Blocks v4](https://github.com/sugarlabs/musicblocks-v4) +**Mentors:** [Anindya Kundu](https://github.com/meganindya/) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-15 – 2025-06-21 + +--- + +## Goals for This Week + +- Design and implement a comprehensive brick tree model for managing hierarchical connections +- Implement connection validation based on brick types and notch availability +- Create robust tree management with proper merging and splitting behavior +- Develop comprehensive test coverage for all tree operations + +--- + +## This Week's Achievements + +### 1. **Comprehensive Brick Tree Model Implementation** + +Developed a \`BrickTreeManager\` class that handles: +- **Tree Structure Management**: Each tree has a unique ID that changes when connections/disconnections occur +- **Hierarchical Connections**: Parent-child relationships where disconnecting a parent keeps children connected +- **Connection Validation**: Ensures bricks can only connect if their notches are compatible and available + +### 2. **Advanced Connection System** + +Implemented a dual connection approach: +- **Top-Bottom Connections**: Hierarchical parent-child relationships +- **Left-Right Notch Connections**: Graph-like where bricks connect only if their right and left notches are free +- **Nested Notch Support**: Support for complex nested brick structures +- **Connection State Tracking**: Real-time tracking of which notches are occupied or available + +### 3. **Tree Management** + +Created tree operations: +- **Tree Merging**: When bricks connect, their respective trees merge into a single tree +- **Tree Splitting**: When bricks disconnect, new trees are formed preserving child relationships +- **Hierarchical Disconnection**: Disconnecting a parent preserves child connections and forms new trees +- **UUID Management**: Each brick has a unique UUID, and trees have dynamic IDs that change with connections + +### 4. **Comprehensive Test Suite** + +Developed extensive test coverage including: +- **Connection Tests**: Validating proper tree merging when bricks connect +- **Disconnection Tests**: Ensuring correct tree splitting behavior +- **Hierarchical Tests**: Testing parent-child relationship preservation +- **Notch Validation Tests**: Verifying connection rules based on notch availability +- **Edge Case Tests**: Handling complex scenarios with multiple connections + +### 5. **Type Safety and Validation** + +Enhanced the type system with: +- **Brick Type Definitions**: Clear interfaces for Simple, Expression, and Compound bricks +- **Connection Validation**: Type-safe connection checking based on brick types +- **Notch Compatibility**: Validation ensuring only compatible notches can connect +- **Error Handling**: Comprehensive error handling for invalid operations + +--- + +## Technical Implementation Details + +### Brick Tree Structure +\`\`\`typescript +interface BrickTree { + id: string; + bricks: Map<string, Brick>; + connections: Map<string, Connection>; + rootBricks: Set<string>; +} +\`\`\` + +### Connection Types +- **Hierarchical Connections**: Top-bottom parent-child relationships +- **Notch Connections**: Left-right graph-like connections +- **Nested Connections**: Complex nested brick structures + +### Key Features +- **Automatic Tree ID Generation**: Trees get new IDs when connections change +- **Connection Validation**: Ensures only valid connections are allowed +- **Hierarchical Preservation**: Child relationships are maintained during disconnections + +--- + +## Challenges & How I Overcame Them + +### Challenge 1: Hierarchical vs Graph-like Connections +**Problem**: Balancing hierarchical parent-child relationships with graph-like notch connections was complex. +**Solution**: Implemented a dual connection system where hierarchical connections manage the tree structure, while notch connections provide the visual puzzle-like behavior. + +### Challenge 2: Tree Splitting Logic +**Problem**: Ensuring that disconnecting a parent brick correctly preserves child relationships and forms new trees. +**Solution**: Developed a algorithm that traverses the tree structure, identifies connected components, and creates new trees while maintaining all valid connections. + +### Challenge 3: Connection Validation +**Problem**: Ensuring that bricks can only connect when their notches are compatible and available. +**Solution**: Created a comprehensive validation system that checks notch types, availability, and compatibility before allowing connections. + +### Challenge 4: Test Coverage +**Problem**: Creating comprehensive tests for complex tree operations and edge cases. +**Solution**: Developed a systematic testing approach covering all major operations, edge cases, and error conditions with clear test descriptions. + +--- + +## Key Learnings + +- **Tree Data Structures**: Deep understanding of tree management, merging, and splitting operations +- **Graph Theory**: Applied graph concepts for notch-based connections +- **Type Safety**: Enhanced TypeScript skills with complex type definitions and validation +- **Testing Strategies**: Learned systematic approaches to testing complex data structures +- **Algorithm Design**: Developed algorithms for tree traversal and component identification + +--- + +## Code Quality Improvements + +- **Comprehensive Documentation**: Added detailed JSDoc comments for all public methods +- **Type Safety**: Enhanced TypeScript interfaces and type checking +- **Test Coverage**: Achieved high test coverage with edge case testing + +--- + +## Next Week's Roadmap + +- **Visual Tree Rendering**: Implement visual representation of the brick tree structure +- **Palette Creation UI**: Create palette interface for rendering list of all bricks +- **Performance Optimization**: Optimize tree operations for large brick structures +- **Integration Testing**: Test the tree model with the existing brick rendering system + +--- + +## Resources & References + +- **Tree Data Structures**: [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects) +- **TypeScript Advanced Types**: [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/advanced-types.html) +- **Testing Complex Data Structures**: [Jest Documentation](https://jestjs.io/docs/getting-started) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for their guidance and support. Special thanks to the community for providing valuable feedback on the tree model design and implementation. + +--- +`,qo=Object.freeze(Object.defineProperty({__proto__:null,default:bn},Symbol.toStringTag,{value:"Module"})),fn=`--- +title: "SSoC ’25 Week 03 Update by Muhammad Haroon" +excerpt: "Experimenting with temperature and top_p parameters in AudioGen model." +category: "DEVELOPER NEWS" +date: "2025-06-22" +slug: "2025-06-22-ssoc-25-MuhammadHaroon-week03" +author: "@/constants/MarkdownFiles/authors/muhammad-haroon.md" +tags: "ssoc25,sugarlabs,week03,GenAI,MusicBlocks,Music" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 03 Progress Report by Muhammad Haroon + +**Project:** [Generative AI Instrument Sample Generation for Music Blocks](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md#Generative-AI-Instrument-Sample-Generation-for-Music-Blocks) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-16 - 2025-06-22 + +--- + +## Goals for This Week + +- **Goal 1:** Generate more samples using AudioGen and save them in Google Drive. +- **Goal 2:** Experiment with temperature and top_p parameters in AudioGen. + +--- + +## This Week's Achievements + +1. **Generated more samples using AudioGen model** + - I was able to generate more samples from AudioGen model and saved them in [Google Drive](https://drive.google.com/drive/folders/10UZzts_AuIe1AypJm9v4ll0NQ0tdkHEI?usp=drive_link). + +2. **Experimented with different values of temperature and top_p** + - I created a [Google Sheet](https://docs.google.com/spreadsheets/d/1tFjL4bXAyB-Z7Fxj4cqiS4_pRkAGo3gKgs-CZVmkFYk/edit?gid=0#gid=0) where I experimented with generating sound samples using different temperature and top_p values. By recording the results, I was able to determine which parameter settings produce more meaningful sound samples. + +--- + +## Key Learnings + +- I gained an understanding of the key parameters temperature and top_p, which are used to tune the output for specific use cases. This [article](https://medium.com/@1511425435311/understanding-openais-temperature-and-top-p-parameters-in-language-models-d2066504684f) was helpful in understanding these concepts. + +--- + +## Next Week's Roadmap + +- To further explore the effects of the temperature and top_p parameters. +- To find an effective method for removing silence and noise from the audio. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,Ho=Object.freeze(Object.defineProperty({__proto__:null,default:fn},Symbol.toStringTag,{value:"Module"})),yn=`--- +title: "DMP ’25 Week 03 Update by Harshit Verma" +excerpt: "Week 3 focused on refining the AI prompt for better debugging suggestions, exploring UI ideas for displaying tips, and testing Sugar AI integration with Pippy." +category: "DEVELOPER NEWS" +date: "2025-06-23" +slug: "2025-06-23-dmp-25-therealharshit-week02" +author: "@/constants/MarkdownFiles/authors/harshit-verma.md" +tags: "dmp25,sugarlabs,week03,therealharshit" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 02 Progress Report by Harshit Verma + +**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-16 - 2025-06-22 + +--- + +## Goals for This Week + +- **Goal 1:** Refine the base prompt for debugging tips. +- **Goal 2:** Explore multiple UX approaches for displaying debug output. +- **Goal 3:** Test Sugar AI integration with Pippy. + +--- + +## This Week’s Achievements + +1. **Refine the base prompt for debugging tips** + - Refine the base prompt sent to the AI model to make debugging suggestions clearer and more relevant. + - Iterated by testing different wording styles and instruction formats, which led to noticeably better model output. + +2. **Explore multiple UX approaches for displaying debug output** + - Considered multiple UX designs for displaying debug tips, such as: + * **Inline** messages near code lines. + * A **side panel** exclusively for displaying suggestions.. + * A **Dedicated Debugging Terminal** for interactive debugging. + - Evaluated each method in terms of ease of integration, readability, and user experience. + - Concluded that a dedicated debugging terminal offers the best balance of usability and flexibility. + - Plan to design a UI mockup for this approach in the upcoming week. + +3. **Test Sugar AI integration with Pippy** + - Successfully tested the connection between Pippy and Sugar-AI. + - Verified that the Python code written in Pippy is extracted correctly, sent to the /ask-llm endpoint, and the response is generated. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Crafting prompts that consistently lead to relevant and useful debugging suggestions. + **Solution:** Studied prompt engineering best practices and experimented with structure, examples, and explicit instructions to guide the model better. + +- **Challenge:** Deciding how to present debug output in a child-friendly and non-intrusive way. + **Solution:** Brainstorm some UI ideas, reviewed how other tools display feedback, and consulted with mentors on what would best align with the Sugar UX philosophy. + +--- + +## Key Learnings + +- Gained deeper insight into prompt engineering and its impact on LLM output quality. +- Developed a design-focused mindset for user-centric debugging tools. + +--- + +## Next Week’s Roadmap + +- Plan to design a UI mockup for debugging terminal. +- Implement a first version of the debug output inside Pippy. +- Collect feedback from mentors on debug message placement and design. + +--- + +**Note:** This week, I was mostly away from the keyboard, so I couldn’t dedicate as much time to coding as usual. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! + +--- +`,Ko=Object.freeze(Object.defineProperty({__proto__:null,default:yn},Symbol.toStringTag,{value:"Module"})),wn=`--- +title: "GSoC '25 Week 03 Update by Shubham Singh" +excerpt: "Mapped Music from Synthutils to LegoBricks. Completed LegoBricks Wdiget UIs" +category: "DEVELOPER NEWS" +date: "2025-06-25" +slug: "2025-06-25-gsoc-25-firepheonix-week03" +author: "@/constants/MarkdownFiles/authors/shubham-singh.md" +tags: + - gsoc25 + - sugarlabs + - week02 + - firepheonix +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 3 Progress Report by Shubham Singh + +**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) +**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-06-16 – 2025-06-22 + +--- + +## Goals for This Week + +- Complete UIs for image upload, webcam integration to Music Blocks. +- Integrating audios from Synth Sampler to LegoBricks widget. +- Researching existing audio integration patterns in the phrase maker and note blocks. + +--- + +## This Week's Achievements + +1. **Complete Image upload facility into Lego Bricks Widget.** + - Integrated image upload support within the LegoBricks widget, enabling external image input directly on the Music Blocks canvas. + - Created a new block type by modifying six core files across the codebase. + - The codebase proved beautifully encapsulated and thoroughly documented, making the learning curve smoother. +  + +  + +2. **Real-time Video Integration** + - Implemented real-time video functionality through webcam integration. + - Enabled real-time video streaming, with support for dynamic canvas manipulation and block interaction. + - Made grided interface for addition of both image and webcam. Made changes for adjusting. + + <iframe width="800" height="400" src="https://www.youtube.com/embed/HG6C0ZX7QRA?si=OIGvtD4qpwxMmb8W" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> + +3. **Addition of music notations to Lego Bricks widget** + - Researched about where audio samples lie. + - Deep-dived into Phrase Maker, Synth Sampler widget documentation and codebase. + - Applied music samples to Music Blocks. + + <iframe width="800" height="400" src="https://www.youtube.com/embed/PwuPtACP8WM?si=NpfkLI-4SUVkVeU7" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Music Blocks didn't have any code for integrating webcam video on to the Music Blocks interface. +**Solution:** Researched some stack overflow resources and added the webcam video on to the legobricks widget canvas. +- **Challenge:** Finding out where the SVGs and existing phrase maker and synthsampler audio files lie. +**Solution:** Asked my mentor, Walter Bender in Wednesday's meet. Saw some previous PRs inside of music blocks itself, related to phrase maker, related to synth sampler. + +--- + +## Key Learnings + +- Gained comprehensive understanding of **synth utils** and how **music samples are being exported to other blocks** +- Deepened appreciation for **code architecture** including inheritance patterns, code modularity, and custom return types within the Music Blocks ecosystem. +- Improved skills in **development workflow** including exports, imports, code reusability, documentation practices, and collaborative development workflows. + +--- + +## Next Week's Roadmap + +- Implement complete Core Implementation of Scanning the Lego Blocks image on the X-axis. +- Next to Next week -> Test for shadow handling +- Focus on algorithmic challenges for note-to-color mapping system. + +--- + +## Resources & References + +- **Project Issue:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) +- **Music Blocks Repository:** [sugarlabs/musicblocks](https://github.com/sugarlabs/musicblocks) +- **Documentation:** Music Blocks Developer Guide + +--- + +## Acknowledgments + +Thank you to my mentors [Walter Bender](https://github.com/walterbender) and [Devin Ulibarri](https://github.com/pikurasa) for invaluable guidance throughout this development phase. Special thanks to Walter. A lot of code of Music Blocks was written by Walter, he has a very good knowledge of this code base. Can completely rely on him for help. He also helped this week as well. + +---`,Vo=Object.freeze(Object.defineProperty({__proto__:null,default:wn},Symbol.toStringTag,{value:"Module"})),vn=`--- +title: "DMP ’25 Week 4 Update by Aman Naik" +excerpt: "This week focused on building a basic UI for the chatbot within Sugar and implementing a book recommendation system using the Google Books API." +category: "DEVELOPER NEWS" +date: "2025-06-29" +slug: "2025-06-22-dmp-25-AmanNaik-week04" +author: "@/constants/MarkdownFiles/authors/amannaik247.md" +tags: "dmp25,writeactivity,write,sugarlabs,week04,amannaik247" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 4 Progress Report by Aman Naik + +**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) +**Reporting Period:** 2025-06-22 – 2025-06-28 + +--- + +## Goals for This Week + +- **Goal 1:** Create some UI to test the demo chatbot inside Sugar +- **Goal 2:** Develop a book recommendation feature for the demo application + +--- + +## This Week’s Achievements + +1. **Built a Basic Chatbot UI Inside Sugar** + - Created an initial UI within Sugar using the demo logic from the Streamlit version as reference. + - Implemented a basic sidebar within the activity that allows students to converse with the chatbot while simultaneously viewing the story context. + - The framework generated from the conversation is currently being saved as a JSON file. UI for displaying the framework is still under development and will be added later. + +  + +2. **Implemented Book Recommendation Feature** + - Integrated the Google Books API to recommend the top 3 similar books based on the conversation with the AI assistant. + - The goal is to inspire children by connecting their creative stories with real-world books. + - Based on mentor feedback, I will prioritize refining the chatbot and story framework builder before expanding the recommendation feature. + +  + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Integrating the chatbot into Sugar and dealing with GTK + **Solution:** As I had limited experience with GTK, I faced difficulties while setting up the interface. Additionally, the initial setup used Groq's SDK, which wasn’t compatible with Sugar. I refactored the code to use the \`requests\` module for calling Groq’s API instead, which made integration possible without extra dependencies. + +- **Challenge:** Displaying the final story framework after clicking the "Create Framework" button + **Solution:** I’m currently working on UI design ideas to present the story structure in a child-friendly and intuitive way. I’ll be discussing different visual layouts with my mentors in the upcoming meeting to finalize a clear and engaging format. + +--- + +## Key Learnings + +**Integrated AI Chatbot Into Sugar's UI Framework** + - Learned how to work with GTK and adapt web-based chatbot logic into a desktop environment suitable for Sugar. + +**Designed Book Recommendation Feature Using Google Books API** + - Built a feature that enriches the student’s experience by recommending related books based on the story they are writing. + +**Improved Problem-Solving Skills While Debugging API and GTK Issues** + - Encountered real-world software integration issues and learned how to handle dependency mismatches and platform limitations effectively. + +--- + +## Next Week’s Roadmap + +- Finalize the UI for the story framework display +- Focus on polishing the conversational flow of the AI assistant +- Exploring LLM's to be used instead of Groq API for AWS integration + +--- + +## Acknowledgments + +Grateful to my mentors, the Sugar Labs community, and fellow contributors for their continuous support and insightful suggestions throughout the week! + +--- +`,Jo=Object.freeze(Object.defineProperty({__proto__:null,default:vn},Symbol.toStringTag,{value:"Module"})),kn=`--- +title: "GSoC ’25 Week 04 Update by Bishoy Wadea" +excerpt: "Soma Cube" +category: "DEVELOPER NEWS" +date: "2025-06-28" +slug: "gsoc-25-BishoyWadea-week04" +author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" +tags: "gsoc25,sugarlabs,week04,BishoyWadea" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 04 Progress Report by Bishoy Wadea + +**Project:** [Soma Cube](https://github.com/Bishoywadea/Soma-Cube) +**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) +**Reporting Period:** 2025-06-22 - 2025-06-28 + +--- + +## Goals for This Week + +- **Goal 1:** Make Four Color map game pep8 compliant [#4 Make activity pep8 compliant](https://github.com/Bishoywadea/Four-Color-Map/issues/4) + +- **Goal 2:** Start implementing Soma Cube game +--- + +## This Week’s Achievements + +### *Goal 1: Fix Issues in Four Color Map Activity* + +1. **Make Four Color map game pep8 compliant** + - commit: [Make main.py, activity.py PEP 8 compliant](https://github.com/Bishoywadea/Four-Color-Map/commit/45b2dd77e39a6d822d9d4ba0a12fbf1c31e1f04b) + +--- + +### *Goal 2: Start implementing Soma Cube game* +1. **3D Environment & Controls** + - Set up a 3D scene with movement and camera control. + - commit: [add 3d space with cube](https://github.com/Bishoywadea/Soma-Cube/commit/c917f9d2af509cc4f405f9b72fe8d479e1f3f56f) + - commit: [add wasd controls](https://github.com/Bishoywadea/Soma-Cube/commit/7dc779dbecd693794a2ae96f25ef3aa3dd174c83) + + + +2. **Soma Pieces & Core Mechanics** + - Added the 7 pieces and enabled, rotation, and collision. + - commit: [add the 7 basic pieces](https://github.com/Bishoywadea/Soma-Cube/commit/5ace6710608720ba05bad05df3dac26bbd1907e9) + - commit: [add collision support](https://github.com/Bishoywadea/Soma-Cube/commit/9e1f60943b64718c4efc6deca1a0a077f1e94475) + + + +3. **Interaction & UI Elements** + - Implemented help system, completion message, and on-screen controls. + - commit: [add help button](https://github.com/Bishoywadea/Soma-Cube/commit/f00c1661fc94a9c29e3325c83c916d215a2b1c32) + - commit: [add controls map on screen](https://github.com/Bishoywadea/Soma-Cube/commit/325d9197cedc5dfa6643382fcaf246b681201806) + +4. **Texturing & Visuals** + - Added textures for floor, sky, and Soma pieces with improved lighting. + - commit: [add sky texture](https://github.com/Bishoywadea/Soma-Cube/commit/be08b1c314dccc7f0c984585a1ee19e27664ce89) + - commit: [add texture for the 7 objects](https://github.com/Bishoywadea/Soma-Cube/commit/8b69f60a615037266dc2ae8e89d8ed09a231c1ea) + + + +--- + +## Challenges & Solutions + +- **Challenge:** Implementing precise snapping and collision for 3D puzzle pieces. + **Solution:** Designed a snapping algorithm with bounding box checks and added a collision detection system to prevent overlaps. + +- **Challenge:** Enhancing the visual quality of the 3D scene. + **Solution:** Introduced floor, sky, and object textures; adjusted lighting and shadows for a more polished and immersive look. + +- **Challenge:** Allowing intuitive piece manipulation with both keyboard and mouse. + **Solution:** Integrated context-aware WASD controls and mouse-based dragging/rotating mechanisms for smooth interaction. + +- **Challenge:** Guiding users through gameplay without overwhelming them. + **Solution:** Added an on-screen control map, a help button, and a success message to support the player experience. + +- **Challenge:** Maintaining code readability during rapid feature additions. + **Solution:** Regularly removed redundant code, followed PEP8 guidelines, and modularized logic for easier updates. + +--- + +## Key Learnings + +- Strengthened understanding of **3D graphics programming** using transformations, lighting, textures, and real-time rendering. +- Gained practical experience in **interactive puzzle game design**, including snapping mechanics, collision handling, and visual feedback. +- Improved skills in **UI/UX design for educational tools**, balancing usability, clarity, and visual appeal. +- Practiced clean coding habits with **modular design**, PEP8 compliance, and ongoing refactoring. +- Learned to integrate **multi-modal controls** (keyboard + mouse) for intuitive 3D manipulation. + + +--- + +## Next Week’s Roadmap + +- Fix any feedback provided by members of the organization. +- Start implementing the 16-puzzle game. +--- +`,Xo=Object.freeze(Object.defineProperty({__proto__:null,default:kn},Symbol.toStringTag,{value:"Module"})),Sn=`--- +title: "GSoC '25 Week 4 Update by Elwin Li" +excerpt: "Weekly progress report for JSEditor updates" +category: "DEVELOPER NEWS" +date: "2025-06-28" +slug: "2025-06-28-gsoc-25-Elwin-Li-week04" +author: "@/constants/MarkdownFiles/authors/elwin-li.md" +tags: "gsoc25,sugarlabs,week4,javaScript editor" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 4 Progress Report by Elwin Li + +**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/config_driven_conversion/elwin) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) + +**Reporting Period:** 2025-06-21 - 2025-06-28 + +--- + +## Goals for This Week + +- **Goal:** Complete the debugger project + +--- + +## This Week’s Achievements + +**Reworked Status Block for Debugger Tool** + +The main goal of this week was to work out difficulties with the status block and status matrix in regards to the debugger tool. There has been many pivots in terms of the UX design, and it is now going in a cleaner direction. + +How the debugger tool currently works: +- The user can set debugger statements either through the debugger block itself, or adding breakpoints in the JSeditor and converting to blocks. +- The user can now begin debugging through one of three methods: + - Run slowly button + - Run step by step button + - Clicking on a block itself (e.g. an action block) +- This will run the blocks and pause at the debugger block(s) +- The user can then choose to inspect variables by dragging out a status block + - The status block will be automatically prepopulated by all the custom variables that are used in the users code + - The status window will also automatically pop up and show the user their variables + +**Small UI fixes** +- I made it so that block highlighting only highlights the current block being executed, for easier code tracing when using run slowly or run by step. +- I made debugger blocks have no effect when using the normal play button, since that's for a finished product, but it will pause execution when ran slowly, by step, or a user manually runs a stack of blocks +- Changed behavior of manually clicking on blocks to run it default to run slowly, as it is for debugging purposes. +- Fixed bug where execution will continue even if you change/delete blocks + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Having a "debug mode" was not a clean solution + + **Solution:** Instead of having a "debug mode", we now distinguish in terms of the play buttons, with the run slowly and run by step buttons being meant for debugging + +- **Challenge:** Status block doesn't work as intended, and dragging a status block manually behaves differently from the one triggered by the debugger block. There could also be multiple status blocks at the same time, which messed up the status window. + + **Solution:** Constrained the maximum number of status blocks to one, and updated the logic for all status blocks to automatically include the custom variables in the blocklist. + +--- + +## Key Learnings + +- Improved skills in UX design and keeping tools simple for the user +- Deepened understanding of how music blocks execution works +- Deepened understanding of how the blocks are designed and the whole flow of a block +- Improved skills in **debugging**, **code design**, and **collaboration workflows**. + +--- + +## Next Week’s Roadmap + +- Complete and deploy debugger project +- Add syntax highlighting to JSeditor code + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,$o=Object.freeze(Object.defineProperty({__proto__:null,default:Sn},Symbol.toStringTag,{value:"Module"})),In=`--- +title: "GSoC '25 Week 4 Update by Krish Pandya" +excerpt: "Python Library Graphics " +category: "DEVELOPER NEWS" +date: "2025-06-28" +slug: "2025-06-28-gsoc-25-mostlyk-week04" +author: "@/constants/MarkdownFiles/authors/krish-pandya.md" +tags: "gsoc25,sugarlabs,week04,mostlyk" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 4: Development on the Python Library + +**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) + +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky), [Juan Pablo Ugarte](https://github.com/xjuan) + +**Reporting Period:** June 21, 2025 till June 28, 2025 + +--- + + +## Style , MenuItem and Changes + +I seem to have missed updating about the Python start on the last week's blog. +This week has 2 videos and less of text! Sorry about that , I will try to summarize the video trascripts for my beloved reading enthusiasts. + +<iframe width="560" height="315" src="https://www.youtube.com/embed/OD1PBOK3g94?si=NT8wfgk7UkQt6gxl" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> + +This short video covers the initial Python layout and CI pipeline. I’ve structured the repo cleanly: + +- \`make ci-test\` now runs a clean, install, test and build. +- Removed the linting stage since we're not enforcing strict import ordering (consistent with GTK3’s sugar-toolkit style). So it is always going to fail on the top import, but I have kept the formatting check!. +- Wheel gets built automatically , and is stored inside \`dist/\`. Following this we can also build tar using \`make tarbell\`, also stored inside \`dist/\`. + +On the graphics front, I wired up a base activity with \`XOColors\`, and a simple close button. This will expand soon as more components are added. +I'm planning to move forward with alert icons, styled windows, and the tool bar to give our activities the "sugary" look. + +> So that was written on Sunday (22nd) and while at the time of writing some more things are added mentioned and demoed in the next video!. + + +I urge you to go to [sugar-toolkit-gtk4-py](https://github.com/MostlyKIGuess/sugar-toolkit-gtk4-py)'s README as it also has a quick start activity which you can directly bump up. Cheers! + +And the next video which is a bit long (_6 mins_) where I talk about what I did this week is: + +<iframe width="560" height="315" src="https://www.youtube.com/embed/-WTojjHpQLs?si=m0msTtsXOvzDTTP-" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> + +This longer video goes into the real dev work of the week. + +- Fixed deprecated API usage in styles by warning users when they try to use old GTK3-style methods, and re-routing to the newer alternatives. I have shown this in video specifically. +- Built a \`MenuItem\` wrapper that supports icons, keyboard accelerators, as used \`Gtk.Button\` rather than \`GtkImageMenuItem\` which is deprecated. +- On styles, I added something more like \`primary\`, \`success\`, etc. The last section in style example shows this. +- Demonstrated accelerators (\`Ctrl+O\`, \`Ctrl+S\`, \`Ctrl+Q\`). these are now working using the newer GTK4 shortcut handling instead of relying on \`GtkImageMenuItem\` and it's older signal. + + +## Sneak Peek & Road Ahead + +Near around 3-4 min mark I started giving the sneak peeks haha, and take this as for the work of week 5-6, and let's see how fast it can be pushed. A bit rough, but fun stuff: + +- Vertical tray widgets with clickable icons and buttons. +- Fullscreen and window information tools. +- Sugar artwork preview with randomized XO colors. ( sanity check if colors are working again v2) +- First version of the window and tray abstraction layers (some bugs but foundational). +- Starting experiments with \`Palette\`, \`Tray\`, and \`Toolbar\`. + +This is the first time I'm actively trying to integrate things built in Week 3 and 4 into full activity flows. +The idea is to not just build features in isolation but make sure they cooperate. + +Ideally I want to have some sort of more quick start activity which uses bunch of these Palettable, Toolbar, Style etc. to see everything in action. + +## Resources & References + +- Project Page – [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) +- New C Library - [sugar-ext repository](https://github.com/sugarlabs/sugar-ext) +- New Python Library - [sugar-toolkit-gtk4-py ](https://github.com/MostlyKIGuess/sugar-toolkit-gtk4-py) +- Active PR - [Establish C library base template with Meson for GTK4](https://github.com/sugarlabs/sugar-ext/pull/1) +- Sugar Toolkit Repository(original) – [sugar-toolkit-gtk3](https://github.com/sugarlabs/sugar-toolkit-gtk3) +- GTK4 Migration Guide – [docs.gtk.org/gtk4/migrating-3to4.html](https://docs.gtk.org/gtk4/migrating-3to4.html) + + +--- + +## Acknowledgments + +Thanks to all the mentors whose guidance and support have been strong in helping me navigate the Port. +`,Yo=Object.freeze(Object.defineProperty({__proto__:null,default:In},Symbol.toStringTag,{value:"Module"})),An=`--- +title: "DMP’25 Week 04 Update by Justin Charles" +excerpt: "Completed SVG path logic for all brick types and documented props and rendering states" +category: "DEVELOPER NEWS" +date: "2025-06-29" +slug: "2025-06-29-dmp-25-justin212407-week04" +author: "@/constants/MarkdownFiles/authors/justin-charles.md" +tags: "dmp25,sugarlabs,week4,justin212407" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 4 Progress Report by Justin Charles + +**Project:** Music Blocks 4 Masonry +**Mentors:** [Anindya Kundu](https://github.com/meganindya/) +**Assisting Mentors:** [Devin Ulibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Reporting Period:** 2025-06-22 - 2025-06-29 + +--- + + +## Goals for This Week + +- Finalize SVG path logic for all three types of bricks +- Categorize and document all props passed into bricks +- Identify all visual states a brick can be rendered in +- Differentiate props and states across brick types +- Write comprehensive tests to verify correctness + +--- + +## This Week’s Highlights + +### 1. Brick Inventory Compilation + +- Catalogued different distinct bricks across categories such as Rhythm, Tone, Flow, Graphics etc. +- Created a centralized metadata list including notches, label types, and slot counts for each. + +### 2. JSON Schema for Brick Types + +- Authored a strict \`bricks-schema.json\` enforcing required fields like \`type\`, \`label\`, \`notches\`. +- Validated all brick entries programmatically and corrected inconsistencies (e.g. naming errors and missing defaults). + +### 3. Palette UI Implementation + +- Built a dynamic React Palette UI that maps categories and bricks from the schema directly. +- Enabled hover previews showing live-rendered brick paths and labels. +- Schema-driven architecture allows zero-maintenance scalability. + +📄 Reference: [Palette – Tab 6](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.2dd4jqek61qh#heading=h.nicqc6ugqkyy) + +--- + +## Challenges & Solutions + +**Challenge: Handling Bricks with Special Properties** +Some bricks (e.g., compound or expression bricks) required special handling due to nested structures, variable slots, or dynamic notches. +**Solution:** Added metadata flags to the brick definitions (e.g., \`hasNotchTop\`) and incorporated them into both the schema and UI logic. + + +**Challenge: Bricks with Ambiguous Labels or Duplicate Names** +A few bricks had similar or identical display labels, which caused confusion in UI previews and JSON definitions. +**Solution:** Assigned internal id fields distinct from display labels. The id ensures uniqueness in JSON and tests, while label stays user-friendly in the UI. + +--- + +## Key Learnings + +- Source-code scraping can outperform manual documentation in accuracy and speed. +- JSON Schema offers powerful safeguards when used with validation tooling. +- UI scalability improves drastically when tied to a schema-first approach. + +--- + +## Resources & References + +- [Palette](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.2dd4jqek61qh#heading=h.nicqc6ugqkyy) +- [musicblocks-v4 Repository](https://github.com/sugarlabs/musicblocks-v4) + +--- + +## Acknowledgments + +Thanks to my mentors for helping review the UI and desgin for the palette. Their early feedback made the path code significantly more robust and maintainable. + +--- +`,Qo=Object.freeze(Object.defineProperty({__proto__:null,default:An},Symbol.toStringTag,{value:"Module"})),Ln=`--- +title: "DMP '25 Week 04 Update by Anvita Prasad" +excerpt: "Completion of target pitch mode and implementation of manual cent adjustments pie menu" +category: "DEVELOPER NEWS" +date: "2025-06-29" +slug: "2025-06-29-DMP-25-AnvitaPrasad-week04" +author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" +tags: "dmp25,sugarlabs,week04,AnvitaPrasad" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 04 Progress Report by Anvita Prasad + +**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) +**Mentors:** [Walter Bender](https://github.com/walterbender) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-23 - 2025-06-29 + +--- + +## Goals for This Week +- Complete and refine target pitch mode implementation +- Implement manual cent adjustment functionality and interface +- Research icons for chromatic and target pitch mode +- Conduct comprehensive testing with various audio sources and instruments +- Research different tuning systems + +--- + +## This Week's Achievements + +1. **Dual-Mode Tuner Implementation** + - Completed target pitch mode implementation with enhanced functionality + - Integrated target pitch selector with pie menu interface + - Implemented logic for precise pitch matching and deviation calculation + - Added comprehensive display for octave, semitone, and cent deviations + - Gathered and incorporated feedback for interface refinements + + + +2. **Manual Cents Adjustment Development** + - Designed and implemented an intuitive pie menu for cent adjustments with: + - Center Area (Controls): + * Grey circular area with three buttons + * "+" button for positive values + * "-" button for negative values + * "×" button for menu exit + - Inner Wheel (Fine Adjustments): Numbers 1-10 + - Middle Wheel (Medium Adjustments): Numbers 20-50 + - Outer Wheel (Large Adjustments): Numbers 60-100 + +3. **Testing Progress** + - Conducted initial testing with various audio sources + - Identified areas for improvement in pitch detection + - Created a test suite for tuner accuracy verification + +--- + +## Challenges & How I Overcame Them + +- **Challenge 1: Event Bubbling in Pie Menu** + The pie menu's nested event listeners for note, accidental, and octave selection were triggering multiple unintended actions due to incorrect event propagation. + **Solution 1:** + Added event.stopPropagation() at the appropriate event handlers and restructured the event listener hierarchy to ensure events were captured at the correct level only. + +- **Challenge 2: State Management Complexity** + Managing three interdependent states (note, accidental, octave) in the tuner widget led to synchronization issues and undefined states during updates. + **Solution 2:** + Implemented a centralized state update method that handles all three components atomically and validates the complete state before triggering any dependent calculations. + +--- + +## Key Learnings + +- Gained deep understanding of Music Blocks' pitch pie menu interface and its implementation patterns +- Learned about various tuning systems including Equal Temperament, Pythagorean, and Just Intonation + +--- + +## Next Week's Roadmap + +- Implement fully functional tuner with comprehensive features +- Complete and refine manual cent adjustment functionality +- Conduct extensive testing with various audio sources and instruments +- Consider implementation of different tuning systems +- Make fine refinements to tuner interface and functionality +- Write blog post for Week 05 + +--- + +## Resources & References + +- [Web Audio API Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) +- [Different Tuning Systems](https://www.musiccrashcourses.com/lessons/tuning_systems.html) +- [Tuning Systems and Equal Temperament](https://www.earmaster.com/music-theory-online/ch06/chapter-6-2.html) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support and valuable feedback on the new features. + +--- `,Zo=Object.freeze(Object.defineProperty({__proto__:null,default:Ln},Symbol.toStringTag,{value:"Module"})),Tn=`--- +title: "DMP ’25 Week 04 Update by Harshit Verma" +excerpt: "Developed a working prototype." +category: "DEVELOPER NEWS" +date: "2025-06-29" +slug: "2025-06-29-dmp-25-therealharshit-week04" +author: "@/constants/MarkdownFiles/authors/harshit-verma.md" +tags: "dmp25,sugarlabs,week04,therealharshit" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 04 Progress Report by Harshit Verma + +**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-23 - 2025-06-29 + +--- + +## Goals for This Week + +- **Goal 1:** Design a UI mockup for the debugging terminal. +- **Goal 2:** Develop the debugging terminal in Pippy. +- **Goal 3:** Connected the debugger LLM server with Pippy. +- **Goal 4:** Feed LLM responses into the debugging terminal. + +--- + +## This Week’s Achievements + +1. **Design a UI mockup for the debugging terminal** + - Plan the layout and user experience for how debug tips should appear inside Pippy. + - Design the UI of the debugging terminal, prioritized clarity and accessibility, especially for children. + +2. **Develop the debugging terminal in Pippy** + - Added a new Virtual Terminal Emulator (VTE) widget to Pippy using GTK. + - Integrated the terminal into the existing layout with proper toggling between output and debug views. +  +  + +3. **Connected the debugger LLM server with Pippy** + - Wired up Pippy to make API calls to the FastAPI server. + - Verified complete flow: \`code is extracted → sent to /debug → response displayed in the debug terminal\`. + +4. **Feed LLM responses into the debugging terminal** + - Successfully passed LLM-generated debug suggestions into the terminal. + - Added simple formatting: newline, spacing, removed markdown syntax elements. +--- + +### Complete Demo: [Watch here](https://drive.google.com/file/d/1Dzomam9dc3U4tHjHhYFGjRbs7-cwJHmM/view?usp=drive_link) + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** GTK app crashing on API call. + **Solution:** The crash was due to API response handling on the main GTK thread. I fixed it by offloading the network request to a separate thread using Python’s \`threading\` module and updating the UI safely with \`GLib.idle_add()\` to avoid blocking or GTK context violations. + +- **Challenge:** Rendering formatted output inside the terminal widget. + **Solution:** GTK doesn’t support Markdown, so I simulated structure using spacing, and removed marksown syntax elements to enhance readability. + +--- + +## Key Learnings + +- Gained hands-on experience with Python threading to perform non-blocking API calls and prevent UI freezes or crashes. +- Learned how to work with GTK widgets and using CSS in GTK, especially Gtk.Stack, Gtk.Box, and VTE terminal building responsive interfaces. + +--- + +## Next Week’s Roadmap + +- Format the LLM response to be more child friendly. +- Develop a custom mardown parser for GTK. +- Begin working on model selection logic and performance optimization. + +--- + +## Resources & References + +**Repository** +- [Pippy](https://github.com/therealharshit/Pippy/tree/DMP2025/Pippy-Debugger) : I have pushed my code for Pippy here. +- [pippy-debugger-server](https://github.com/therealharshit/pippy-debugger-server) : The FastAPI server which I am using as of now. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! + +--- +`,ei=Object.freeze(Object.defineProperty({__proto__:null,default:Tn},Symbol.toStringTag,{value:"Module"})),Pn=`--- +title: "GSoC ’25 Week 04 Update by Mebin J Thattil" +excerpt: "A new voice for Speak & laying down pipelines" +category: "DEVELOPER NEWS" +date: "2025-06-29" +slug: "2025-06-29-gsoc-25-mebinthattil-week4" +author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" +tags: "gsoc25,sugarlabs,week04,mebinthattil,speak_activity" +image: "assets/Images/GSOCxSpeak.png" +--- + +<!-- markdownlint-disable --> + +# Week 04 Progress Report by Mebin J Thattil + +**Project:** [Speak Activity](https://github.com/sugarlabs/speak) +**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-22 - 2025-06-29 + +--- + +## Goals for This Week + +- **Goal 1:** Integrate Kokoro into Speak +- **Goal 2:** Create a pipeline to quickly quantize and run a model hosted on 🤗 + +--- + +## This Week’s Achievements + +_Note: I was on leave this week till the 26th due to my final exams. But I still managed to do a bunch of cool stuff after that._ + +1. **Kokoro meets Speak - A new chapter** + - One of the three major parts of my proposal was to integrate a more modern, natural-sounding TTS model into Speak. + - I used Kokoro and integrated it with the activity. + - We now have access to the entire catalog of voices that Kokoro comes with. This will be helpful for our idea of having different personas—each persona could have a different voice. + - The current implementation of the code is a _rather hacky_ way of integrating Kokoro. I say this because the audio pipeline currently looks like this: + > Text → Kokoro → Outputs a temporary WAV file → Read by GStreamer → Audio output can be heard + - This is not ideal for obvious reasons. We don't want Kokoro to save an audio file every time and then read from it again. This is slow because Kokoro has to process the entire text, convert it to a WAV, and then GStreamer has to read and output it. For smaller text inputs it's still fine, but it’s not optimal. + - The better approach would be to have Kokoro stream the audio directly, which GStreamer can then stream and output. This would reduce perceived latency significantly. Kokoro currently does not have a function / API that works like this. I would have to make one. + - But for now, this is just an initial implementation to get feedback from mentors and peers, optimization can come later. + - Kokoro also uses the espeak-ng engine as a fallback. Since Speak already uses espeak, I’ll try to go under the hood and tweak Kokoro to use espeak instead. This would reduce additional dependencies. + - Currently, I was able to get this working with just 125KB of additional dependencies. + +Video demo: +<iframe src="https://drive.google.com/file/d/19oUe3oIlMIO_pFUHVZatR6uWP1u23oU7/preview" width="740" height="480" allow="autoplay"></iframe> + +_Note that the recording has a slight echo, but that's the recordings issue, it sounds perfectly fine inside of speak._ + +2. **Quantization Pipeline** + - This is fairly simple. I created a script that: + > pulls a model hosted on 🤗 → sets up all local dependencies → quantizes the model → exports it as a GGUF → and uses a plugin script (model dependent) to run it in chat mode. + - Currently, this works only for chat-styled models. + - This was essential because we are fine-tuning foundational models, and after fine-tuning we get unquantized models. It doesn't make sense to benchmark these unquantized versions. We need to evaluate their performance post-quantization to truly understand their behavior. + - This script could also be useful for other contributors training models intended to run locally. + - The config for the script is shown below and can adjusted to match whichever model you intend to use: + \`\`\`bash + # Model Config + + MODEL_REPO="hfusername/modelname" + GGUF_OUT="output_model_name.gguf" + GGUF_QUANT="output_model_name-q4.gguf" + N_CTX=2048 + BUILD_DIR="build" + SAVED_DIR_NAME_HF="output_dir_name" + \`\`\` + - Another thing to note is the URL to the plugin inference script: + \`\`\`bash + RAW_URL="https://raw.githubusercontent.com/mebinthattil/template_llama_chat_python/main/chatapp.py" + \`\`\` + - This script tries to be OS agnostic, and attempts to detect which OS you're on to run commands accordingly. It’s not fully comprehensive yet, but it works well on macOS, as that’s the only platform I’ve tested it on. + +--- + +## Next Week’s Roadmap + +- Integrate the SLM into Speak +- Test out different Kokoro voices +- Lay the foundations for different personas and automatic voice selection + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for their ongoing support. + +---`,ni=Object.freeze(Object.defineProperty({__proto__:null,default:Pn},Symbol.toStringTag,{value:"Module"})),Cn=`--- +title: "GSoC '25 Week 04 Update by Nikhil Bhatt" +excerpt: "Integrated the frontend with the Git backend and enabled project creation, editing, and forking via the UI in MusicBlocks." +category: "DEVELOPER NEWS" +date: "2025-06-29" +slug: "2025-06-29-gsoc-25-nikhilbhatt-week04" +author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" +tags: "gsoc25,sugarlabs,week04,nikhilbhatt" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 04 Progress Report by Nikhil Bhatt + +**Project:** [Git backend for MusicBlocks](https://github.com/benikk/musicblocks-backend) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Reporting Period:** 2025-06-22 – 2025-06-28 + +--- + +## Goals for This Week + +- Integrate the frontend with the backend Git routes. +- Enable project creation and editing via UI. +- Build a dashboard to list and manage all projects. + +--- + +## This Week's Achievements + +### Frontend-Backend Integration + +I created a dedicated branch in the MusicBlocks repo to begin integrating the Git backend routes. + +- Created API calls to interact with the backend for: + - Creating a new project. + - Editing an existing one. + - Forking a project. + + +### Create & Edit Projects from UI + +Users can now: + +- Create new projects from the frontend. +- Edit and update existing ones. + +This is made possible by sending project name and data to the backend, which handles Git commit and push operations. + +--- + +### Project Dashboard + +Built a new page to display **all projects** (original and forked) in a list format. + +Features include: + +- “Open in MusicBlocks” to edit any project. +- “Fork” to create a copy with the current user as owner. +- Display of metadata like project name, fork status, and last updated time. + +**All Projects Dashboard** + + +--- + +## Challenges & How I Solved Them + +- **Challenge:** Avoiding Git complexity on the frontend. + **Solution:** All operations like branch creation, commits, and metadata updates are handled server-side. Frontend only triggers them. + +- **Challenge:** Keeping fork lineage visible. + **Solution:** Stored original repo metadata inside \`metaData.json\` of each fork. + +--- + +## Key Learnings + +- How to bridge frontend interfaces with a Git-based backend. +- Improved UI/UX by keeping it simple, made it similar to existing planet page for students to learn. + +--- + +### Fun Debug Moment + +Accidentally forked a fork of a fork and ended up with a hilarious recursive repo tree. +But it confirmed my fork metadata system worked perfectly across multiple levels! + +--- + +## Next Week's Roadmap + +- Build UI to submit pull requests from forks. +- Display list of pull requests and metadata. + +--- + +## Resources & References + +- [MusicBlocks Frontend Repo](https://github.com/sugarlabs/musicblocks) +- [musicblocks-backend](https://github.com/benikk/musicblocks-backend) +- [GitHub REST API for PRs](https://docs.github.com/en/rest/pulls/pulls) +- [Octokit REST.js Library](https://github.com/octokit/rest.js) + +--- + +## Acknowledgments + +Thanks again to my mentors and the Sugar Labs community for feedback and support! +Looking forward to next week’s frontend PR features. + +`,ti=Object.freeze(Object.defineProperty({__proto__:null,default:Cn},Symbol.toStringTag,{value:"Module"})),Mn=`--- +title: "GSoC '25 Week 4 Update by Safwan Sayeed" +excerpt: "AST to IR Implementation" +category: "DEVELOPER NEWS" +date: "2025-06-29" +slug: "2025-06-29-gsoc-25-sa-fw-an-week4" +author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" +tags: "gsoc25,sugarlabs,week4,sa-fw-an" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 4 Progress Report by Safwan Sayeed + +**Project:** Music Blocks 4 Program Engine +**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-06-23 - 2025-06-29 + +--- + +## A Blog-style Retrospective + +This week marked a significant milestone in our Music Blocks program engine development as we transitioned from the foundational memory architecture to the core compilation logic. The focus shifted to implementing the AST-to-IR (Intermediate Representation) translation layer - the crucial bridge between our abstract syntax tree representation and executable code. + +--- + +## Goals for This Week + +- Complete the AST-to-IR compilation logic technical specification with detailed pseudocode patterns. +- Implement the AST Parsing logic for all expression classes returning instruction lists. +--- + +## This Week's Highlights + +1. **AST-to-IR Compilation Logic Specification** + - Expanded the tech spec with comprehensive AST-to-IR translation documentation covering expression and statement compilation patterns. + - Detailed instruction list generation requirements and variable management strategies. + - Link: [IR Compilation Logic](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.i655udul8zuq) + +2. **Implemented AST Parsing Logic** + - Developed parsing logic for all expression classes, ensuring they return the correct instruction lists. + +--- + +## Challenges & Solutions + +- **Understanding Static vs Runtime Compilation:** + Initially confused about whether we were performing runtime calculations or static code translation. + *Solution:* Mentors clarified that this is purely static AST-to-IR conversion with no runtime execution, helping focus the implementation approach. + + +--- + +## Key Learnings + +- Gained a deeper understanding of static compilation principles and the importance of maintaining clean instruction generation patterns. +- Learned how to effectively manage variable scopes and dependencies during the AST-to-IR translation process. + +--- + +## Next Week's Roadmap + +- Finalize the AST-to-IR compilation logic implementation for all expression and statement classes. +- Begin integrating the IR generation with the memory management system to ensure proper variable resolution. +- Start working on the execution engine that will interpret the generated IR instructions. +--- + +## Resources & References + +- **Tech Spec:** [AST to IR Methods](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.87123fra3s4#heading=h.gqjcwrtkdgvq) +- **Repository:** [musicblocks-v4](https://github.com/sugarlabs/musicblocks-v4) + +--- + +## Acknowledgments + +Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their crucial guidance on compiler design principles and static compilation concepts. Their clarification on the AST-to-IR translation approach and emphasis on maintaining clean instruction generation patterns was essential for this week's successful progress. + +---`,ai=Object.freeze(Object.defineProperty({__proto__:null,default:Mn},Symbol.toStringTag,{value:"Module"})),xn=`--- +title: "GSoC ’25 Week 04 Update by Diwangshu Kakoty" +excerpt: "Implementing a Reasoning-Enabled AI Model" +category: "DEVELOPER NEWS" +date: "2025-06-29" +slug: "2025-06-29-gsoc-25-diwangshu-week04" +author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" +tags: "gsoc25,sugarlabs,week04,AI" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 04 Progress Report by Diwangshu Kakoty + +**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) +**Reporting Period:** 2025-06-22 - 2025-06-28 + +--- + +## Goals for This Week + +- **Goal 1:** Leveraging Gemini's Thinking Feature. +- **Goal 2:** Code Migration: LangChain → Gemini SDK. +- **Goal 3:** Clean up the codebase. +- **Goal 4:** Make sample summaries to test the 'Analyis' feature. +- **Goal 5:** Fix bugs occured by these changes. + +--- + +## This Week’s Achievements + +1. **Using Gemini's 'Think' Capability for Enhanced Responses** + - I have implemented the 'thinking' capability of the Gemini model in the multi-agent chat model. This allows the LLM to break down complex queries into smaller, manageable parts, leading to more accurate and relevant responses. + + - But it came with a challenge, as LangChain's Gemini module does not support the 'thinking' capability directly (more on this in the challenges section). + +2. **Code Migration: LangChain → Gen AI SDK** + - As mentioned in the last point, LangChain's Gemini module does not support the 'thinking' capability. Therefore, I have started migrating the 'generation' code from LangChain to the official Gen AI SDK. This migration allows us to use the 'thinking' capability and other features of the Gemini model dynamically. + + - The official Gen AI SDK allows us to use the 'think' dynamically, which means the LLM can decide when to use the 'thinking' capability based on the complexity of the query. It also allows us to specify the number of thinking tokens aka 'thinkingBudget' to be used or set it to auto. This flexibility is crucial for optimizing the performance and cost of using the Gemini model. + +3. **Cleaning Up the Codebase** + - I have cleaned up the codebase by structuring the code into separate files, functions and modules. This makes the code more organized and easier to maintain. + +--- + +## Challenges & How I Overcame Them + +- **Challenge :** LangChain's Gemini module does not support the 'thinking' capability directly. This project uses RAG (Retrieval-Augmented Generation) with LangChain, which is a popular framework for building LLM applications. While the retrieval part works well, the generation part needs to be changed. But it is not that simple. The Gen AI SDK uses its own library for storing conversations, which is different from LangChain. + + **Solution:** There's no doubt that leveraging the reasoning capabilities of the Gemini model can significantly enhance response quality. However, as this is still an evolving technology, full support in LangChain is likely to emerge soon. For testing purposes, a complete migration isn't necessary at this stage. Therefore, I've implemented two separate classes: \`llm\` and \`reasoning_llm\`, which initialize \`Gemini-1.5-flash\` and \`Gemini-2.5-flash\`, respectively. The \`llm\` class handles general queries, while \`reasoning_llm\` is dedicated to writing algorithms for the project code when passed as a query. The \`Gemini-2.5-flash\` is the model that supports and uses the 'thinking' capability by default. + + This is a temporary arrangement. If I get positive feedback from the mentors, I will proceed with the complete migration of the 'generation' code to the official Gemini SDK. + +--- + +## Key Learnings + +- While working on this project, I explored extensive documentation for both Gemini and LangChain. This deep dive significantly enhanced my understanding of LLMs, including concepts like structured output, function calling, code execution, reasoning capabilities, and various prompting techniques. + +--- + +## Next Week’s Roadmap + +- Build a developer settings in the sidebar to allow testers to choose between the 'llm' and 'reasoning_llm' classes for each query. +- Work on things suggested by mentors. This could include: + - Full migration of the 'generation' code to the official Gen AI SDK. +- Developing sample summaries to test the 'Analysis' feature. + +--- + +## Resources & References + +- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,oi=Object.freeze(Object.defineProperty({__proto__:null,default:xn},Symbol.toStringTag,{value:"Module"})),Gn=`--- +title: "GSoC’25 Week 04 Update by Om Santosh Suneri" +excerpt: "AI-powered Debugger for Music Blocks" +category: "DEVELOPER NEWS" +date: "2025-06-29" +slug: "2025-06-29-gsoc-25-omsuneri-week04" +author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" +tags: "gsoc25,sugarlabs,week04,Debugger,AI,Music Blocks" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 04 Progress Report by Om Santosh Suneri + +**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) +**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) +**Reporting Period:** 2025-06-22 - 2025-06-28 + +--- + +## Goals for This Week + +- **Goal 1:** Testing the Debugger with Intensive Prompting +- **Goal 2:** Improving the Quality of LLM Responses +- **Goal 3:** Making the Debugger Interactive and Kid-Friendly + +--- + +## This Week’s Achievements + +1. **Testing the Debugger with Intensive Prompting** + - I carried out extensive testing of the debugger by feeding it a wide range of Music Blocks projects and crafting diverse prompts to simulate how real users — especially children — might ask questions or seek help. This allowed me to observe how the LLM interprets different project structures and how effectively it can guide users toward understanding and improving their project. + - Debugging is not just about fixing errors — it’s also about discovering new possibilities. Through this intensive testing, I was able to identify how the debugger could become a more intuitive assistant. Ensuring it understands various project contexts means kids can explore their creativity more freely, knowing they have a tool that helps them understand what’s happening and what more they can do. It moves the debugger from being reactive to being proactively supportive. + +2. **Improving the Quality of LLM Responses** + - I focused on tuning the LLM prompts to ensure that the responses it generates are not only accurate but also clear, structured, and easy to understand for children. I experimented with different prompt formats, simplified technical jargon, and shaped the tone to be more friendly and encouraging. The goal was to make every response feel like it’s coming from a helpful companion, not a complicated machine. + - For many young learners, especially those just starting their journey into coding and music, complex feedback can be discouraging. By improving the quality of responses, I’ve made the debugger more approachable and effective as an educational tool. This change ensures that kids receive feedback they can truly learn from. + +3. **Making the Debugger Interactive and Kid-Friendly** + - One of my main goals this week was to make the debugger feel more alive and responsive. I improved the system prompts to encourage a more interactive and friendly tone. Additionally, I introduced a feature where the debugger can automatically detect key elements of a project right after it is loaded — such as the instruments used, patterns in sequences, or loops — and immediately offer feedback or suggestions. This turns the debugger into more of a conversational partner than just a tool. + - Young minds learn best when they feel engaged and supported. By making the debugger more interactive and giving it the ability to respond to a project from the moment it is initialized, the experience becomes more seamless and enjoyable. Kids no longer have to wait or guess what to do next — they’re gently guided and encouraged to explore, learn, and improve. It transforms the debugger into a playful mentor that supports learning through interaction, discovery, and fun. + +--- + +## Deployed Project +- **Music Blocks Debugger:** [Live Demo](https://debuggmb.streamlit.app/) + +<a href=""><img src="https://i.ibb.co/p6H5y3Bw/Screenshot-2025-06-28-at-10-41-28-AM.png" alt="Music Blocks Debugger"></a> + +- **JSON to Text Converter:** [Live Demo](https://omsuneri.github.io/JSON-to-Text-representation/) + +<a href=""><img src= "https://i.ibb.co/ycNPrKVs/Screenshot-2025-06-28-at-10-42-38-AM.png" alt="JSON to Text Converter"></a> + +## Challenges & How I Overcame Them + +- **Challenge:** Refining System Instructions for Better LLM Responses + **Solution:** One key challenge I encountered was fine-tuning the system instructions to consistently get high-quality, relevant responses from the LLM. The solution was to conduct extensive testing using a variety of prompts and project types. This helped me understand how the model interprets different contexts and allowed me to iteratively improve the instructions for more accurate, helpful, and kid-friendly outputs. + +--- + +## Next Week’s Roadmap + +- Integrate real-time response improvement based on project complexity. +- Enhance system prompts further through prompt-chaining and context tuning. +- Improving the Quality of LLM Responses + +--- + +## Resources & References + +- **Repository:** [JSON to Text representation](https://github.com/omsuneri/JSON-to-Text-representation) +- **Repository:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) +- **Debugger Streamlit App:** [Music Blocks Debugger](https://debuggmb.streamlit.app/) +- **Directory for Projects:** [Embedding Project Set](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks/tree/main/data/docs) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,ii=Object.freeze(Object.defineProperty({__proto__:null,default:Gn},Symbol.toStringTag,{value:"Module"})),_n=`--- + +title: "GSoC '25 Week 04 Update by Saumya Shahi" +excerpt: "This week focused on implementing advanced tree rendering with nested, stacked, and argument brick support, dynamic sizing for the masonry module." +category: "DEVELOPER NEWS" +date: "2025-06-29" +slug: "2025-06-29-gsoc-25-saumya-shahi-week04" +author: "@/constants/MarkdownFiles/authors/saumya-shahi.md" +tags: "gsoc25,sugarlabs,week04,saumya-shahi" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 04 Progress Report by Saumya Shahi + +**Project:** [Masonry Module - Music Blocks v4](https://github.com/sugarlabs/musicblocks-v4) +**Mentors:** [Anindya Kundu](https://github.com/meganindya/) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-22 – 2025-06-29 + +--- + +## Goals for This Week + +- Implement advanced tree rendering with nested, stacked, and argument brick support +- Develop dynamic brick sizing based on content and children +- Create comprehensive validation systems for brick connections +- Establish robust rendering algorithms with proper traversal strategies +- Integrate the complete tree rendering system into the storybook + +--- + +## This Week's Achievements + +### 1. **Advanced Tree Rendering System Implementation** + +Developed a brick tree rendering system that handles three distinct connection types: + +#### **Stacked Tree Rendering** +- **Vertical Stacking**: Bricks can be connected vertically in sequence below their parent +- **Cumulative Height Calculation**: Total height of stacked trees is calculated by summing individual brick heights +- **Width Optimization**: Stacked trees maintain optimal width by taking the maximum width of all stacked bricks + + +#### **Argument Brick Rendering** +- **Expression-Only Validation**: Implemented validation ensuring only Expression bricks can be used as arguments +- **Slot-Based Positioning**: Argument bricks are positioned at specific argument slots on their parent bricks +- **Dynamic Slot Management**: Parent bricks automatically adjust their argument slots based on the number of arguments + + +#### **Nested Tree Rendering** +- **Multi-Level Nesting**: Implemented support for bricks nested inside compound bricks, which can themselves contain nested bricks +- **Dynamic Sizing**: Parent bricks automatically resize based on their nested children's bounding boxes +- **Proper Positioning**: Nested bricks are positioned at calculated connection points within their parent containers + + +### 2. **Dynamic Brick Sizing and Layout System** + +#### **Label Width Adjustment** +- **Dynamic Text Measurement**: Implemented canvas-based text measurement for accurate label width calculation +- **Real-Time Updates**: Brick dimensions update automatically when labels change +- **Fallback System**: Robust fallback for server-side rendering when canvas is unavailable + + +#### **Child-Based Resizing** +- **Bounding Box Calculation**: Parent bricks recalculate their bounding boxes based on their children's dimensions +- **Compound Brick Layout**: Compound bricks expand their nested regions to accommodate all nested children +- **Automatic Geometry Updates**: Brick geometry updates trigger re-rendering with new dimensions + + +### 3. **Advanced Rendering Algorithms** + +#### **Two-Phase Rendering Strategy** +- **Phase 1 - Preorder Traversal**: Calculate all bounding boxes and dimensions from root to leaves +- **Phase 2 - Postorder Traversal**: Render from leaves to root, ensuring children appear on top of parents +- **Z-Index Management**: Proper layering prevents visual conflicts between nested elements + +#### **Bounding Box Computation** +\`\`\`typescript +function computeBoundingBoxes(allNodes: Map<string, ExtendedTreeNode>) { + // Preorder traversal for dimension calculation + // Handles nested, argument, and stacked children + // Updates compound brick layouts with nested content + // Returns comprehensive bounding box map +} +\`\`\` + +### 4. **Comprehensive Validation Systems** + +#### **Brick Type Validation** +- **Nesting Validation**: Only Compound and Simple bricks can be nested inside other bricks +- **Argument Validation**: Only Expression bricks can be used as arguments +- **Connection Validation**: Ensures compatible brick types for different connection types + +#### **Connection Point Validation** +- **Notch Compatibility**: Validates that connecting bricks have compatible notch types +- **Slot Availability**: Ensures argument slots are available before allowing connections +- **Nested Space Validation**: Verifies sufficient space in compound bricks for nested children + +### 5. **Brick Model System** + +Refined the brick model architecture with advanced features: +- **SimpleBrick**: Basic statement bricks with configurable notches and argument support +- **ExpressionBrick**: Value-holding bricks with expression support and argument-only usage +- **CompoundBrick**: Container bricks with nested children support and dynamic sizing + +--- + +## Technical Implementation Details + +### Advanced Tree Structure +\`\`\`typescript +interface ExtendedTreeNode extends TTreeNode { + isNested?: boolean; // Indicates nested brick + argIndex?: number; // Argument slot index + children?: { + nested: ExtendedTreeNode[]; + args: ExtendedTreeNode[]; + stacked: ExtendedTreeNode[]; + }; +} +\`\`\` + +### Dynamic Sizing Algorithm +\`\`\`typescript +function updateCompoundBrickLayouts(nodes: Map<string, ExtendedTreeNode>) { + // Calculate total nested content dimensions + // Update compound brick's bboxNest array + // Trigger geometry recalculation + // Update connection points +} +\`\`\` + +### Validation System +\`\`\`typescript +function validateBrickConnection(parent: BrickModel, child: BrickModel, type: ConnectionType) { + switch(type) { + case 'nested': + return parent.type === 'Compound' || parent.type === 'Simple'; + case 'argument': + return child.type === 'Expression'; + case 'stacked': + return child.type !== 'Expression'; // expression brick can't be stacked + } +} +\`\`\` + +--- + +## Challenges & How I Overcame Them + + +### Challenge 1: Compound Brick Layout with Multiple Nested Children +**Problem**: Compound bricks needed to accommodate multiple nested children with varying sizes and positions. +**Solution**: Implemented a two-phase approach: first calculate all child dimensions, then update parent bounding boxes and trigger geometry recalculation. Developed a recursive algorithm that calculates bounding boxes bottom-up, then renders top-down with proper z-indexing to ensure children appear above parents. + +### Challenge 2: Label Width Calculation and Dynamic Updates +**Problem**: Bricks needed to resize based on their label text, requiring accurate text measurement and real-time updates. +**Solution**: Implemented canvas-based text measurement with fallback for server-side rendering, and integrated it into the brick geometry update system. + + + +--- + +## Key Learnings + +- **Advanced Tree Algorithms**: Deep understanding of preorder/postorder traversal for different rendering phases +- **Dynamic Layout Systems**: Learned how to implement responsive layouts that adapt to content changes +- **Canvas Text Measurement**: Mastered techniques for accurate text measurement in web environments +- **Z-Index Management**: Gained expertise in managing visual layering in complex nested structures +- **Type-Safe Validation**: Enhanced skills in creating comprehensive validation systems with TypeScript + +--- + +## Resources & References + +- **Tree Traversal Algorithms**: [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects) +- **Canvas Text Measurement**: [MDN Canvas Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) +- **TypeScript Validation Patterns**: [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/advanced-types.html) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for their guidance and support. Special thanks to the community for providing valuable feedback on the tree model design and implementation. + +--- +`,ri=Object.freeze(Object.defineProperty({__proto__:null,default:_n},Symbol.toStringTag,{value:"Module"})),En=`--- +title: "GSoC ’25 Week 07 Update by Aditya Kumar Singh" +excerpt: "Enhanced shared mode synchronization for Tour and Doctor activities, improved scoring visualization, and camera state persistence in the 3D Human Activity." +category: "DEVELOPER NEWS" +date: "2025-06-30" +slug: "2025-06-30-gsoc-25-AdityaKrSingh26-week07" +author: "@/constants/MarkdownFiles/authors/aditya-singh.md" +tags: "gsoc25,sugarlabs,week07,AdityaKrSingh26" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 07 Progress Report by Aditya Kumar Singh + +**Project:** [Sugarizer](https://github.com/llaske/sugarizer) +**Mentors:** [Lionel Laské](https://github.com/llaske) +**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) +**Reporting Period:** 2025-06-19 - 2025-06-25 + +--- + +## Goals for This Week + +- **Goal 1:** Implement shared mode synchronization for Tour activity +- **Goal 2:** Enhance Doctor mode to show XO Icons and name with real-time scoring visualization +- **Goal 3:** Persist camera zoom and orientation across sessions +- **Goal 4:** Add support for side and back view positioning in Tour + +--- + +## This Week’s Achievements + +1. **Shared Tour Mode** + - Implemented broadcast message \`tourStep\` carrying the part index & name; the host fires it and peers replay it to keep camera position and mesh highlight in lock-step. + - Added graceful join-in-progress sync: newcomers receive the current step and camera pose on \`syncAllPaintData\`, so nobody is “mid-tour-lost”. +  + \`\`\`javascript + // Broadcast tour step to other users + presence.sendMessage(presence.getSharedInfo().id, { + user: presence.getUserInfo(), + action: "tourStep", + content: { + index: tourIndex, + partName: part.name + } + }); + + // Sync handler + function syncTourStep(index, partName) { + const part = bodyParts[index]; + const currentMesh = currentModel.getObjectByName(part.mesh); + + // Highlight mesh + currentMesh.material = new THREE.MeshStandardMaterial({ + color: new THREE.Color("#ffff00"), + emissive: "#ffff00", + emissiveIntensity: 0.2 + }); + + // Position camera + camera.position.set( + part.position[0], + part.position[1], + part.position[2] + 5 + ); + camera.lookAt(part.position[0], part.position[1], part.position[2]); + } + +2. **Shared Doctor Mode** + - Re-used the Presence layer from Paint mode to emit nextQuestion / answer / scoreUpdate events. + - First-correct-gets-the-point logic now lives entirely on the host + - Peer-to-peer visual feedback: *correct click flashes the mesh green, wrong click red*; scores float next to each user’s XO badge +  +  +  + + +3. **Camera & Zoom Persistence** + - Stored \`cameraPosition\`, \`cameraTarget\`, and \`cameraFov\` in the Journal JSON when the Stop icon is pressed. + - On activity resume we restore both orbit target and FOV, giving users continuity—especially useful after deep-dive zooms into organs. + \`\`\`javascript + // Saving camera state + function saveCameraState() { + return { + position: { + x: camera.position.x, + y: camera.position.y, + z: camera.position.z + }, + target: { + x: orbit.target.x, + y: orbit.target.y, + z: orbit.target.z + }, + fov: camera.fov + }; + } + // Restoring camera state + function restoreCameraState(state) { + camera.position.set(state.position.x, state.position.y, state.position.z); + orbit.target.set(state.target.x, state.target.y, state.target.z); + camera.fov = state.fov; + camera.updateProjectionMatrix(); + orbit.update(); + } + +4. Side and Back View Support for Tour +- Extended body part data (\`organParts.json\`) to include \`sideView\` and \`frontView\` flags. +- Tour camera now automatically adjusts orientation: + - **Side view** → +X + - **Back view** → −Z + - **Front view** → +Z (default) +- Created adaptive camera logic in \`activity.js\` to interpret these flags. +  +  + + +--- + +## Key Learnings + +- Three.js Camera Control: Mastered advanced camera manipulation techniques +- Real-time Sync Patterns: Developed robust synchronization for 3D interactions +- Educational UX: Learned principles for effective learning feedback systems + +--- + +## Next Week’s Roadmap + +- Write Weekly Blog Post summarizing progress, screenshots, and key learnings. +- Fix remaining issues for Human body mentioned in PR +- Start to implement the dashboard features of the stickman activity: draw, move +- Start with implementing the Frame part of the stickman activity, add a frame, remove a frame, + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,si=Object.freeze(Object.defineProperty({__proto__:null,default:En},Symbol.toStringTag,{value:"Module"})),Dn=`--- +title: "SSoC ’25 Week 04 Update by Muhammad Haroon" +excerpt: "Experimenting with prompts parameter in AudioGen model." +category: "DEVELOPER NEWS" +date: "2025-06-30" +slug: "2025-06-30-ssoc-25-MuhammadHaroon-week04" +author: "@/constants/MarkdownFiles/authors/muhammad-haroon.md" +tags: "ssoc25,sugarlabs,week04,GenAI,MusicBlocks,Music" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 04 Progress Report by Muhammad Haroon + +**Project:** [Generative AI Instrument Sample Generation for Music Blocks](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md#Generative-AI-Instrument-Sample-Generation-for-Music-Blocks) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-23 - 2025-06-30 + +--- + +## Goals for This Week + +- **Goal 1:** To further explore the effects of the temperature and top_p parameters. +- **Goal 2:** To find an effective method for removing silence and noise from audio. + +--- + +## This Week's Achievements + +1. **Explored the effects of the temperature and top_p parameters** + - After experimenting with different temperature and top_p values, I found that AudioGen performs well with temperature = 1 and top_p = 1 values, generating audio that closely matches the prompt. + +2. **Found effective method for removing silence and nosie form audio** + - I found python libraries for removing silence (pydub) and noise (noisereduce) from the audio and it gave good results. + +--- + +## Next Week's Roadmap + +- Generate more samples using different prompts. +- Explore how to connect backend with the frontend using FastAPI. +- Explore how to deploy the backend on AWS. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,li=Object.freeze(Object.defineProperty({__proto__:null,default:Dn},Symbol.toStringTag,{value:"Module"})),jn=`--- +title: "GSoC '25 Week 04 Update by Shubham Singh" +excerpt: "Pivoted from Point Scanner to Line Scanner, got some real results." +category: "DEVELOPER NEWS" +date: "2025-07-01" +slug: "2025-07-01-gsoc-25-firepheonix-week04" +author: "@/constants/MarkdownFiles/authors/shubham-singh.md" +tags: + - gsoc25 + - sugarlabs + - week02 + - firepheonix +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 4 Progress Report by Shubham Singh + +**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) +**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-06-23 – 2025-06-30 + +--- + +## Goals for This Week + +- Implement complete Core Implementation of Scanning the Lego Blocks image on the X-axis. +- Focus on algorithmic challenges for note-to-color mapping system. + +--- + +## This Week's Achievements + +1. **Tested out the scanning errors. Realized the scanning single pixels isnt' gonna work.** + - So after testing out multiple errors, I realized that the DOT scanning method just isn't working that accurately(only ~40% accuracy). It's completely because of the core functionality of how the method itself works. + - So, I realized there has to be a better method than this. Scanning have been taking place for a long time. There had to be a better method than this. + - Began reverse engineer everything. Questioning every decision I've made for this project. Going to the very core of how the entire process, storage, time complexity is going on with the dot method. +  + +2. **Tested out spherical method. Failed.** + - Implemented the spherical method. It basically takes an AVERAGE of all the pixels underneath it rather than a scanning a single pixel. I did this keeping in mind more and more accuracy, + - Little did I know, I ran into more errors and worse accuracy than before. + +  + +3. **Finally reached an optimal, LINE scanner. Highly balanced. Got to a VERY good accuracy level.** + - Learned it the hard way why all bar code scanners are line type scanners. Why all machines (like, even your local printer machine/ or laser scan) follow the line scanning method. Got the best results and very a good accuracy. + +  + + - Now, this doesn't mean that the line scanner doesn't have it's cons. It has cons like the texture-confusion in a place where the block's edge is there, and the green background. But, such a confusion edge is only for a VERY small time. I predict it to be < 0 ms, hence automatically being ignored by the algorithm. And there are some issues still left to be fixed. + +4. **Made an output system for TESTING the accuracy of algorithm.** + - I ofc was not able to see how my output is through a mere array{{}} type console.log(). + - So, I developed this method of outputting of the colors on .png type image. To make it visually seem like the image itself for a DIRECT comparision. + +  + +  + + - Now I am rather thinking of making use of THIS .png output instead, it's simply good. Should I? Or should I not? Gonna have to ask from my mentors and do some research on this. + + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Was getting stressed about why am I not able to get the accuracy I need. +**Solution:** Reverse engineered stuff. Thought on my own. Research on youtube- how do scanning algorithms actually work? +- **Challenge:** Not being to see if my algorithm is accurate or not. +**Solution:** Made it output the array in the format of a .png format instead of a simple console.log(array). + +--- + +## Key Learnings + +- Reverse engineering always works. Dive in the BASICS. See the core of how everything is working. Make your human brain work more than asking AI for suggestions. It's possible that you're making things complicated with AI when the answer is really simple and lies in basic thinking. +- Figuring out what will work <<<< Figuring out what DOES NOT WORK. + +--- + +## Next Week's Roadmap + +- Implement the exisiting music blocks number to color mapping system that already exists (as suggested by my mentor, Walter) +- Implementing the dynamic input of NOTES like in the phrase maker. +- Figure out how the phrase maker has many different instuments with different audio files and LOADING them into legobricks.js +- Fix some more issues in the scanning that are visible to me. +- Once the above is done, we can move to mapping the lengths to corresponding notation lengths and production of musical notations. Initial weeks will be mostly figuring out the method for figuring out length of each block for each notation, am I going to use grid? Or will I use The lengths? Or will it be the time? + +--- + +## Resources & References + +- **Some youtube videos related to arduino color detection** + +--- + +## Acknowledgments + +Thank you to my mentors [Walter Bender](https://github.com/walterbender) and [Devin Ulibarri](https://github.com/pikurasa) for invaluable guidance throughout this development phase. Special thanks to Devin. I had typhoid last week due which I had a week of backlog in my work. He didn't mind at all. Happy have such cooperative mentors :p . +P.S.: I've finally caught up to the work I missed. + +---`,di=Object.freeze(Object.defineProperty({__proto__:null,default:jn},Symbol.toStringTag,{value:"Module"})),Wn=`--- +title: "DMP ’25 Week 5 Update by Aman Naik" +excerpt: "This week focused on improving the story framework display UI and attempting to deploy an LLM model on AWS." +category: "DEVELOPER NEWS" +date: "2025-07-05" +slug: "2025-06-05-dmp-25-AmanNaik-week05" +author: "@/constants/MarkdownFiles/authors/amannaik247.md" +tags: "dmp25,writeactivity,write,sugarlabs,week05,amannaik247" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 5 Progress Report by Aman Naik + +**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) +**Reporting Period:** 2025-06-29 – 2025-07-05 + +--- + +## Goals for This Week + +- **Goal 1:** Finalize the UI to display the generated story framework +- **Goal 2:** Create an API endpoint to host an LLM model on AWS + +--- + +## This Week’s Achievements + +1. **Worked on Story Framework Display UI** + - Designed and implemented a widget within Sugar to display the generated story framework. + - Although the basic version is functional, it still needs design improvements to make it more engaging and intuitive for children. + +  + +  + + +2. **Attempted AWS LLM Deployment** + - Made an initial attempt to deploy an LLM model on AWS. + - Faced permission issues during the process, which blocked progress. I plan to resolve this in discussion with mentors and continue deployment next week. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Creating a child-friendly UI for the framework display + **Solution:** Designing a UI that clearly represents story elements while remaining easy to understand for young learners was tricky. Through trial and error, and repeated testing, I managed to connect the output with the UI successfully. + +- **Challenge:** AWS deployment blocked by permission issues + **Solution:** Will consult with mentors to resolve the issue and resume progress on hosting the LLM next week. + +--- + +## Key Learnings + +**Learned the Complexity of Designing Educational UIs** + - UI for children must be both simple and informative. Building the framework display taught me how to balance functionality with visual clarity. + +**Encountered and Tackled Real-World Deployment Hurdles** + - Faced permission-related roadblocks during AWS deployment. This helped me understand the practical challenges of managing cloud-based services. + +**Learned the Importance of LLM Selection and Hosting Before Testing Flow** + - Since I am working with a Groq API using llama-versatile-70b model for testing. But due to license issues this wont be the final API used for deployment. + - Realized that choosing and hosting the right LLM model is critical before properly testing the conversation flow. The AI’s behavior is tightly linked to the model used, making this step a top priority for the coming week. + +--- + +## Next Week’s Roadmap + +- Finalize the LLM model and deploy it on AWS +- Complete and finalize the story framework display UI + +--- + +## Acknowledgments + +Thank you to my mentors and the Sugar Labs community for their continued feedback, guidance, and patience as I work through these technical and design challenges. + +--- +`,ci=Object.freeze(Object.defineProperty({__proto__:null,default:Wn},Symbol.toStringTag,{value:"Module"})),On=`--- +title: "GSoC '25 Week 5 Update by Krish Pandya" +excerpt: "Animations, Toolbars, and a Playable Game" +category: "DEVELOPER NEWS" +date: "2025-07-05" +slug: "2025-07-05-gsoc-25-mostlyk-week05" +author: "@/constants/MarkdownFiles/authors/krish-pandya.md" +tags: "gsoc25,sugarlabs,week05,mostlyk" +image: "assets/Images/GSOC.png" +--- + +# Week 5: Animations, Toolbars, and a Playable Game + +**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) + +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky), [Juan Pablo Ugarte](https://github.com/xjuan) + +**Reporting Period:** June 22, 2025 – June 28, 2025 + +--- + +## Travel and Context + +This week started with an 8-hour flight from Hyderabad to Diu ( my hometown ) between Sunday and Monday. +And _YES_ , I am home, sweet home. It was fun working on animations , toolbars and the game. + + +## Animations and Toolbars + +So as discussed and sneak peeked in last week, first part was finishing the toolbar integration and that was done! I also added animations.py. +I have always been a big fan of animations, my first addition to my [PKMS Site](https://pkms.vercel.app/) ( Personal Knowledge Management System ) was a handcrafted and personal documentation of Manim which a python animation library. + +Now it has a lot of things but it started as a manim documentation. + +### Animations + +Added a few clean effects: + +- \`fade-in\` and \`fade-out\` +- \`color\` transitions +- \`scale-down\` + + +### Toolbars + +Features include and tested in example: + +- Full range of buttons: open, save, undo, redo, cut, copy, paste +- Multi-select toggles, zoom controls, view modes +- Toolbuttons ( This requires palette somehow so will be updated next week. Sorry for the wait! ) +- And because of that if someone wants to play the game, you would have to wait till next week for the palette finish and the ToolButton addition in library. + + +## Why Not HelloWorld Yet? + +The actual HelloWorld example has more dependencies than just graphics. It needs: + +- \`widgets.py\` +which further needs: + - \`RadioButton\`, \`ToolButton\`, \`ToolBarButton\`, \`PaletteMenuBox\` etc. + - A bunch of internal glue that isn't finalized yet + +A good HelloWorld will take a few more weeks to land, realistically. +It requires almost all graphics-related components working in unison. Instead of rushing a half-baked HelloWorld, I decided to make something fun using what I already have. + + +## The Game: Super Ball Dodge + +<iframe width="560" height="315" src="https://www.youtube.com/embed/B517C_LTCns?si=u4zGfRp0yEJca8_O" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> + +So I built a game. It's simple, but fully interactive, and it uses the toolkit as it currently exists ( well it uses ToolButton which is half baked, so you would be able to play it by next week, can watch the video to see what it is though! ). + +### Game Mechanics + +- Use \`WASD\`, arrow keys, or toolbar buttons to move +- Press \`P\` to pause, \`R\` to restart +- Touch the red ball and you lose +- Hitting walls increases your speed and randomizes your color +- Max speed is capped to keep it playable + +This game is both a stress test and a fun break. It's a good way to validate rendering, event handling, animation, and user interaction at once. +Also it kind of stands like a hello world alternative for now before everything is done in unison and final decisions are made. + + +## Summary of Progress + +- Built and finalized core animations +- Integrated and tested full-featured toolbar +- Added working event bindings and accelerators +- Created Super Ball Dodge as a game/activity testbed + +--- + +## Next Steps + +- Refactor window tests (they're not up to standard yet) +- Finalize and commit \`widgets.py\`, \`ToolButton\`, and all of \`pallete\` stuff. +- Start building the actual HelloWorld once widget infra is stable + +--- + +## Links + +- [Project Page](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) +- [Toolkit Repo (Python)](https://github.com/MostlyKIGuess/sugar-toolkit-gtk4-py) +- [sugar-ext (C bindings)](https://github.com/sugarlabs/sugar-ext) +- [Game Demo Video](https://youtu.be/B517C_LTCns) + + +## Closing Thoughts + +It's funny how animations were the thing that got me into this headspace of _I GOTTA DO SOMETHING DYNAMIC_ , and I have always loved geometry and maths. And I got to introduce and do something related to that this week and this game was the result of what came out this week and I am glad I got to do it. + +Until next week, +Krish! +(P.S. If you couldn’t tell already , I love hiding pop culture references and breaking the fourth wall in these posts. So yes, you, yup, you alright, the reader.... enjoy.) +`,ui=Object.freeze(Object.defineProperty({__proto__:null,default:On},Symbol.toStringTag,{value:"Module"})),Bn=`--- +title: "GSoC ’25 Week 05 Update by Bishoy Wadea" +excerpt: "Fifteen Puzzle" +category: "DEVELOPER NEWS" +date: "2025-07-05" +slug: "gsoc-25-BishoyWadea-week05" +author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" +tags: "gsoc25,sugarlabs,week05,BishoyWadea" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 04 Progress Report by Bishoy Wadea + +**Project:** [Fifteen Puzzle](https://github.com/Bishoywadea/FifteenPuzzle) +**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) +**Reporting Period:** 2025-06-29 - 2025-07-05 + +--- + +## Goals for This Week + +- **Goal 1:** Start implementing Fifteen Puzzle Game +--- + +## This Week’s Achievements + +### *Goal 1: add helpful video tutorial in Soma Cube Game* + +1. **add video in help button** + - commit: [modify code to handle help videos](https://github.com/Bishoywadea/Soma-Cube/commit/63a7daaa8009f5f54791cdf9081e765846135f70) + +--- + +### *Goal 2: Start implementing Fifteen Puzzle Game* +1. **UI Foundation & Game Board** + - Set up the game window with a functional 4x4 puzzle grid and animated tile movements. + - commit: [add basic board UI](https://github.com/Bishoywadea/FifteenPuzzle/commit/ee2a8ec0a87949a93f0093b558de5d760ef66d59) + - commit: [add animation for the board](https://github.com/Bishoywadea/FifteenPuzzle/commit/a09f407451cb0772eff80d605509854d76522d17) + + + +2. **Core Logic & Gameplay** + - Added full logic for tile shifting, move counting, and puzzle completion detection. + - commit: [add game logic](https://github.com/Bishoywadea/FifteenPuzzle/commit/28d835400fb80c32d0eebba7c08f83fcfe9f9c63) + +3. **Help System & UI Integration** + - Introduced help instructions and integrated the help button into the top toolbar for easier access. + - commit: [add help button](https://github.com/Bishoywadea/FifteenPuzzle/commit/494f212f83e469fe2f3c24dd54e398c903a77dcc) + + + + + +--- + +## Challenges & Solutions + +- **Challenge:** Creating a responsive and user-friendly tile movement system. + **Solution:** Implemented smooth tile animations and move validation logic to ensure accuracy and a satisfying user experience. + +- **Challenge:** Designing a clean UI that adapts to game states like playing, winning, or seeking help. + **Solution:** Built a modular UI with conditionally rendered elements such as move counters, help overlays, and success animations for clarity and flow. +--- + +## Key Learnings + +- Gained hands-on experience in building grid-based puzzle logic, including tile shifting, move tracking, and win condition detection. + +--- + +## Next Week’s Roadmap + +- Fix any feedback provided by members of the organization. +- Start implementing the Euclid’s Game. +--- +`,hi=Object.freeze(Object.defineProperty({__proto__:null,default:Bn},Symbol.toStringTag,{value:"Module"})),Rn=`--- +title: "GSoC '25 Week 5 Update by Elwin Li" +excerpt: "Weekly progress report for JSEditor updates" +category: "DEVELOPER NEWS" +date: "2025-07-05" +slug: "2025-07-05-gsoc-25-Elwin-Li-week05" +author: "@/constants/MarkdownFiles/authors/elwin-li.md" +tags: "gsoc25,sugarlabs,week5,javaScript editor,debugger,syntax highlighting" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 5 Progress Report by Elwin Li + +**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/config_driven_conversion/elwin) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) + +**Reporting Period:** 2025-06-29 - 2025-07-05 + +--- + +## Goals for This Week + +- **Goal:** Complete the debugger project and add syntax highlighting + +--- + +## This Week’s Achievements + +**Made PR for Debugger Project** + +The debugger project has been complete and a [PR has been made](https://github.com/sugarlabs/musicblocks/pull/4717). The functionalities that have been described in the [previous weeks post](https://www.sugarlabs.org/news/developer-news/2025-06-28-gsoc-25-Elwin-Li-week04) are all included in this PR, and the demonstration video is below: + +[youtube: ZVqi7zIJ9kw] + +**Basic Syntax Highlighting** + +I've added basic syntax highlighting to the JS editor, making it more pleasing to the eye. + +<a href="https://ibb.co/23vbzVqq"><img src="https://i.ibb.co/RT35Xr22/Screenshot-2025-07-06-at-12-28-58-AM.png" alt="Syntax Highlight"></a> + +--- + +## Key Learnings + +- Improved skills in UX design and keeping tools simple for the user +- Deepened understanding of highlightjs +- Improved skills in **debugging**, **code design**, and **collaboration workflows**. + +--- + +## Next Week’s Roadmap + +- Complete syntax highlighting to JSeditor code (including error highlighting) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,gi=Object.freeze(Object.defineProperty({__proto__:null,default:Rn},Symbol.toStringTag,{value:"Module"})),zn=`--- +title: "GSoC ’25 Week 05 Update by Mebin J Thattil" +excerpt: "New brains and new voices for Speak!" +category: "DEVELOPER NEWS" +date: "2025-07-06" +slug: "2025-07-06-gsoc-25-mebinthattil-week5" +author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" +tags: "gsoc25,sugarlabs,week05,mebinthattil,speak_activity" +image: "assets/Images/GSOCxSpeak.png" +--- + +<!-- markdownlint-disable --> + +# Week 05 Progress Report by Mebin J Thattil + +**Project:** [Speak Activity](https://github.com/sugarlabs/speak) +**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-29 - 2025-07-06 + +--- + +## Goals for This Week + +- **Goal 1:** Test out different Kokoro voices +- **Goal 2:** Integrate the SLM into Speak + +--- + +## This Week’s Progress + +### **1. Hey Kokoro, you sound different today** + +This week, I tested out different voices of Kokoro in two different ways: + +1. I tested them inside Speak, within Sugar, and it worked. It still uses the _hacky_ way of creating a temporary WAV file and then playing it via GStreamer, but it works. Streaming will be introduced soon. + + **Under-the-hood changes:** + - Kokoro currently uses the following stack: + > Text → Kokoro → handle phonemes via G2P engine → Misaki (primary G2P) → fallback → Espeak-ng + - Speak already uses Espeak. + - So I swapped Misaki's fallback with Espeak (instead of Espeak-ng) to reduce dependencies. + - I’ve yet to encounter a case that triggers the fallback, as Misaki is already quite good. + +2. I deployed a web app that lets you generate and mix audio. You can try it out [here](https://newstreamlit-frontend.blackpond-9921706d.eastus.azurecontainerapps.io/). + - The primary reason this was built as a web app is so that we can get kids to test this out and having things as a web app makes it easier. It's cruical for us to get real world feedback before proceeding with the implementation. + - This web app allows you to try out a plethora of different voices and also mix and match different voices to create basically infinite combinations. It's truly amazing the kind of voices you can create with this. + +  + + - It's a container app, meaning both the frontend (Streamlit) and backend (Kokoro - FastAPI) run as separate Docker containers hosted on Azure. + - The [Kokoro - FastAPI](https://github.com/mebinthattil/Kokoro-FastAPI) exposes an OpenAI-compatible API to generate audio. + - This allows us to stream audio output to a client using OpenAI’s Python libraries, like so: + + \`\`\`python + from openai import OpenAI + + client = OpenAI( + base_url="http://my_kokoro_backend:8880/v1", api_key="not-needed" + ) + + with client.audio.speech.with_streaming_response.create( + model="kokoro", + voice="af_sky+af_bella", # single or multiple voicepack combo + input="Hello world!" + ) as response: + response.stream_to_file("output.mp3") + \`\`\` + + - Another potential application of this setup (deploying as separate containers) is to bring Kokoro into pre-existing Speak with minimal dependency changes. + - This would work on low end machines with a stable internet connection, as audio is generated server-side and streamed to the client. + - While this wasn’t in the original plan, the current architecture makes it a _possibility_ worth exploring. + - The original plan was to have an offline only version of Kokoro that Speak uses for it's voice. + +#### _Understanding and playing with Kokoro:_ + +- **How voice names are read** + + Kokoro has a catalog of voices like \`af_bella\` or \`af_sky\`. + The first letter of the voice name indicates the language: + - \`a\` for American English + - \`b\` for British English + - \`j\` for Japanese + - \`m\` for Mandarin Chinese + - \`s\` for Spanish + - \`f\` for French + - \`h\` for Hindi + - \`i\` for Italian + - \`p\` for Brazilian Portuguese + + The second letter indicates gender: + - \`m\` for male + - \`f\` for female + + So \`af_bella\` would be American English, female. + +- **Different language options:** + + These do two things: + 1. Speak the text with an accent. + 2. Handle the language-specific text more effectively. + + Example: Using \`hf_alpha\` with both Hindi and English: + Input: + > नमस्ते, आप कैसे हैं? I can also speak in English as well! + + Output audio: + <iframe src="https://drive.google.com/file/d/1vd0V3hoZlEYQBhm9clSeeDz25qwtwXEE/preview" width="450" height="50" allow="autoplay"></iframe> + + I speak Hindi, and I can confirm it sounds correct. + This is a great example of how Kokoro can help kids learning new languages by combining accent and language aware pronunciation. + +- **Voice mixing:** + + - You can mix any of the available Kokoro voices. + - Mixing is done by assigning weights (between 0 and 1) to each voice. + - For example, mixing two voices with 0.5 weight each gives a 50-50 blend. + - Mixing three voices with weights 0.6, 0.3, and 0.1 gives a 60-30-10 blend. + - This allows for basically infinite voice combinations. + + This could be super useful for building *personas* in Speak, as each persona could have a unique voice! + +  + +**Links:** +- [Streamlit web app](https://newstreamlit-frontend.blackpond-9921706d.eastus.azurecontainerapps.io/) +- [Kokoro - Fast API](https://github.com/mebinthattil/Kokoro-FastAPI) +- [Streamlit Source Code](https://github.com/mebinthattil/Streamlit-Kokoro-Voice-Mixer-Demo) + +--- + +### **2. New brains for Speak** + +- I used the previously quantized Tiny Llama 1B GGUF model with llama-cpp-python inside Sugar, using it as the backend for Speak’s chatbot. +- Using llama-cpp gave great performance boosts, but there's a catch: + - Llama-cpp needs to be built for each OS and architecture. + - This complicates distribution and packaging. + - We can’t shift the build process to the client since most of them are using constrained hardware. + +- So I tried a different approach: fine-tune a smaller model that doesn't need such optimizations. +- I chose [Llama 135M](https://huggingface.co/amd/AMD-Llama-135m) (yes, *M*, not *B* 😄) and fine-tuned it on my [educational conversation dataset](https://github.com/mebinthattil/Education-Dialogue-Dataset). +- I cleaned and extended the dataset (cleanup scripts are in the repo). +- The model was fine-tuned on AWS Sagemaker. You can find the files [here](https://huggingface.co/MebinThattil/Llama-135M-FT/tree/main). +- The unquantized size is ~500MB, so post-quantization it should shrink further. + +But... + +- I didn’t proceed with quantization because the raw performance post finetuning wasn’t up to expectations. +- So next step: gather better data, retrain, and re-evaluate. +- Will also discuss next directions with mentors after the next fine-tune round. + +--- + +## Next Week’s Roadmap + +- Work on mechanics for voice switching and personas inside sugar. +- Improve dataset quality. +- Fine-tune the model again and evaluate performance. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for their ongoing support. + +---`,mi=Object.freeze(Object.defineProperty({__proto__:null,default:zn},Symbol.toStringTag,{value:"Module"})),Un=`--- +title: "GSoC '25 Week 05 Update by Shubham Singh" +excerpt: "Building and testing out the Image to video player" +category: "DEVELOPER NEWS" +date: "2025-07-05" +slug: "2025-07-05-gsoc-25-firepheonix-week05" +author: "@/constants/MarkdownFiles/authors/shubham-singh.md" +tags: + - gsoc25 + - sugarlabs + - week05 + - firepheonix +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 5 Progress Report by Shubham Singh + +**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) +**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-07-01 – 2025-07-07 + +--- + +## Goals for This Week + +- Fix some more issues in the scanning that are visible to me. +- Implementing the dynamic input of NOTES like in the phrase maker. + +--- + +## This Week's Achievements + +1. **Implemented dynamic input of Notes like in phrase maker.** + - So the very good thing about music blocks is, if you want to implement something, it's most LIKELY already there. Haha. So I scanned through the entire code of phrase maker's code and found out the code responsible for what type of input is taking place. Since I already extended the class LegoBricksBlock with StackClampBlock class, the input already worked, but for print block, since I used it as a dummy for future. + - Well turns out everything fell right into place and I figured out NOT only just the input, but the output of how phrase maker took place and I implemented it on to my own LegoBrick.js . I now completely understand how the output is working out. +  + + <iframe width="800" height="405" src="https://www.youtube.com/embed/ObNYq29QHZw?si=uoYPchoQUhbEnmY4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> + + +2. **Implemented the complete phrase maker pitch functionality by adding PitchBlocks.js.** + - I figured out how to configure the notes, yet struggled with hardcoded value on the octave, which is by default, 4. + - So I had to literally, manually go over the entire pitch-blocks.js and a few files. After making adjustments inside some of those files, I was finally able to get the octave as well. + +  + + <iframe width="800" height="405" src="https://www.youtube.com/embed/XpgFTjimPyc?si=fi9HxuN5o8BOP26J" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> + +3. **Finally - Testing out Devin's CMK'24 project.** + - I finally did what I've always wanted. It was Devin's experiments that inspired me to take up this ,project in core Javascript for music blocks. So, here's a quick summary, haha: + + - Devin led a project called “Lego Musical Notation for the Blind” during the CMK workshop, aiming to create a tactile music system using Lego bricks for visually impaired users. Working with Jamie Chelel from MIT’s K12 Maker Lab, they built a prototype where pitch was mapped vertically and time horizontally on a Lego baseplate. Different brick lengths represented note durations, and a special marker block acted like a clef to guide pitch reference. + +  + + - After building the basic physical model, Devin shifted focus toward digitizing the system. Devin, created a functional prototype of this scanning system, he encountered challenges when trying to assign precise, meaningful pitches within Scratch’s limitations. + + <iframe title="vimeo-player" src="https://player.vimeo.com/video/983707992?h=0b765ba25a" width="800" height="405" frameborder="0" allowfullscreen></iframe> + + - Now, as you can read in my previous, week04 blog, I was able to completely overcome the Technical Hurdle of not being able to detect colors with a very high accuracy from static images. + + - And, finally here's how the scanning result looks like. + +  + +  + + - I realize that the output is coming ONE ROW down. also, the print functionality, it's automatically adjusting the rows ONE down. Still left with some adjustments to make something to show across all the blocks. + + - This still won't cut it. It has to be more accurate than this. I'll continue to optimize further, but I'll move on to the next phase, which is music generation from next week. + +  + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Reading through multiple files + **Solution:** No solution, just did the old-fashioned, long way. Also read some documentation +- **Challenge:** Have a lot of college related in the upcoming week. + **Solution:** Woke up 2-3 sleepless nights to get more time?? Yeah that's what I did. + +--- + +## Key Learnings + +- If you're building something, for example, a full-stack frontend backend website, you shouldn't vibe code it with AI and THEN run into errors. Create a basic frontend -> Send post requests with some tool -> Then connect the backend. . And this applied here as well since I put the NOTES as input functionality first THEN the pitch. Build in steps. Plan it out better. Even better, use some LLM to plan it out for you step by step. +- I tried learning a LOT of stuff this week. I'm learning how CORE JAVASCRIPT in itself works and it's an amazing opportunity. I never knew any of the browser storage concepts, or for that matter, time complexity practical use case before hand. I'm just learning so in-depth. It's crazy good. + +--- + +## Next Week's Roadmap + +- Now we are getting on the main part, which is producing musical sounds with the printed output. I still have to figure out a way ALONG with that I also have my college related work I've got to do. +- Figuring out the when does music production START. This was mentioned by my mentor, Walter, that the music should start playing the moment the algorithm bumps into the FIRST color change from green. That's a START point. + +--- + +## Resources & References + +- **Nothing much, just Music Blocks documentation sufficed** + +--- + +## Acknowledgments + +Thank you to my mentors [Walter Bender](https://github.com/walterbender) and [Devin Ulibarri](https://github.com/pikurasa) for invaluable guidance throughout this development phase. I like how Devin actually reads everyone's blogs every single week. He's an inspiring person. +PS: If you're reading this blog Devin, I hope you're enjoying the details. + +---`,pi=Object.freeze(Object.defineProperty({__proto__:null,default:Un},Symbol.toStringTag,{value:"Module"})),Fn=`--- +title: "GSoC '25 Week 05 Update by Nikhil Bhatt" +excerpt: "Implemented historical forking using Git CLI to preserve commit history and securely update metadata for downstream workflows." +category: "DEVELOPER NEWS" +date: "2025-07-06" +slug: "2025-07-06-gsoc-25-nikhilbhatt-week05" +author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" +tags: "gsoc25,sugarlabs,week05,nikhilbhatt" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 05 Progress Report by Nikhil Bhatt + +**Project:** [Git backend for MusicBlocks](https://github.com/benikk/musicblocks-backend) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Reporting Period:** 2025-06-29 – 2025-07-06 + +--- + +## Goals for This Week + +- Investigate and solve the issue of missing commit history in forked repositories. +- Switch from GitHub API–based file copying to full repo cloning with Git CLI. +- Ensure \`metaData.json\` updates include a new hashed key and get committed to the fork. +- Maintain clean repo history and secure edit permissions for each forked project. + +--- + +## This Week's Achievements + +### Switched to \`forkWithHistory\` via Git CLI + +Previously, when users forked a project, only the latest files (\`projectData.json\` and \`metaData.json\`) were copied into a new repository via GitHub's REST API. This approach **did not preserve commit history**, making it impossible to trace past changes. + +To fix this: + +- I implemented a new backend function \`forkWithHistory()\` using \`git clone\`, \`git remote\`, and \`git push\` with a Personal Access Token (PAT). +- This ensured that **full commit history is retained** in forked repositories. +- Each fork gets its own hashed key securely stored in the updated \`metaData.json\`. + +- Commits now reflect actual history +- Forks maintain lineage via \`forkedFrom\` metadata +- All content and hashes are committed and pushed as part of the first commit + +--- + +### 🔐 MetaData Commit Confirmation + +- I ensured that after updating the hash and \`forkedFrom\` link, the file is committed and pushed using Git CLI commands (\`git add\`, \`git commit\`, \`git push\`). +- The Git identity is explicitly set for the commit using: + +--- + +## Challenges & How I Solved Them + +- **Challenge:** Missing commit history in GitHub API forks + **Solution:** Switched to using Git CLI and a service account PAT to clone and push the entire repository. + +- **Challenge:** Rate Limits with PATs + **Solution:** We're currently using a single org service account PAT. The rate limits (5,000 requests/hour) are more than enough for current needs, but we may consider switching to app-based or scoped PATs if traffic scales up. + +--- + +## Key Learnings + +- Learned how to automate git commands securely in Node.js (using child_process.execSync). +- Understood the limitations of GitHub’s REST API for repo-level history and collaboration. + +--- + +## Next Week's Roadmap + +- Discuss and analyse possible downsides of the current approach, ensuring good fallbacks +- Create a commit history feature students can see how their project evolved with time + +## Resources & References + +- [MusicBlocks Frontend Repo](https://github.com/sugarlabs/musicblocks) +- [musicblocks-backend](https://github.com/benikk/musicblocks-backend) +- [Octokit REST.js Library](https://github.com/octokit/rest.js) + +--- + +## Acknowledgments + +Thanks again to my mentors and the Sugar Labs community for feedback and support! +Looking forward to next week’s frontend PR features. +`,bi=Object.freeze(Object.defineProperty({__proto__:null,default:Fn},Symbol.toStringTag,{value:"Module"})),Nn=`--- +title: "GSoC '25 Week 5 Update by Safwan Sayeed" +excerpt: "Implementing the Symbol Table and Memory Module Integration" +category: "DEVELOPER NEWS" +date: "2025-07-06" +slug: "2025-07-06-gsoc-25-sa-fw-an-week5" +author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" +tags: "gsoc25,sugarlabs,week5,sa-fw-an" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 5 Progress Report by Safwan Sayeed + +**Project:** Music Blocks 4 Program Engine +**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-06-30 - 2025-07-06 + +--- + +## A Blog-style Retrospective + +This week I implemented the Symbol Table and integrated it with the Memory Module to manage variable scopes and dependencies effectively. This was a crucial step in preparing for the Abstract Syntax Tree (AST)-to-Intermediate Representation (IR) compilation logic, ensuring that our program engine can handle variable resolution correctly during the translation process. + +--- + +## Goals for This Week + +- Design the Symbol Table. +- Implement the Symbol Table in the Memory Module. +--- + +## This Week's Highlights + +1. **Symbol Table Design and Implementation** + - Designed the Symbol Table to manage variable scopes and dependencies effectively. + - Integrated the Symbol Table with the Memory Module to ensure proper variable resolution during AST-to-IR translation. + - Documented the design and usage patterns for future reference. + +--- + +## Challenges & Solutions + +- **Managing Variable Scopes:** + Initially faced challenges in ensuring that variable scopes were correctly maintained across different blocks of code. + *Solution:* Implemented a robust Symbol Table that tracks variable declarations and their scopes, allowing for accurate resolution during the AST-to-IR translation. + + +--- + +## Key Learnings + +- Gained a deeper understanding of how to manage variable scopes and dependencies in a compiler context. +- Learned how to design and implement a Symbol Table that integrates with the Memory Module to facilitate variable resolution during the AST-to-IR translation process. + +--- + +## Next Week's Roadmap + +- Start working on the execution engine that will interpret the generated IR instructions. +- Begin implementing the first set of IR instructions. +--- + +## Resources & References + +- **Repository:** [musicblocks-v4](https://github.com/sugarlabs/musicblocks-v4) + +--- + +## Acknowledgments + +Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their crucial guidance on compiler design principles and static compilation concepts. Their clarification on the AST-to-IR translation approach and emphasis on maintaining clean instruction generation patterns was essential for this week's successful progress. + +---`,fi=Object.freeze(Object.defineProperty({__proto__:null,default:Nn},Symbol.toStringTag,{value:"Module"})),qn=`--- +title: "GSoC ’25 Week 05 Update by Diwangshu Kakoty" +excerpt: "Reflection Learning Widget in Music Blocks" +category: "DEVELOPER NEWS" +date: "2025-07-06" +slug: "2025-07-06-gsoc-25-diwangshu-week05" +author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" +tags: "gsoc25,sugarlabs,week05,AI" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 05 Progress Report by Diwangshu Kakoty + +**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) +**Reporting Period:** 2025-06-29 - 2025-07-05 + +--- + +## Goals for This Week + +- **Goal 1:** Develop a 'reflection' widget in Music Blocks. +- **Goal 2:** Update Fast API server code. +- **Goal 3:** Fix bugs occured by these changes. + +--- + +## This Week’s Achievements + +1. **Develop a 'reflection' widget in Music Blocks** + - For this week, I have finally got the green light to work on the frontend of the project. I have started developing a 'reflection' widget in Music Blocks and it is almost comleted. It can be found in the Widget section. + + - The conversation history is stored in the client side. For every query, the widget sends a request to the FastAPI server with payloads like \`query\`, \`messages\` and \`mentor\`. The server then processes the request and returns a response. The response is then displayed in the widget. + + <a href="https://ibb.co/NdLhh6DX"><img src="https://i.ibb.co/21j227Vw/first-Reflection.jpg" alt="first-Reflection" border="0"></a> + +2. **Update Fast API server code** + - As mentioned in my first week's report that I made the Fast API endpoints \`/chat\` and \`/summary\`, I have now updated the code to handle the new 'reflection' widget. + + - The \`/chat\` endpoint now expects a payload with \`query\`, \`messages\`, and \`mentor\`. + + - The messages include only the conversation history between the user and the AI, excluding the system message. This is because each mentor has a unique system message, which is dynamically set by the server based on the mentor field in the payload. So, we can say that the client-side is not storing any kind of prompts or system message. + +--- + +## Challenges & How I Overcame Them + +- **Challenge 01:** I found difficulties in integrating the 'reflection' widget with the FastAPI server. The widget was not handling the response correctly. + + **Solution:** Although I was familiar with async/await and promises in JavaScript, I lacked sufficient hands-on experience. To ensure the widget properly awaited the server response before updating the UI, I revisited these concepts. I also implemented error handling to address any potential issues during API calls. + +- **Challenge 02:** The widget was not initializing the messages after re-opening it. + + **Solution:** This was a simple bug where I forgot to initialize the messages array in the widget's state. I fixed it by ensuring that the messages array is initialized when the widget is opened. +--- + +## Key Learnings + +- I gained hands-on experience with integrating a frontend widget with a backend server using FastAPI. +- I learned how to handle asynchronous operations in JavaScript, which is crucial for building responsive web applications. +- I improved my understanding of how to structure API requests and responses for a better user experience. + +--- + +## Next Week’s Roadmap + +- From the last meeting with my mentors, I have learned that saving a reflection session is very necessary. It will allow users to revisit their reflections later and also helps a lot in testing. Therefore, I will be implementing saving and loading reflection sessions in the Streamlit app. Infact, I have already made a download button that downloads a JSON file containing the conversation history. + +- I was also informed that the AI is asking too many follow-up questions, which is not ideal. I will be working on refining the prompts to reduce unnecessary follow-ups and give it a more natural conversation flow. + +- Implement other features like 'generate summary' and 'generate analysis' in the widget. + +- Store the conversation summaries in user's browser using localStorage, so that the user can revisit their reflections later. This will also help in testing the 'analysis' phase of the reflection learning cycle. + +--- + +## Resources & References + +- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) +- **Streamlit App:** [Reflection App](https://reflectionapp-2yoxtvn6sknvktme2zorvq.streamlit.app/) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,yi=Object.freeze(Object.defineProperty({__proto__:null,default:qn},Symbol.toStringTag,{value:"Module"})),Hn=`--- +title: "GSoC’25 Week 05 Update by Om Santosh Suneri" +excerpt: "AI-powered Debugger for Music Blocks" +category: "DEVELOPER NEWS" +date: "2025-07-06" +slug: "2025-07-06-gsoc-25-omsuneri-week05" +author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" +tags: "gsoc25,sugarlabs,week05,Debugger,AI,Music Blocks" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 05 Progress Report by Om Santosh Suneri + +**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) +**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) +**Reporting Period:** 2025-06-29 - 2025-07-05 + +--- + +## Goal for This Week + +**Migrating Music Blocks JSON-to-Text Converter to Streamlit App** + +--- + +## This Week’s Achievements + +### Introduction + +This week, I focused on one of the key deliverables of the project — **integrating the JSON-to-Text Representation Converter into a Streamlit application**. This marks a major step in our plan to create a seamless debugging experience for Music Blocks users. The converter, which was originally built using JavaScript, is now fully functional in Python via Streamlit and ready for integration with the AI-powered debugger. + +### What I Did + +#### Goal + +The previous tool was a **client-side JavaScript converter** that parsed JSON representations of Music Blocks projects and produced a structured, readable **tree-view text format**. The aim this week was to **translate this logic into Python** and build a **Streamlit interface** to make the tool backend-friendly and easily integrable with the AI Debugger app. + +#### Migration from JavaScript to Python + +Converting the JavaScript-based logic to Python wasn’t a simple one-to-one translation. It involved rethinking data structures, managing recursion differently, and carefully ensuring that **each Music Blocks "block" type was accurately represented** in the output. + +Key technical components of the migration included: + +* **Parsing the block structure**: + + * Each block in the JSON is structured like \`[block_id, block_type, ..., connections]\` + * The Python version uses dictionaries (\`block_map\`) and recursion to follow nested or sequential connections (\`clamp\` and \`stack\` logic). + +* **Handling specific block types**: + + * Each block type (like \`start\`, \`setmasterbpm2\`, \`newnote\`, \`repeat\`, etc.) has a distinct logic for representation. + * For example, the \`setmasterbpm2\` block may include a divider block to represent beat values (like \`4/4 = 1.00\`), which must be parsed recursively. + +* **Redacting base64-encoded content**: + + * Just like in the JS version, the Python converter checks for base64 strings (e.g., audio/image data) and replaces them with \`"data"\` to keep the output clean and safe. + +* **Maintaining tree formatting**: + + * I replicated the \`├──\` and \`│\` styled tree structure for visual clarity. + * Indentation is handled dynamically based on the depth of recursion. + +#### Enhancements Added + +While rewriting, I also took the opportunity to **extend the support to more block types** that weren’t handled earlier — for example: + +* \`arc\` +* \`incrementOne\` +* \`pitch\` +* \`text\` +* \`settransposition\` + +This ensures that even **newer or more complex Music Blocks projects** are parsed correctly and comprehensively. + +#### The Streamlit App + +Once the backend logic was ready, I integrated it with a user-friendly Streamlit interface. The app consists of: + +* A **text area** for JSON input. +* A **convert button** to trigger the parsing. +* A cleanly formatted **output section** with scrollable, monospaced text. +* Error handling for invalid or empty JSON. + +--- + +### Why It Matters + +Music Blocks is used in educational environments. One of the biggest challenges new users face is **understanding how blocks connect and function** under the hood. By converting the visual block code into a readable text format, this tool: + +* Makes debugging more accessible for students. +* Helps educators explain project logic in class. +* Provides an exportable, printable format of block logic. + +#### Foundational Component for the Debugger + +This converter will play a **crucial role** in the **AI-powered Music Blocks Debugger**. By giving a structured, simplified text representation of the project: + +* The LLM (Large Language Model) will better understand the project logic. +* It enables **embedding**, **chunk retrieval**, and **semantic search** for debugging. +* Users will be able to see both their visual project and a clean text summary on the same platform. + +#### Seamless Integration Ahead + +Now that the converter is in Streamlit (and Python), integrating it into the AI Debugger system becomes straightforward: + +* No need to mix JavaScript and Python — the backend stays unified. +* Users can input JSON and debug in the **same interface**. +* It aligns with the vector database and LLM pipeline we’re building. + +### 📸 Preview + +Here’s a quick preview of the app: + +<a href=""><img src="https://i.ibb.co/XZt6MF9k/Screenshot-2025-07-05-at-3-09-15-PM.png" alt="Convertor Streamlit interface"></a> + + +### Final Thoughts + +Rewriting an entire logic-heavy JavaScript app into Python was both challenging and rewarding. It made me deeply understand how each block works in Music Blocks and how a simple but well-structured parser can bring clarity to even the most complex visual projects. + +--- + +## Next Week’s Roadmap + +* Integrate the Streamlit-based converter directly into the AI Debugger interface. +* Improve the understanding of actions in the project by enhancing the LLM prompts. + +## Resources & References + +- **Repository:** [JSON to Text representation](https://github.com/omsuneri/JSON-to-Text-representation) +- **Repository:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) +- **Debugger Streamlit App:** [Music Blocks Debugger](https://debuggmb.streamlit.app/) +- **Directory for Projects:** [Embedding Project Set](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks/tree/main/data/docs) + + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,wi=Object.freeze(Object.defineProperty({__proto__:null,default:Hn},Symbol.toStringTag,{value:"Module"})),Kn=`--- +title: "SSoC ’25 Week 05 Update by Muhammad Haroon" +excerpt: "Generated additional samples using various prompts, which were then evaluated by mentors." +category: "DEVELOPER NEWS" +date: "2025-07-06" +slug: "2025-07-06-ssoc-25-MuhammadHaroon-week05" +author: "@/constants/MarkdownFiles/authors/muhammad-haroon.md" +tags: "ssoc25,sugarlabs,week05,GenAI,MusicBlocks,Music" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 05 Progress Report by Muhammad Haroon + +**Project:** [Generative AI Instrument Sample Generation for Music Blocks](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md#Generative-AI-Instrument-Sample-Generation-for-Music-Blocks) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-30 - 2025-07-06 + +--- + +## Goals for This Week + +- **Goal 1:** Generated more samples using various prompts, which were then evaluated by mentors. +- **Goal 2:** Explored FastAPI and AWS. + +--- + +## This Week's Achievements + +1. **Generated more samples using various prompts** + - I generated more samples using [various prompts](https://docs.google.com/spreadsheets/d/1lxMHoiE-4YB5oDYlXfSP9TK5iXWkGYWC33ll8weJIO8/edit?usp=sharing). These samples were stored in [Google Drive](https://drive.google.com/drive/folders/1jee1MAmsyNddbh-pTIOX9K6Wctbd6Cf9?usp=drive_link) and shared with the mentors. The mentors scored the sounds using the following Google Sheets: [Walter's Score](https://docs.google.com/spreadsheets/d/1gzh7w2o8TeUUaePqOSlN2bt1T7fofFeRNoGzxq97PPM/edit?usp=sharing) and [Devin's Score](https://docs.google.com/spreadsheets/d/1ozwnBbXLQKZY_EQ-p7I4y0PRtzkqUauYOwstVnvjxFU/edit?usp=sharing). The scores that could be assigned were: bad (1), fair (2), and good (3). Both Devin and Walter gave an average score of 1.485, indicating that the overall output quality was closer to bad than fair. After reviewing the score, it became evident that a new model was needed. + +2. **Explored FastAPI and AWS** + - I explored FastAPI for connecting the backend with the frontend and AWS for deploying our backend. + +--- + +## Next Week's Roadmap + +- Find another open-source model to generate high quality sound samples. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,vi=Object.freeze(Object.defineProperty({__proto__:null,default:Kn},Symbol.toStringTag,{value:"Module"})),Vn=`--- +title: "DMP’25 Week 05 Update by Justin Charles" +excerpt: "Setup a visual playground with drag-and-drop brick placement from a palette UI" +category: "DEVELOPER NEWS" +date: "2025-07-06" +slug: "2025-07-06-dmp-25-justin212407-week05" +author: "@/constants/MarkdownFiles/authors/justin-charles.md" +tags: "dmp25,sugarlabs,week5,justin212407" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 5 Progress Report by Justin Charles + +**Project:** Music Blocks 4 Masonry +**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-06-29 - 2025-07-06 + +--- + +## Goals for This Week + +- Set up the core **Playground UI** to serve as the editable workspace +- Build a **Palette** with available brick types and integrate it visually into the Playground +- Enable **drag-and-drop interactions** from the palette into the workspace + +--- + +## This Week’s Highlights + +### 1. **Playground Workspace Setup** + +Created a dedicated layout component for the brick workspace: +- Positioned using CSS grid to support side-by-side palette and canvas +- Styled with scrollable overflow to allow panning and scaling in future updates +- Prepares the base for rendering brick instances using spatial coordinates + + +### 2. **Brick Palette UI** + +Added Palette UI to playground: +- Lists all brick types with color-coded icons and labels +- Styled for compact visibility, allowing quick scanning of available bricks +- Each brick is draggable and includes metadata for \`type\`, \`defaultProps\`, and visual ID + +🎨 Gives users clear visual feedback about available building blocks before use + +### 3. **Drag-and-Drop from Palette to Playground** + +Implemented full drag-and-drop pipeline: +- **OnDragStart**: Attaches metadata (\`type\`, \`defaultProps\`) to the drag event +- **OnDrop**: Computes drop position relative to workspace container +- **Dispatch**: Triggers creation of a new brick model at the drop location via Recoil + +Supports extensibility for: +- UUID generation +- Position snapping +- Drag preview overlays + +--- + +## Challenges & Solutions + +**Challenge:** Drop positioning was inaccurate due to nested containers and scroll +**Solution:** Used \`getBoundingClientRect()\` to normalize the offset and compute absolute drop coordinates + +**Challenge:** Drag behavior caused unwanted rerenders across unrelated components +**Solution:** Memoized drag metadata using \`useRef\` and lifted shared handlers to a centralized manager + +--- + +## Key Learnings + +- **Component Composition** + Learned how to break large UI logic into isolated playground, palette, and renderer components for clarity + +- **Event Normalization** + Understood how native drag events behave in nested layouts and how to calculate relative drop points robustly + +- **State Orchestration** + Tied together UI state (hover/drag) and business state (brick model updates) using Recoil and internal \`BrickFactory\` functions + +--- + +## Next Week’s Roadmap + +- Implement dragging of bricks in the playground. +- Implement Collision Maps for colliding objects. +- Create a reverse mapping utility file to fetch all connection points. +--- + +## Resources & References + +- [musicblocks-v4 Repository](https://github.com/sugarlabs/musicblocks-v4) +- [MDN Drag and Drop Guide](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) +- [RecoilJS Docs](https://recoiljs.org/) + +--- + +## Acknowledgments + +Thanks to the my mentor Anindya Kundu team for helping me align on visual structure of palette. + +--- +`,ki=Object.freeze(Object.defineProperty({__proto__:null,default:Vn},Symbol.toStringTag,{value:"Module"})),Jn=`--- +title: "DMP ’25 Week 05 Update by Harshit Verma" +excerpt: "This week, I built a custom Markdown parser for VTE (Virtual Terminal Emulator), began evaluating model performance, and discussed age appropriate debugging practices with mentors." +category: "DEVELOPER NEWS" +date: "2025-07-07" +slug: "2025-07-07-dmp-25-therealharshit-week05" +author: "@/constants/MarkdownFiles/authors/harshit-verma.md" +tags: "dmp25,sugarlabs,week05,therealharshit" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 05 Progress Report by Harshit Verma + +**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-30 - 2025-07-06 + +--- + +## Goals for This Week + +- **Goal 1:** Develop a custom Markdown parser for VTE (Virtual Terminal Emulator). +- **Goal 2:** Begin model selection and optimization. +- **Goal 3:** Discuss best debugging practices for children. + +--- + +## This Week’s Achievements + +1. **Built a Lightweight Markdown Parser for VTE** + - Created a simple parser to interpret basic Markdown (like \`**bold**\`, \`- bullets\`, \`### headers\`) and display it using ANSI-style formatting in the VTE terminal. + - Iterated by testing different wording styles and instruction formats, which led to noticeably better visual output. +  + +2. **Started Model Evaluation and Optimization** + - Compared several models (like Mistral, CodeLlama, and others from Hugging Face) to balance output quality with local performance. + - The response was good but it was taking a lot of time to generate the response. + +3. **Had a Discussion on Debugging Practices for Children** + - Talked with mentors about how to present debugging in a way that encourages curiosity rather than frustration. + - Key ideas included: focusing on helpful language, start with contextualization, and offering clear, step-by-step suggestions. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Parsing Markdown in a VTE terminal widget. + **Solution:** Since VTE doesn't support rich text natively, I built a custom parser to translate basic Markdown into stylized terminal output using spacing, symbols, and ANSI codes. + +- **Challenge:** Running the model locally on CPU. + **Solution:** Faced performance limitations due to lack of GPU support. To address this, I explored the option of offloading model inference to AWS. + +--- + +## Key Learnings + +- Gained experience in building a custom parser, handling string pattern detection and safe rendering within VTE. +- Practiced simplifying technical content for young learners, focusing on clarity over complexity. + +--- + +## Next Week’s Roadmap + +- Work on setting CSS for Debugging terminal, to style it. +- Finalize model selection and prepare integration with Sugar-AI. +- Start working on saving debug history to Sugar Journal. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! + +--- +`,Si=Object.freeze(Object.defineProperty({__proto__:null,default:Jn},Symbol.toStringTag,{value:"Module"})),Xn=`--- +title: "GSoC ’25 Week 08 Update by Aditya Kumar Singh" +excerpt: "Resolved key issues in shared Paint & Tour workflows, introduced a real-time XO-icon leaderboard in Doctor mode, and bootstrapped the Stickman activity scaffold." +category: "DEVELOPER NEWS" +date: "2025-07-09" +slug: "2025-07-08-gsoc-25-AdityaKrSingh26-week08" +author: "@/constants/MarkdownFiles/authors/aditya-singh.md" +tags: "gsoc25,sugarlabs,week08,AdityaKrSingh26" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 07 Progress Report by Aditya Kumar Singh + +**Project:** [Sugarizer](https://github.com/llaske/sugarizer) +**Mentors:** [Lionel Laské](https://github.com/llaske) +**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) +**Reporting Period:** 2025-07-03 – 2025-07-09 + +--- + +## Goals for This Week + +- **Goal 1:** Bug-hunt Shared Paint & Tour PR (Restore zoom-out capability when a session starts at a custom FOV, Guarantee that newcomers instantly receive every painted mesh, Ensure the palette reflects the host-selected mode (Paint / Tour / Doctor) on join.) +- **Goal 2:** Finish Doctor refactor – replace the legacy username-only leaderboard with XO icons tinted to each participant’s Sugar colour. +- **Goal 3:** Kick-off Stickman Activity – create a blank shell with full toolbar assets ready for upcoming features. + + +--- + +## This Week’s Achievements + +1. **Fixed Zoom-Out Limitation** + - **Issue:** When the Human Body activity was opened with a custom zoom level, users were unable to zoom out due to improper FOV (Field of View) limits. + - **Fix:** + - Implemented clamped zoom logic by calculating and bounding the \`camera.fov\` value between 5° and 75°. + - Both scroll wheel and toolbar zoom now honor the same constraints. + - This method ensures that camera zoom respects a realistic viewing range, preventing the camera from getting stuck in an unusable state. + \`\`\`javascript + function getFov(zoom) { + return Math.min(Math.max(zoom, 5), 75); // clamp zoom to valid FOV range + } +2. **Shared Paint Mode – Late Joiner Synchronization** + - **Issue:** When a new user joined an already shared Paint session, the previously painted parts weren’t visible to them. + - **Fix:** + - The host maintains a complete list of painted parts and their corresponding color mappings in paintedPartsList. + - When a new user joins, the host invokes: \`sendFullPaintDataToNewUser(presenceId)\` + - This sends all \`meshName → hexColor\` mappings via the \`syncAllPaintData\` action. + - Peers then replay this data and apply consistent material colors to each 3D mesh + - This method ensures that camera zoom respects a realistic viewing range, preventing the camera from getting stuck in an unusable state. + + +3. **Mode Palette Sync Across Clients** + - **Issue:** The palette mode (Paint, Tour, Doctor) would sometimes display inconsistently across users in a shared session. + - **Fix:** + - Centralized mode state and now rebroadcast on every mode change. + - When any user joins, their client listens to \`syncCurrentMode\` and updates icons accordingly: + - **Effect:** UI remains consistent regardless of when users join or switch modes. + + +4. **Redesigned Doctor Mode Leaderboard with XO Icons** + - **Objective:** Replace the old leaderboard (just usernames and scores) with a Sugar-style UI using XO icons and user colors. + - **Implementation Highlights:** + - \`generateXOLogoWithColor(userColor)\`: A dynamic SVG generator that outputs an XO icon with the user’s stroke and fill colors, derived from Sugar presence data. + - \`showLeaderboard()\`: Constructs a ranked visual layout showing each user’s XO icon, name, and score—updated in real time with every correct answer. + - **Algorithm Steps:** + - Maintain a scoreBoard object mapping presenceId → {score, userInfo}. + - Upon a correct answer: + - Host sends a \`scoreUpdate\` broadcast. + - All peers update their UI leaderboard. + - Leaderboard HTML is re-rendered using updated user data and SVG icons. +  + + +3. **Stickman Activity – Initial Scaffold** + - Created an initial version of the activity. + - Toolbar now displays all expected icons (draw, move, add frame, delete frame, play, stop). + - Currently, button clicks do nothing—but the structure is laid out to integrate drawing and animation logic next week. +  + + + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Simultaneous paint broadcasts leading to race conditions. + **Solution:** Ensured all paints are stored only on host, then synced post-join via a single action. + +- **Challenge:** Dynamic XO SVGs without image files. + **Solution:** Used inline SVG with JS string templates to create colored icons on-the-fly. + + +--- + +## Key Learnings + +- Gained in-depth understanding of Three.js camera manipulation and persistence. +- Built a robust synchronization pattern using presence broadcasts and authoritative state snapshots. +- Practiced UI/UX consistency across Sugarizer activities with reusable SVG elements and Sugar-specific color schemes. + +--- + +## Next Week’s Roadmap + +- Write Weekly Blog Post summarizing progress, screenshots, and key learnings. +- Fix Remaining Issues in Human Body Activity +- Stickman Dashboard – Draw & Move +- Stickman Frame Management + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,Ii=Object.freeze(Object.defineProperty({__proto__:null,default:Xn},Symbol.toStringTag,{value:"Module"})),$n=`--- +title: "DMP ’25 Week 6 Update by Aman Naik" +excerpt: "This week involved integrating the LLM's story framework into the UI, user testing with school children, and successfully resolving AWS deployment issues." +category: "DEVELOPER NEWS" +date: "2025-07-12" +slug: "2025-07-12-dmp-25-AmanNaik-week06" +author: "@/constants/MarkdownFiles/authors/amannaik247.md" +tags: "dmp25,writeactivity,write,sugarlabs,week06,midterm,amannaik247" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 6 Progress Report by Aman Naik + +**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) +**Reporting Period:** 2025-07-06 – 2025-07-12 + +--- + +## Goals for This Week + +- Build a user interface for the generated story framework +- Integrate LLM-generated responses into the UI +- Get feedback from real students using the demo application +- Deploy an LLM model on AWS + +--- + +## This Week’s Achievements + +1. **Built the Story Framework UI** + - Designed and implemented the story framework display using GTK and GTK CSS. + - The UI now dynamically displays the story structure based on the JSON response received from the LLM. + - The framework was successfully demonstrated to mentors, who gave positive feedback on the overall integration and experience. + +2. **Integrated LLM Response Into the UI** + - Parsed the JSON response from the LLM and displayed each story element in dedicated sections within the app. + - Incorporated error handling for missing or blank story categories. + +  + +3. **Gathered Real-User Feedback Through a School Demo** + - Mentor [Devin Ulibarri](https://github.com/pikurasa) organized a hands-on testing session with 12 students across four different activity stations: + - LLM-Speak + - Story Builder + - Personas + - Students reflected on their experience via handouts. I’ll be analyzing their feedback to better understand their thoughts and identify areas of improvement. + +  + +4. **Resolved AWS Permissions Issue** + - Successfully resolved the permission issue that previously blocked AWS access. + - Now have access to SageMaker and am prepared to deploy the LLM model as planned in the upcoming week. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Handling incomplete or empty story categories in LLM responses + **Solution:** Added placeholders in the UI for missing categories. These placeholders guide the student with helpful questions (e.g., "What could be the turning point in your story?") to encourage further development. Future updates will include buttons for AI-generated suggestions. + +- **Challenge:** Gaining access to deploy on AWS + **Solution:** Through clear and timely communication with mentors, I was able to get the necessary permissions and understand more about how access control and user roles work in AWS. + +--- + +## Key Learnings + +**Learned How to Build and Parse Adaptive Story Frameworks in UI** + - Learned how to dynamically map LLM outputs into GTK UI components and ensure the experience remains useful even when some inputs are missing. + - Code of try and except block parsing the response given by the LLM to update story info: + + \`\`\`python + try: + start_idx = analysis.find('{') + end_idx = analysis.rfind('}') + 1 + if start_idx != -1 and end_idx != -1: + json_str = analysis[start_idx:end_idx] + story_data = json.loads(json_str) + return story_data + except Exception: + pass + # Return default structure if parsing fails + return { + "title": "", + "setting": "", + "character_main": "", + "character_side": "", + "goal": "", + "conflict": "", + "climax": "", + "helpers": "", + "villains": "", + "ending": "", + "theme": "" + } + \`\`\` + +**Valuable Experience from Real User Testing** + - Understood how students react to the tool, what excites them, and what confuses them — essential insights to shape the next phase of development. + +**Improved My Understanding of AWS Deployment Workflows** + - Resolved previous blockers and now have a clearer picture of how cloud model hosting works and how access can be securely managed. + +--- + +## Next Week’s Roadmap + +- Finalize the deployment of the selected LLM model using AWS SageMaker +- Make the sidebar panel collapsable so it can be accessed when needed +- Understand feedback of the UI based on student and mentor feedback + +--- + +## References + +_Quote from Devin Ulibarri (Mentor):_ +> "Since these are experimental, I was mildly concerned that a student might find something inappropriate, but nothing of the sort happened. One student made a story about a "Blob of Poop", but it wasn't too bad." + +This has prompted me to think about on how to make LLM responses more child-friednly and create strict restrictions for inappropriate content. + +--- + +## Midterm Progress Summary + +Over the past six weeks, I’ve made significant progress toward building an AI-powered assistant for the Write Activity: + +- **Week 1–2:** Explored different approaches to creative writing and finalized a guided AI-assisted architecture for story building. +- **Week 3:** Built a working demo using Streamlit and received initial mentor feedback. +- **Week 4:** Began integrating the demo into the Sugar Activity and created the first UI prototype with a sidebar chatbot. +- **Week 5:** Designed a widget to display the story framework and attempted to deploy the LLM model on AWS (later resolved). +- **Week 6:** Fully integrated LLM JSON responses into the app's UI, tested the tool(using the demo application) with 12 students, and gathered real-world feedback. Also successfully resolved the AWS access issue for upcoming deployment. + +These weeks have been packed with learning—from UI design for young learners to API integration, cloud model deployment, and real-user testing. With foundational blocks in place, I’m now ready to polish the experience and begin iterative improvements with real feedback in mind. + +--- + +## Acknowledgments + +A huge thank you to my mentors, especially Devin Ulibarri for arranging the user testing session. I’m also grateful to Walter, Ibiam, and the Sugar Labs community for their continued support and constructive feedback every week. + +--- +`,Ai=Object.freeze(Object.defineProperty({__proto__:null,default:$n},Symbol.toStringTag,{value:"Module"})),Yn=`--- +title: "GSoC '25 Week 6 Update by Elwin Li" +excerpt: "Weekly progress report for JSEditor updates" +category: "DEVELOPER NEWS" +date: "2025-07-12" +slug: "2025-07-12-gsoc-25-Elwin-Li-week06" +author: "@/constants/MarkdownFiles/authors/elwin-li.md" +tags: "gsoc25,sugarlabs,midterm,week6,javaScript editor,debugger,syntax highlighting" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 6 Progress Report by Elwin Li + +**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/config_driven_conversion/elwin) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) + +**Reporting Period:** 2025-07-05 - 2025-07-12 + +--- + +## Goals for This Week + +- **Goal:** Complete syntax/error highlighting, and conclude the project + +--- + +## This Week’s Achievements + +**Made PR for Syntax highlighting project** + +The syntax/error highlighting project has been complete and a [PR has been made](https://github.com/sugarlabs/musicblocks/pull/4723). This project adds syntax highlighting and error highlighting to the JS editor, making the editor easier to work with. The syntax highlighting was done using +the highlightjs library, and the error highlighting was done by using the acorn library to parse the JavaScript code, and marking down the location +of any errors, and doing some calculations to highlight the associating places red. + +Any syntax errors will not only cause the place of errors to be highlighted, but it will also print an error message in the console log. This will additionally make it easier for the user to understand when and where an error occurs. A demo of the highlighting is displayed below: + +<a href="https://ibb.co/VpVMyZFM"><img src="https://i.ibb.co/yB0gT1zg/Screenshot-2025-07-12-at-9-01-37-PM.png" alt="Syntax Highlight"></a> + +<a href="https://ibb.co/1YTRYQFx"><img src="https://i.ibb.co/Y4hf4QHG/Screenshot-2025-07-12-at-9-01-48-PM.png" alt="Error Highlight"></a> + +**Made prototype for prompt to valid JavaScript code that can convert to MusicBlocks AI** + +This week, I have also made a gemini wrapper that takes in a prompt such as "Play twinkle twinkle little star with the guitar" and outputs JavaScript code that specifically works with MusicBlocks, so the user can copy paste the result into the JSeditor, convert the code to blocks, and play the result. This was done with a Google gemini API call along with extensive prompt engineering making sure it knows exactly what kind of code works with MusicBlocks, and what kind of code will cause errors if attempted to convert to blocks. + +[youtube: BFY3Bbi8V2g] + +[youtube: TEGWOAf5iO4] + +## Midterm Progress Summary + +**Over the 6 weeks of GSoC, I have accomplished the following** + +### Community Bonding: Project Foundation +- **Planning and Research**: Defined project scope and educational goals +- **Initial Implementation**: Started with basic JavaScript-to-blocks conversion for rhythm, flow, number, and boolean palettes +- **Architecture Design**: Planned the overall system architecture and feature roadmap + +### Week 1: Architecture Breakthrough +- **Config-Driven Refactoring**: Developed JSON-based configuration system for block mappings +- **AST Integration**: Implemented Acorn parser for JavaScript code analysis +- **Pattern Matching**: Created flexible AST pattern matching for complex JavaScript constructs +- **Extensibility**: Made adding new blocks as simple as updating configuration files + +### Week 2: Complete Implementation +- **Full Block Support**: Extended system to support all compatible block types +- **Optimization**: Implemented JSON minification and config consolidation +- **Documentation**: Created comprehensive conversion guide and unit tests +- **Production Deployment**: Successfully deployed feature through merged PR + +### Week 3: Debugger Development +- **Interactive Debugger**: Built working debugger with breakpoint system +- **Variable Inspection**: Implemented real-time variable display and tracking +- **Visual Integration**: Connected debugger statements to visual blocks +- **Educational Features**: Added step-by-step execution and status block integration + +### Week 4: Debugger Refinement +- **UX Optimization**: Simplified debug mode and improved user interface +- **Status Block Enhancement**: Optimized variable management and display +- **Execution Control**: Enhanced integration with existing play controls +- **Bug Fixes**: Resolved execution flow and block behavior issues + +### Week 5: Final Integration +- **Debugger Completion**: Finalized debugger with comprehensive PR +- **Syntax Highlighting**: Added basic syntax highlighting to JavaScript editor +- **Production Ready**: Completed all planned features and deployed to production +- **Documentation**: Finalized user guides and technical documentation +--- + +## Key Learnings + +- Improved skills in UX design and keeping tools simple for the user +- Deepened understanding of highlightjs +- Learned Gemini API calls +- Improved skills in prompt engineering +- Improved skills in **debugging**, **code design**, and **collaboration workflows**. + +--- + +## Next Week’s Roadmap + +- Fine tune an LLM to work better with MusicBlocks specific requests + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- +`,Li=Object.freeze(Object.defineProperty({__proto__:null,default:Yn},Symbol.toStringTag,{value:"Module"})),Qn=`--- +title: "GSoC '25 Week 05, 06 Update by Saumya Shahi" +excerpt: "This week, I focused on building drag-and-drop utilities for bricks, developed a reverse mapping utility for coordinate-to-brick/tower lookup, and integrated these with the new collision map. Next up: visual interactions and user feedback!" +category: "DEVELOPER NEWS" +date: "2025-07-06" +slug: "2025-07-06-gsoc-25-saumya-shahi-week05" +author: "@/constants/MarkdownFiles/authors/saumya-shahi.md" +tags: "gsoc25,sugarlabs,week05,saumya-shahi" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 05 & 06 Progress Report by Saumya Shahi + +**Project:** [Masonry Module - Music Blocks v4](https://github.com/sugarlabs/musicblocks-v4) +**Mentors:** [Anindya Kundu](https://github.com/meganindya/) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-30 – 2025-07-06 + +--- + +## Goals for Weeks 05 & 06 + +- Build robust drag-and-drop utilities for bricks and palette +- Develop a reverse mapping utility to map coordinates to bricks/towers +- Integrate collision detection logic for interactive feedback +- Prepare for next week’s focus on visual feedback and user interactions + +--- + +## This Week's Progress + +### 1. **Drag-and-Drop Utilities for Bricks** + +This week, I focused on refining the drag-and-drop experience across both the palette and the workspace. +- **Unified Drag Logic:** The drag-and-drop system now works seamlessly, whether you’re moving bricks from the palette or rearranging them in the workspace. +- **Component Integration:** Real brick components are now fully draggable and interactable, making the workspace more dynamic. +- **Consistent State Management:** Drag state is now shared and updates are reflected instantly, ensuring a smooth user experience. + + + + +--- + +### 2. **Reverse Mapping Utility** + +I developed a utility that allows us to map any (x, y) coordinate to the corresponding brick and tower. +- **Efficient Lookup:** The utility uses bounding box and layout data for fast, accurate results. +- **Foundation for Visual Interactions:** This mapping is essential for features like selection, highlighting, and collision detection post processing. + +\`\`\`typescript +function getBrickAtCoordinate(x: number, y: number): { brickId: string, towerId: string } | null { + // Uses bounding box/layout data to find the brick and tower at (x, y) +} +\`\`\` + +--- + +### 3. **Collision Map Integration** + +- **Collaboration:** I worked closely with another contributor who implemented the core collision detection logic. +- **Utility Integration:** The drag-and-drop and reverse mapping utilities are now integrated with the new collision map, enabling real-time interaction and hit-testing. + + + +As a side project, I also built a visualizer for collision points on the workspace. While it’s not part of the final product, it was a valuable exercise in visualizing interactions. + + + +--- + +## Technical Details + +- **Component Reuse:** Brick components are reused across different parts of the app, reducing duplication. +- **Extensible Design:** The reverse mapping utility is designed to support future features like selection and tooltips. + +--- + +## Key Takeaways + +- **Component and State Reuse:** Reusing logic and state across the app improves maintainability and reliability. +- **Hit Testing:** Building efficient hit-testing utilities is crucial for interactive UIs. +- **Atomic Commits:** I continued to practice atomic commits for better codebase hygiene and easier reviews. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for your ongoing support and feedback. + +--- + +<!-- markdownlint-enable -->`,Ti=Object.freeze(Object.defineProperty({__proto__:null,default:Qn},Symbol.toStringTag,{value:"Module"})),Zn=`--- +title: "GSoC '25 Week 6 Update by Krish Pandya" +excerpt: "Palettes, Groups, and GTK4 Decisions " +category: "DEVELOPER NEWS" +date: "2025-07-15" +slug: "2025-07-15-gsoc-25-mostlyk-week06" +author: "@/constants/MarkdownFiles/authors/krish-pandya.md" +tags: "gsoc25,sugarlabs,week06,mostlyk,midterm" +image: "assets/Images/GSOC.png" +--- + + +# Week 6: Palettes, Windows, and GTK4 Decisions + +**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky), [Juan Pablo Ugarte](https://github.com/xjuan) +**Reporting Period:** July 7, 2025 – July 15, 2025 + +--- + +## Why This Blog is Two Days Late + +First off, a confession: this update is getting written on 15th instead of the usual Saturday, I was travelling back to my university and this week's work was plenty and important. +I wanted to make sure I gave the proper write-up it deserves, especially since it's also the time for **midterm** evaluations. So if you are reading this, thank you for patience. + + +## Midterm Evaluations: Reflections + +For this week we had to write about midterm evaluations and after 6 weeks we have the halfway point. To look back what's been done , what changed and why. This project has been as much about architectural decisinos and learning as it has been about code or just porting in itself. + +- Weeks 1–2: Laying the foundation, setting up the C and Python split, and getting the Meson build system working. +- Weeks 3–4: We move into event controllers, file attribute utilities, and the starting of python library. +- Weeks 5–6: Animations, toolbars, and a full rework of the palette system for GTK4 python library now. + +### What changed and why? + +- Modern GTK4 patterns: Embracing controllers, gestures, and popovers has improved both code quality and user experience. +- Testing and documentation: Every major change is now accompanied by example scripts and documentation, making it easier for others (and my future self) to pick up where I leave off. + +### Personal growth: +Beyond the code, the first half taught me a lot about communcation, documenting decisions and working with mentors across time zones. I'have learned to reason and think about changes, justify architectural decisions, think broad and wide and accept that sometimes the best solutions are just compromise! +I look forward for the next half where I can finalizing the widgets and graphics and get one or two activities ported. + +## The Palette Rewrite of '25 + +The palette system was one of the most challenging and complex rewrites till now, it wasn't a find and replace, original implementation was tied to our own gestures. And event model and widget hierarchy which has been changed significantly in GTK4. + + +### What's the update in the Palettes? + + +- Will be sharing the example videos on next week! But here's the technical gist that I remember is big: + +- \`Gtk.Popover\` is King: Instead of manually managing popup windows, the new \`Palette\` class now uses \`Gtk.Popover\` for the menu implementation. + +- Controllers over Signals: The tangled web of event signals is gone. All interaction is now handled by \`Gtk.EventController\` and \`Gtk.Gesture\` objects. +For example, hover detection in \`WidgetInvoker\` now uses \`Gtk.EventControllerMotion\`, and clicks are captured with \`Gtk.GestureClick\`. + +- Real Widgets for Menu Items: \`PaletteMenuItem\` is no longer a \`Gtk.EventBox\`. It is now a proper \`Gtk.Button\`, which gives us accessibility, theming, and correct behavior for free. CSS is used to style it to look like a menu item, removing the need for manual background color changes on hover. + + +- \`ToolButton\`: The GTK3 \`Gtk.ToolButton\` is deprecated. So as the replacement we have \`Gtk.Button\` subclass styled with CSS to be our toolbutton, integrated with the \`ToolInvoker\` and palette system. It handles the activate state drawing and accelerator setup using modern \`Gtk.Application\` actions. + +- Streamlined Invokers: All invoker classes (\`WidgetInvoker\`, \`CursorInvoker\`, \`ToolInvoker\`, \`TreeViewInvoker\`) have been refactored to use the new controller-based system. + +### Some Threads and Docs: + +- https://gitlab.gnome.org/GNOME/gimp/-/issues/7700 +- https://docs.gtk.org/gtk4/class.EventControllerMotion.html +- https://valadoc.org/gtk4/Gtk.Popover.html +- https://docs.gtk.org/gtk4/class.GestureClick.html + +--- + + +## Progress Snapshot + +- Palette System: Complete rewrite for GTK4, including \`Palette\`, \`PaletteGroup\`, \`PaletteMenuItem\`, and all \`Invoker\` types. +- ToolButton: A new, modern \`ToolButton\` widget from scratch. +- Examples: Added comprehensive demos (\`palette_example.py\`, \`palettegroup_example.py\`) to showcase every feature and edge case of the new system. + +--- + +## Looking Ahead + +With palettes and toolbuttons now on a solid GTK4 footing, the next weeks will focus on: + +- Finalizing the remaining widget infrastructure (\`widgets.py\`) and integrating it with the palettes. +- Porting an actual Sugar activity to use the new toolkit, putting our work to a real-world test. + +--- + +## Links + +- [Project Page](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) +- [New Python Library (sugar-toolkit-gtk4-py)](https://github.com/MostlyKIGuess/sugar-toolkit-gtk4-py) +- [New C Library (sugar-ext)](https://github.com/sugarlabs/sugar-ext) +- [Game Demo Video](https://youtu.be/B517C_LTCns) + +--- + +## Closing Thoughts + +Next half of this GSoC going to be fun! And also we merged Sugar-AI ( _yay!_ thanks to Ibiam for taking out time to sit on a meet and go through this ) now we can deploy and test our LLMs and try to have more fun that way as well. + +And YESS NOW YOU CAN PLAY THE GAME HEHE. + +Until next week (on time, I promise!), +Krish +`,Pi=Object.freeze(Object.defineProperty({__proto__:null,default:Zn},Symbol.toStringTag,{value:"Module"})),et=`--- +title: "GSoC ’25 Week 06 Update by Mebin J Thattil" +excerpt: "Optimizations and reading documentation" +category: "DEVELOPER NEWS" +date: "2025-07-13" +slug: "2025-07-13-gsoc-25-mebinthattil-week6" +author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" +tags: "gsoc25,sugarlabs,week06,mebinthattil,speak_activity" +image: "assets/Images/GSOCxSpeak.png" +--- + +# Week 06 Progress Report by Mebin J Thattil + +**Project:** [Speak Activity](https://github.com/sugarlabs/speak) +**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-07-07 - 2025-07-13 + +--- + +## Goals for This Week + +- **Goal 1:** Improve dataset quality +- **Goal 2:** Fine-tune the model again and evaluate performance +- **Goal 3:** Work on mechanics for voice switching and personas inside Sugar + +--- + +## This Week’s Progress + +### **1. Improving the dataset** + +I fine-tuned the model using the dataset I had before, but it didn’t meet expectations. The model's responses were often repetitive and lacked the nuanced, encouraging tone of a teacher. For instance, it would give correct but blunt answers without any of the supportive dialogue we were aiming for. At times it gave answers that were completely irrelevant to the question. + +To address this, the next logical step was to significantly improve the dataset. I expanded it with more diverse conversation types and a wider range of questions that children might ask. To better simulate a real learning environment, I added examples where the teacher corrects a child's factual mistakes or spelling errors. Finally, to make the interactions feel more natural, I included general conversational snippets like “I love pizza” or “I just woke up.” + +### **2. Fine-tune the model again and evaluate performance** + +I proceeded to fine-tune the [Llama 135M model](https://huggingface.co/amd/AMD-Llama-135m) again, this time on the [updated dataset](https://github.com/mebinthattil/AMD_Llama_135M). After testing its performance, the results were still disappointing. While the tone improved slightly, the model struggled to maintain context in longer conversations and sometimes produced irrelevant responses, likely due to the inherent limitations of such a small model. + +Wanting to give it one last shot, I generated an entirely new, higher-quality dataset using Gemini, focusing specifically on teacher-child conversational patterns(Next week I'll share a link to a repo where I aggregate all these different datasets and model outputs in different formats). After fine-tuning the model on this new dataset, it performed better than before but still fell short of my goals. The next step is to formally benchmark both fine-tuned versions against the 50 questions I used for [benchmarking earlier](https://llm-benchmarking-sugar.streamlit.app/) and add their results for a direct comparison. + +### **3. Work on mechanics for voice switching and personas inside Sugar** + +I began working on the mechanics for voice switching and persona selection within Sugar. Before diving into the UI, I decided to first optimize Kokoro's integration with the Speak activity. The current process, where Kokoro writes a WAV file that GStreamer then plays, introduces a delay of 2 - 4 seconds. My goal is to get Kokoro to stream audio data directly to GStreamer as a source, which can then be played out using dual sinks similar to Speak's current implementation. This part isn’t fully working yet, as it requires a deeper dive into GStreamer's internals. I've been studying the documentation and hope to have this optimization completed in a few days, after which I can resume implementing the voice switching and persona mechanics. + +### **4. Size Optimization** + +One of the hardest and most interesting parts of this project was to package the SLM, the TTS model, and all its required dependencies within very tight size constraints. Every single byte matters. + +These are the sizes of the components as of now: +- **TTS**: 0.7MB Base + 0.5MB for each additional voice +- **SLM**: 82.6MB +- **Llama.cpp**: + - if we choose to distribute binaries for llama-cpp that will be used for inference: 2MB + - else, I would need to look into optimization (not done yet) + +Main factors contributing to the small size of components were: +- **TTS**: Switching Kokoro's fallback to use espeak instead of espeak-ng, since espeak was already used by the Speak activity. It also helps that Kokoro is pretty lightweight with only 82M parameters. +- **SLM**: The biggest reason is the insanely small parameter count of the SLM. I'm using LLaMA-135M. Further quantization and converting to GGUF format helped. +- **llama-cpp** (local model inference): Compiling to binary helped reduce size. I did a specific compilation, so it did not build a binary for everything, only the inference binary for chat was built. + +So overall, including the TTS, SLM, and llama-cpp, the size of additional components would be ~85–110MB (85MB if we distribute the binaries, 110MB if we don't). Do note that the dependencies for the LLM have not been included, but those are pretty lightweight, since it's just calling an API endpoint. + +--- + +## Midterm Summary + +*It feels great to sit back and reflect on what I’ve done so far. I’ve learned a lot and had a lot of fun building things.* +- The first week started off with a lot of [benchmarking](https://llm-benchmarking-sugar.streamlit.app/). This was essential, as we needed to choose a model to fine-tune. +We tested various models on a standard set of questions, asking each model the same ones and comparing the responses. +I also ensured I had a clear understanding of the project constraints, especially the limited client-side hardware. This directly influenced many of the design decisions later on. + +- The second week was focused on setting up the AWS infrastructure. +AWS was configured, and the LLaMA3-1B foundation model was fine-tuned on the [education dataset](https://github.com/mebinthattil/Education-Dialogue-Dataset). +The dataset was cleaned and formatted for LLaMA, and after fine-tuning, it was deployed to AWS. +I then tested the API endpoint with a Python script. This gave us a solid base to move forward. + +- The third week was spent addressing a model behavior issue where it would generate long response chains instead of simple Q&A style outputs. +To fix this, I restructured the [dataset](https://github.com/mebinthattil/Education-Dialogue-Dataset). +That week also coincided with my exams, so progress was slower than usual. + +- In Week 4, I worked on [integrating Kokoro into Speak](https://drive.google.com/file/d/1Z-zQrnH56CDVFJnEMmm6DflwpajwrLmI/view?usp=sharing). +While I managed to integrate Kokoro TTS, it was a bit hacky. Kokoro saved WAV files, and GStreamer read from them. +I also built a [model quantization pipeline](https://github.com/mebinthattil/Model_Quantize_Pipeline) that allowed me to quickly quantize chat-style models from 🤗, convert them to GGUF, and run [inference with plugin](https://github.com/mebinthattil/template_llama_chat_python) support. +This significantly sped up testing and allowed me to observe the impact of quantization on output quality. + +- And finally, last week was spent building a [Streamlit app](https://newstreamlit-frontend.blackpond-9921706d.eastus.azurecontainerapps.io/) for experimenting with different Kokoro voices. The app let you try differnt voices in kokoro with different languages, and also had an option to blend and mix different voices to create a unique voice. +This app made it easier to demo the new TTS to kids and collect feedback. +I also integrated the SLM into Speak. I used \`llama-cpp-python\` during inference, which led to noticeable performance boosts. +The model used was a fine-tuned and quantized version of [Llama-135M](https://huggingface.co/MebinThattil/Llama-135M-FT/tree/main). +However, due to the model’s small size, the initial responses were underwhelming. Even with fine-tuning, the improvements were only slight. + +--- + +## Next Week’s Roadmap + +- Complete Kokoro streaming with GStreamer +- Work on UI enhancements and group Kokoro voices by language +- Add both variations of the SLM to the benchmark + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for their ongoing support. + +---`,Ci=Object.freeze(Object.defineProperty({__proto__:null,default:et},Symbol.toStringTag,{value:"Module"})),nt=`--- +title: "GSoC '25 Week 06 Update by Nikhil Bhatt" +excerpt: "Implemented commit history viewer and version loading system using Git CLI and new backend routes, enabling seamless time-travel across project states." +category: "DEVELOPER NEWS" +date: "2025-07-13" +slug: "2025-07-13-gsoc-25-nikhilbhatt-week06" +author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" +tags: "gsoc25,sugarlabs,week06,nikhilbhatt,midterm" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 06 Progress Report by Nikhil Bhatt + +**Project:** [Git backend for MusicBlocks](https://github.com/benikk/musicblocks-backend) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Reporting Period:** 2025-07-07 – 2025-07-13 + +--- + +## Progress Summary + +The first 6 weeks of GSoC'25 have been a great learning experience. The project is progressing as planned with meaningful improvements every week. <br/> +Our primary focus during this phase was the backend, with some attention to enhancing the user experience. +- Repository Creation with Ownership Tracking (using a Github app) - \`\`\`Github apps\`\`\` are safer, and scalable way of dealing with github directly, students can now create repositories directly into a centralised account, with ownership using a key, note that we do not save any user related information. +- Secure Editing Mechanism - even after publishing a project, students are able to edit their projects. Only those having a valid key can now edit their projects, in absence of that key, the project becomes \`\`\`read only\`\`\`. +- Forking with Metadata & History - Projects can be forked easily via the UI. Forked repositories retain original content and metadata,A later upgrade replaced basic copying with full Git CLI–based cloning, ensuring complete \`\`\`commit history is preserved\`\`\`. +- Commit History & Version Time Travel - Users can now select a commit from a UI modal and load the project state at that point. This feature introduces \`\`\`reflective-learning\`\`\` in students. +- Pull Request Workflow - an interesting addition to our existing planet based system, students can now contribute back to original projects after forking. The backend logic for this is complete and tested. Frontend integration is currently underway and will allow students to \`\`\`submit PRs with minimal effort.\`\`\` + +## A flow chart about the architecture of the project + + + +## This Week's Achievements + +### Backend: Commit History & Version Retrieval + +To support loading older versions of projects, I implemented two key backend routes using the Git CLI: + +- \`GET /api/github/commitHistory/?repoName\` + → Returns a list of all commit SHAs and messages for a given repository. + +- \`GET /api/github/getProjectDataAtCommit?repoName=""&sha=""\` + → Accepts a repo name and commit SHA, checks out the commit, and returns the \`projectData.json\` at that point in history. + +Both routes use secure Git Rest API methods. + +--- + +### 💡 Frontend: Modal Interface for Commit Viewer + +- Added a modal component that displays when the user clicks **"Show Commits"** from the GitHub dropdown. +- Each commit is rendered as a card showing the commit message, SHA, and a **"Load this version"** button. +- On click, the selected commit is sent to the backend, and the returned \`projectData\` is loaded using: + +--- + +## Challenges & How I Solved Them + +- **Challenge:** GitHub API only returns the latest file in current branch + **Solution:** Used GET /repos/:owner/:repo/contents/:path?ref=sha to fetch files at a specific commit. + +- **Challenge:** Loading project data for specific commits + **Solution:** Created an end point which takes the commit \`sha\` and returns the project data for that commit + +--- + +## Key Learnings +- How to use GitHub's REST API to interact with historical commit data. +- How to extract blob data (projectData) from specific commits using SHA. +- Importance of UX when introducing power-user features like history viewing. + +--- + +## Next Week's Roadmap +- Begin work on pull request functionality from forked projects. +- Enable students to raise PRs with metadata describing their changes. +- Explore preview diffs before PR submission. + +--- + +## Resources & References + +- [MusicBlocks Frontend Repo](https://github.com/sugarlabs/musicblocks) +- [musicblocks-backend](https://github.com/benikk/musicblocks-backend) +- [Octokit REST.js Library](https://github.com/octokit/rest.js) + +--- + +## Acknowledgments + +Thanks again to my mentors and the Sugar Labs community for feedback and support! +Looking forward to next week’s frontend PR features. + +`,Mi=Object.freeze(Object.defineProperty({__proto__:null,default:nt},Symbol.toStringTag,{value:"Module"})),tt=`--- +title: "GSoC '25 Week 6 Update by Safwan Sayeed" +excerpt: "Symbol Table Refinements, IR Instructions Design, and Interpreter Architecture" +category: "DEVELOPER NEWS" +date: "2025-07-13" +slug: "2025-07-13-gsoc-25-sa-fw-an-week6" +author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" +tags: "gsoc25,sugarlabs,week6,sa-fw-an,midterm" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 6 Progress Report by Safwan Sayeed + +**Project:** Music Blocks 4 Program Engine +**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-07-07 - 2025-07-13 + +--- + +## A Blog-style Retrospective + +This week marked a significant refinement phase in our Music Blocks program engine development as we focused on optimizing the Symbol Table design and laying the groundwork for the execution phase. The primary focus was on identifying and cataloging the IR (Intermediate Representation) instructions that will be implemented, followed by beginning the technical specification for the Interpreter module - the component that will bring our compiled IR code to life. + +The Symbol Table modifications were crucial for improving variable resolution efficiency and ensuring proper scope management. Working through the IR instruction identification process helped clarify the execution model and provided a clear roadmap for the interpreter implementation. + +--- + +## Six-Week Progress Summary + +Over the past six weeks, we've built a comprehensive foundation for the Music Blocks 4 Program Engine: + +**Weeks 1-2:** Established the core architecture with AST (Abstract Syntax Tree) framework and memory management system, implementing a three-scope hierarchy (Global, Thread, Local) with full CRUD operations. + + + +**Weeks 3-4:** Developed the AST-to-IR compilation logic, creating the crucial translation layer between abstract syntax trees and executable instructions using three-address code format. + +**Week 5:** Implemented the Symbol Table and integrated it with the Memory Module for effective variable scope and dependency management. + + + +**Week 6:** Refined the Symbol Table design, identified comprehensive IR instruction sets, and initiated the Interpreter architecture specification. + + + +This progression has taken us from initial planning to having a complete compilation pipeline ready for execution engine implementation. + +--- + +## Goals for This Week + +- Refine the Symbol Table design to improve variable resolution efficiency. +- Identify and catalog all IR instructions that will be implemented in the execution engine. +- Begin writing the technical specification for the Interpreter module. +- Define the interpreter's execution model and core implementation patterns. + +--- + +## This Week's Highlights + +1. **Symbol Table Design Modifications** + - Refined the Symbol Table implementation to improve variable resolution performance and scope management. + +2. **IR Instructions Identification** + - Conducted comprehensive analysis to identify all IR instructions required for the execution engine. + +3. **Interpreter Technical Specification** + - Started writing the technical specification for the Interpreter module architecture. + +--- + +## Challenges & Solutions + +- **IR Instruction Completeness:** + Ensuring we identified all necessary IR instructions for complete program execution support. + *Solution:* Systematically analyzed the AST compilation patterns and execution requirements to create a comprehensive instruction catalog. + +--- + +## Key Learnings + +- Gained deeper understanding of IR instruction design and Interpreter architecture. + +--- + +## Next Week's Roadmap + +- Complete the Interpreter technical specification with detailed implementation patterns. +- Begin implementing the first set of IR instructions in the execution engine. + +--- + +## Resources & References + +- **Tech Spec:** [Interpreter Architecture](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.vexvgnhpt90v) +- **Repository:** [musicblocks-v4](https://github.com/sugarlabs/musicblocks-v4) + +--- + +## Acknowledgments + +Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their continued guidance on compiler design principles and execution engine architecture. Their emphasis on maintaining clean separation between compilation and execution phases was crucial for this week's successful progress. + +--- +`,xi=Object.freeze(Object.defineProperty({__proto__:null,default:tt},Symbol.toStringTag,{value:"Module"})),at=`--- +title: "GSoC ’25 Week 06 Update by Diwangshu Kakoty" +excerpt: "Reflection Learning Widget in Music Blocks" +category: "DEVELOPER NEWS" +date: "2025-07-13" +slug: "2025-07-13-gsoc-25-diwangshu-week06" +author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" +tags: "gsoc25,sugarlabs,week06,AI,midterm" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 06 Progress Report by Diwangshu Kakoty + +**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) +**Reporting Period:** 2025-07-06 - 2025-07-13 + +--- + +## Progress Summary + +The first six weeks of GSoC'25 have been highly productive, with several key milestones already accomplished: + +- Developed a Retrieval-Augmented Generation (RAG) pipeline. +- Built a fully functional Streamlit application for testing. +- Implemented a multi-agent chat model. +- Experimented with reasoning models and explored their integration. +- Created API endpoints for backend functionality. +- Developed a "reflection" widget in Music Blocks. +- Added save and upload capabilities to the Streamlit app. + +## Goals for This Week + +- **Goal 1:** Add upload and download of session state in Streamlit app. +- **Goal 2:** Add code conversion function in Streamlit app. +- **Goal 3:** Implement periodic summary generation. +- **Goal 4:** Fix bugs occured by these changes. + +--- + +## This Week’s Achievements + +1. **Add upload and download of session state in Streamlit app** + - Users can now conveniently save their conversations by downloading them. If they wish to resume at a later time, they can simply upload the saved session to continue where they left off. + + <a href="https://ibb.co/XZB7HJMG"><img src="https://i.ibb.co/zhcXdfDt/image.png" alt="image" border="0"></a> + +2. **Add code conversion function in Streamlit app** + - Users can now copy their Music Blocks project code and paste it into the app. The app then uses a conversion algorithm developed by [Omsuneri](authors/om-santosh-suneri) to generate an equivalent flowchart, which is easier for the LLM to interpret. + + - This flowchart is sent to the reasoning_llm, which produces the algorithm, a summary, and the purpose of the code. These outputs are then utilized by lightweight models. + +3. **Implement periodic summary generation** + - Based on my mentor's suggestion, I am implementing automatic periodic summary generation instead of relying on a manual button. This approach keeps the conversation seamless and allows users to take notes as they go. + + - This feature is still a work in progress. + +4. **Fix bugs occured by these changes** + - This week's work focused primarily on debugging. There were issues with the download button and updating the session state after file uploads. Further details on these challenges will be covered in the next section. + +--- + +## Challenges & How I Overcame Them + +- **Challenge :** I encountered challenges in refreshing the session states upon file upload. The expected behavior includes updating the message history, selected mentor, and user interface, but these updates weren't occurring properly. + + **Solution :** Streamlit reruns the entire script each time a button is clicked — a core behavior of the framework. Many of the issues I faced were due to the improper ordering of session state declarations, which I have now resolved. Additionally, I enhanced the download functionality to include more comprehensive information in the saved file, such as the mentor's name, the message history, and the session title. + +--- + +## Key Learnings + +- I am becoming more experienced as a Streamlit developer. + +--- + +## Next Week’s Roadmap + +- Implement a widget with functionality to save conversations, session summaries, and analytical insights. +- Finalize the auto-summary generation feature. +- Deploy the FastAPI server on AWS. + +--- + +## Resources & References + +- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) +- **Streamlit App:** [Reflection App](https://reflectionapp-2yoxtvn6sknvktme2zorvq.streamlit.app/) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,Gi=Object.freeze(Object.defineProperty({__proto__:null,default:at},Symbol.toStringTag,{value:"Module"})),ot=`--- +title: "GSoC '25 Week 06 Update by Shubham Singh" +excerpt: "Music Player + Mid Term Evaluation" +category: "DEVELOPER NEWS" +date: "2025-07-13" +slug: "2025-07-13-gsoc-25-firepheonix-week06" +author: "@/constants/MarkdownFiles/authors/shubham-singh.md" +tags: + - gsoc25 + - sugarlabs + - week06 + - firepheonix +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 6 Progress Report by Shubham Singh + +**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) +**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) +**Reporting Period:** 2025-07-07 – 2025-07-13 + +--- + + +## Goals for This Week + +- Printing the outputs detected by the color detector. +- Implementing the music player. + +--- + +## This Week's Achievements + +1. **The music notations and their durations are now logged to the console** + - I finally logged all the colors to the console in a systematic way, without affecting projectstorage.js. +  + + +2. **Implemented the music playing feature** + - For example, the music player plays X rows, and the music for those X rows is played simultaneously, just like in the PhraseMaker. + - The system works on the principle: if green → no note played; if not green → note played. + - All notes are started simultaneously, then played according to their mapped timings. + - And here's a sample of the music generated. + + <iframe width="800" height="405" src="https://www.youtube.com/embed/ySjvYi936tg?si=FxZQn19AiLRixlpM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> + + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Wasn't able to figure out the next steps in development, and felt stuck while trying to find multiple ways of using the existing data. + **Solution:** I logged the data to the console and observed the PhraseMaker's approach to simultaneous playing. + +--- + +## Key Learnings + +- Sometimes logging the output to the console helps you take the next steps more effectively. For example, in API responses, you'll need to have the same type of UI as the type of response generated, so it's better to take care of that step beforehand. + +--- + +## Next Week's Roadmap + +- Build the action block output. +- Try to build a simple Do Re Mi Fa Sol La Ti sequence and its reverse, using exported action blocks in Music Blocks. + +--- + +## Resources & References + +- **Nothing much, just the Music Blocks documentation sufficed.** + +--- + +## Acknowledgments + +Thank you to my mentors [Walter Bender](https://github.com/walterbender) and [Devin Ulibarri](https://github.com/pikurasa) for invaluable guidance throughout this development phase. + +---`,_i=Object.freeze(Object.defineProperty({__proto__:null,default:ot},Symbol.toStringTag,{value:"Module"})),it=`--- +title: "GSoC’25 Week 06 Update by Om Santosh Suneri" +excerpt: "AI-powered Debugger for Music Blocks" +category: "DEVELOPER NEWS" +date: "2025-07-13" +slug: "2025-07-13-gsoc-25-omsuneri-week06" +author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" +tags: "gsoc25,sugarlabs,week06,Debugger,AI,Music Blocks,GSoC Midterm" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 06 Progress Report by Om Santosh Suneri + +**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) +**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) +**Reporting Period:** 2025-07-06 - 2025-07-12 + +--- + +## Goal for This Week + +**Build a tightly integrated debugging experience by embedding the JSON-to-Text converter into the main debugger Streamlit app and enabling users to export complete chat logs with the AI assistant** + +--- + +## This Week’s Achievements + +### Introduction + +This week’s focus was two-fold: + +1. **Merge and integrate** the Music Blocks JSON-to-Text converter directly into the existing Streamlit-based debugger UI. +2. **Enhance user experience** by introducing a "Chat Export" feature that allows users to download their complete AI-debugger conversation history in \`.txt\` format. + +These updates mark a major usability milestone and make the debugging experience smoother and more developer-friendly. + +### What I Did + +#### 1. Embedded JSON-to-Text Converter in the Debugger Workflow + +Previously, users had to first convert their Music Blocks JSON into readable text using a separate converter app and then copy that result into the debugger interface. This extra step caused friction in the user flow. + +Now, I’ve **fully integrated the \`convert_music_blocks()\` function** (from our \`json_parser.py\` module) directly into the debugger pipeline. Here’s how it works: + +* A user pastes raw Music Blocks JSON code into a text area inside the main debugger app. +* Upon clicking **"🚀 Launch My Music Blocks Project!"**, the code is parsed using \`json.loads()\` and fed into the \`convert_music_blocks()\` function. +* This recursive function translates the block structure into a clean, readable text representation using a tree-like format (\`├──\`, \`│\`, etc.), supporting clamp/stack logic and deeply nested project structures. +* The converted code is **stored in \`st.session_state.project_code\`** and becomes the foundational context for the entire debugging session. + +**Key Enhancements**: + +* Handles more block types like \`arc\`, \`incrementOne\`, \`pitch\`, and \`settransposition\`. +* Automatically redacts base64-encoded data like audio/image blobs by replacing them with \`"data"\` in output. +* Maintains formatting consistency to assist LLM comprehension and improve semantic chunk retrieval. + +--- + +#### 2. Chat Export Functionality + +To support documentation, sharing, and revisiting past sessions, I implemented a **chat export button**. The feature is context-aware and only appears when the user has interacted with the debugger. + +**Implementation Details**: + +* On each AI-user interaction, chat messages are appended to \`st.session_state.chat_history\` as a list of message dictionaries (\`{"role": ..., "content": ...}\`). +* The \`generate_chat_export()\` function: + + * Adds a timestamp using Python’s \`datetime.now()\`. + * Includes both the original converted project code and the full chat history. + * Formats everything into plain text. +* The Streamlit \`st.download_button()\` is used to render the export option, generating a downloadable \`.txt\` file named like \`music_blocks_chat_20250711_143512.txt\`. + +This makes the tool much more practical for teachers or learners who want to **archive** AI insights, share results, or continue the session later. + +--- + +### Why These Features Matter + +**Improved UX**: +With the converter now inside the debugger, users no longer need to juggle multiple tools. They can paste once, click once, and begin debugging immediately. + +**Smarter Debugging**: +The LLM uses the converted project code + relevant chunks from Music Blocks documentation (via \`retrieve_relevant_chunks()\`) to generate highly contextual, beginner-friendly replies. + +**Educational Value**: +Students and educators can **save their interactions**, review solutions offline, or submit chat logs for peer or mentor feedback. + +--- + +### Preview Features + +<a href=""><img src="https://i.ibb.co/FbHymBYN/Screenshot-2025-07-11-at-2-16-30-PM.png" alt="Music Blocks Debugger"></a> + +* 🔁 One-click conversion of Music Blocks JSON to structured text. +* 💬 Chat-driven debugging using Music Blocks Bot + documentation chunks. +* 💾 "Export Chat" button for persistent chat history. +* 🧽 "Clear Chat" button to reset sessions easily. + +--- + +## Midterm Evaluation Summary (Weeks 01–06) + +The first six weeks of GSoC 2025 have been focused on architecting and implementing the core systems behind the **AI-powered Debugger for Music Blocks**. From block parsing and embedding generation to LLM integration and full-stack deployment, the project has steadily evolved into a functional, AI-assisted debugging tool optimized for kids and educators. + +--- + +### Key Technical Achievements + +* **JSON-to-Text Parser**: Migrated the logic-heavy JavaScript converter to Python, maintaining tree-structured formatting (\`├──\`, \`│\`) and supporting recursion for nested Music Blocks projects. This makes visual projects readable and interpretable as text. + +* **Streamlit Interface**: Built a clean, user-friendly UI that enables users to paste JSON, parse it live, and interact with the AI debugger—all in one app. Integrated Gemini for generating responses tailored to kids. + +* **Vector Search with Qdrant**: Generated semantic embeddings from 14 curated Music Blocks projects and stored them in a Qdrant vector DB. This enables chunk retrieval from documentation and real examples to enhance LLM understanding. + +* **RAG Pipeline**: Combined user input + parsed project code + vector context to construct dynamic prompts for the LLM. Prompt behavior adapts based on session length to balance discovery and solution guidance. + +* **Export + UX Enhancements**: Added \`.txt\` chat export, refined session state handling, and introduced autoscroll + dynamic prompt control for a polished user experience. + +--- + +### Why It Matters + +By allowing users to paste a Music Blocks JSON file and instantly receive both a clean text summary and interactive feedback from an AI assistant, the tool reduces the barrier to debugging and learning. It helps students understand project flow, educators explain logic, and kids explore possibilities in a guided, friendly way. + +--- + +### Final Thoughts + +Over the past six weeks, I’ve transitioned from building isolated components to integrating them into a cohesive, interactive debugger. This week’s merge of the JSON converter into the main app simplified the workflow and enabled richer, context-aware prompts for the LLM. + +Technically, it deepened my understanding of state management, error handling, and modular design. Functions like convert_music_blocks() and retrieve_relevant_chunks() proved invaluable for maintaining clean, scalable code. The debugger is now not just functional — it’s ready to be embedded, deployed, and used meaningfully by kids and educators alike. + +--- + +### Next Week’s Roadmap + +* **Deploy the app to Sugar Labs’ AWS server** for long-term availability and community usage. +* **Develop a Music Blocks Widget** to embed the debugger directly into the Music Blocks environment for seamless integration and real-time support. + +--- + +## Resources & References + +- **Repository:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) +- **Debugger Streamlit App:** [Music Blocks Debugger](https://debuggmb.streamlit.app/) +- **Directory for Projects:** [Embedding Project Set](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks/tree/main/data/docs) + +--- + +### Acknowledgments + +Thanks to my mentors Walter Bender for the consistent feedback and support, and to Devin Ulibarri for assisting with insights into Music Blocks educational usage. The Sugar Labs community continue to be an invaluable support system. + +--- +`,Ei=Object.freeze(Object.defineProperty({__proto__:null,default:it},Symbol.toStringTag,{value:"Module"})),rt=`--- +title: "DMP ’25 Week 06 Update by Harshit Verma" +excerpt: "I added a new step to help students understand their code’s intent before debugging begins. I also worked on improving the terminal’s formatting and finalized Mistral 7B as the debugging model to be integrated with Sugar AI" +category: "DEVELOPER NEWS" +date: "2025-07-14" +slug: "2025-07-14-dmp-25-therealharshit-week06" +author: "@/constants/MarkdownFiles/authors/harshit-verma.md" +tags: "dmp25,sugarlabs,week06,midterm,therealharshit" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 06 Progress Report by Harshit Verma + +**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-07-07 - 2025-07-13 + +--- + +## Goals for This Week + +- **Goal 1:** Work on contextualization before debugging. +- **Goal 2:** Add CSS-style formatting to the debugging terminal. +- **Goal 3:** Finalize model decision for debugging. + +--- + +## This Week’s Achievements + +1. **Implemented Code Context Display for Learners** + - As discussed in the debugging meeting, added a step that shows the context or purpose of the code to the student, helping them understand what the code is trying to do before showing debug suggestions. + - This helps children first grasp what the code is meant to do, which builds confidence and improves the effectiveness of the debugging tips that follow. + - Introduced a new step in the debugging flow: before showing any suggestions, the interface displays a brief summary of the code’s intent or functionality. + +2. **Worked on Debug Terminal Formatting** + - Tried to apply CSS-like styles to make debug output more structured and visually appealing. + - GTK limitations posed challenges, continued work on enhancing the Markdown parser instead. + +3. **Finalize model decision for debugging** + - Decided to use **Mistral 7B**, which will be integrated with Sugar AI for better compatibility and performance. + - Based on performance tests and Sugar AI's deployment pipeline, It offers a good balance of output quality and resource efficiency for server-side use. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Styling Virtual Terminal Emulator (VTE) output with CSS. + **Solution:** Learned that we can't apply CSS to the VTE terminal output as they are not GTK widget, so I decided to work on further improving the markdown parser. + +--- + +## Key Learnings + +- Learned how code contextualization can help beginner coders by giving them an idea of what the code should do, and it also improves their ability to understand and fix problems. +- Developed a design-focused mindset for user-centric debugging tools. + +--- + +## Next Week’s Roadmap + +- Start working on replacing pippy-debugger-server with sugar-ai. +- Start working on saving debug history to Sugar Journal. +- Work on preparing a presentation as part of DMP midterm evaluation. + +--- + +# Midterm Progress Report (6 Week Summary) + +## Project Objective + +The goal of this project is to enhance the Pippy learning environment by integrating an LLM-powered debugger. The debugger uses LLMs to provide readable, friendly suggestions for fixing broken code, helping young learners understand and improve their programs. + +--- + +## Technical Implementation + +- Set up a **FastAPI backend** (\`/debug\`) to handle Python code input. + +- Integrated **Hugging Face model** for generating debugging tips. + +- Created **Run & Debug** buttons in Pippy’s GTK interface. + +- Connected **Pippy** with the backend server via API. + +- Implemented a **Debug terminal** in the UI to display suggestions. + +- Developed a **basic Markdown parser** for formatted output in VTE. + +- Added a **Contextualization step** to show students what the code intends to do before debugging begins. + +--- + +## Research & Design + +- Explored multiple **UI layouts** for debug output. + +- Tested different **LLM prompts** for clarity and simplicity. + +- Held discussions on **Debugging best practices for children**. + +- Evaluated models and selected **Mistral 7B** for deployment via Sugar AI. + +--- + +## Project Demo + +Please watch the project demo to see the progress I've made so far. +[Watch here](https://drive.google.com/file/d/1-FHfsd0YiOZ2Fb7V7HeSswcga89jEvos/view?usp=drive_link) + +--- + +## Resources & References + +**Repository** +- [Pippy](https://github.com/therealharshit/Pippy/tree/DMP2025/Pippy-Debugger) +- [sugar-ai](https://github.com/sugarlabs/sugar-ai) +- [pippy-debugger-server](https://github.com/therealharshit/pippy-debugger-server) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! + +--- +`,Di=Object.freeze(Object.defineProperty({__proto__:null,default:rt},Symbol.toStringTag,{value:"Module"})),st=`--- +title: "GSoC ’25 Week 06 Update by Bishoy Wadea" +excerpt: "Mid term evaluation reflection" +category: "DEVELOPER NEWS" +date: "2025-07-13" +slug: "gsoc-25-BishoyWadea-week06" +author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" +tags: "gsoc25,sugarlabs,week06,midterm,BishoyWadea" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 06 Progress Report by Bishoy Wadea + +**Project:** [Euclid’s Game](https://github.com/Bishoywadea/Euclid-s-Game) +**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) +**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) +**Reporting Period:** 2025-06-07 - 2025-07-14 + +--- + +## Goals for This Week + +- **Goal 1:** Start implementing Euclid’s Game +--- + +## This Week’s Achievements + +### *Goal 1: add helpful video tutorial in Soma Cube Game* + +1. **add video in help button** + - commit: [modify code to handle help videos](https://github.com/Bishoywadea/Soma-Cube/commit/63a7daaa8009f5f54791cdf9081e765846135f70) + +Soma Cube as Sugar activity [youtube: Q4BKp3Yo3Uw] + +--- + +### *Goal 2: Start implementing Euclid’s Game* + +**description of the game:** +The game inspired by Euclid’s game is a two-player mathematical strategy game +that illustrates the principles of the Euclidean algorithm, particularly in finding the +greatest common divisor (GCD) of two numbers. The game begins with two unequal +positive integers written on a board. Players alternate turns, and on each turn, a +player writes a new number on the board, which is the positive difference of any two +numbers already present. The new number must be distinct from all numbers +previously written. The game continues until a player cannot make a valid move; this +player loses the game. + +**Menu Light Theme:** + +This shows the main menu screen of Euclid’s Game in light mode. You can see the toolbar at the top with buttons like New Game and Help, along with options to switch between light and dark themes. Below that, there are buttons for selecting difficulty levels and choosing game modes, such as 2‑player or vs AI. + + + +**Menu Dark Theme:** + +This shows the main menu screen of Euclid’s Game in Dark theme + + + +**Gameplay Dark Theme:** + +Here you’re looking at the core game screen in dark mode. There's a board displaying numbers—the starting pair and any differences added. You can also see the current player’s turn and the move counter. + + + +**Gameplay Dark Theme:** + + + +**Gameplay Light Theme** + +This is the same gameplay view but in light theme. + +**Help Panel** + +This overlay provides instructions or guidance on how to play the game. It likely appears when you click the “Help” button from the toolbar, offering context and tips for first-time users. + + +--- + +## Challenges & Solutions + +- **Challenge:** Creating a responsive and user-friendly . + **Solution:** Implemented smooth game play logic to ensure accuracy and a satisfying user experience. +--- + +## Midterm Evaluation Reflection + +As I reach the halfway point of my GSoC journey, I’ve had the chance to reflect on the past six weeks—both the technical milestones and personal growth that came with them. + +### Progress So Far +Over the first phase of GSoC, I successfully developed and shipped five fully functional Sugar activities: +- [**Four Color Map Puzzle**](https://github.com/Bishoywadea/Four-Color-Map) – Core gameplay, UI enhancements, region data integration. +- [**Broken Calculator**](https://github.com/Bishoywadea/Broken-Calculator) – Restrictive math puzzle with scoring, themes, and child-friendly UX. +- [**Soma Cube**](https://github.com/Bishoywadea/Soma-Cube) – A 3D spatial reasoning puzzle featuring piece manipulation, textures, collision, and video tutorials. +- [**Fifteen Puzzle**](https://github.com/Bishoywadea/FifteenPuzzle) – Classic sliding puzzle with smooth animations and responsive layout. +- [**Euclid’s Game**](https://github.com/Bishoywadea/Euclid-s-Game) – Strategic math game with theme switching, help overlays, and polished UI. + + +Each activity was built from scratch or significantly improved, covering diverse gameplay styles—from logic puzzles to real-time spatial challenges—all designed with **educational value and child accessibility** in mind. + +### What I’ve Learned +- **Technical Mastery:** Strengthened my experience with **Pygame**, **Three.js**, and **GTK**, along with concepts like game loops, animation, and real-time input handling. +- **UI/UX Design:** Built interfaces tailored for young learners, focusing on clarity, feedback, and accessibility. +- **Open Source Discipline:** Embraced good development practices—clean commits, documentation, issue tracking, and community feedback cycles. + +### cknowledgments +This progress would not have been possible without the patient guidance of my mentors, Ibiam. Their feedback has helped me think more deeply about software design, education, and the impact of simplicity. The Sugar Labs community’s encouragement has also been motivating and insightful. + + +--- + +## Next Week’s Roadmap + +- Fix any feedback provided by members of the organization. +- Start implementing the Magic moving game. +--- +`,ji=Object.freeze(Object.defineProperty({__proto__:null,default:st},Symbol.toStringTag,{value:"Module"})),lt=`--- +title: "GSoC ’25 Week 09 Update by Aditya Kumar Singh and Midterm Summary" +excerpt: "Enhanced collaboration in Human Body activity by refining Paint and Tour interactions, improved UX in Doctor mode, and launched key features in Stickman like frame handling and animation controls." +category: "DEVELOPER NEWS" +date: "2025-07-15" +slug: "2025-07-15-gsoc-25-AdityaKrSingh26-week09" +author: "@/constants/MarkdownFiles/authors/aditya-singh.md" +tags: "gsoc25,sugarlabs,week09,AdityaKrSingh26,midterm" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 09 Progress Report by Aditya Kumar Singh and Midterm Summary + +**Project:** [Sugarizer](https://github.com/llaske/sugarizer) +**Mentors:** [Lionel Laské](https://github.com/llaske) +**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) +**Reporting Period:** 2025-07-10 – 2025-07-16 + +--- + +## Goals for This Week + +- **Goal 1:** Fix key UX and sync issues in the Human Body activity for Paint and Tour modes. +- **Goal 2:** Improve interactivity and usability in Doctor mode. +- **Goal 3:** Add shared leaderboard functionality for Doctor participants. +- **Goal 4:** Begin dashboard and animation logic in Stickman activity. + +--- + +## This Week’s Achievements + +1. **Human Body Paint & Tour Interaction Fixes** + - **Issue:** When switching from Tour to Paint, highlighted parts remained visually active across users. + - **Fix:** Restored original mesh material on mode switch using \`restoreMeshColor()\` and synced the update with a new \`restoreMaterials\` action. + - **Issue:** Unnecessary part-name popup showed for everyone when anyone painted. + - **Fix:** Restricted the popup to only the user who performed the action, enhancing clarity in shared sessions. + - **Issue:** Doctor mode lacked reminders of the current target part after failed guesses. + - **Fix:** Implemented a reminder popup after every 3 failed attempts to display: \`"Remind you, we're looking for [Part Name]"\`. + \`\`\`javascript + // restore material + if (msg.action = = "modeChange") { + if (msg.content != 0) return; + if (currentModel) { + currentModel.traverse((node) => { + if (node.isMesh && node.userData.originalMaterial) { + node.material = node.userData.originalMaterial.clone(); + } + }); + } + } + // Reminder popup + if (failedAttempts % 3 === 0 && failedAttempts > 0) { + showModal("Remind you, we're looking for " + l10n.get(bodyParts[presenceCorrectIndex].name)); + } + \`\`\` + - Links : PR [#1800](https://github.com/llaske/sugarizer/pull/1800) + > Failed Attempt Popup +  + + +2. **Shared Doctor Mode Leaderboard Enhancements** + - Reworked the leaderboard to show users with the **highest score on top** in real-time. + - Implemented logic to sort and re-render the leaderboard HTML dynamically after each answer. + - Ensured that scores are updated and synchronized across all participants using the \`scoreUpdate\` action. + \`\`\`javascript + playerScores.sort((a, b) => b[1] - a[1]); + \`\`\` + - XO icons rendered dynamically using user colors: + \`\`\`javascript + iconElement.style.backgroundImage = \`url(\${generateXOLogoWithColor(playerColor)})\`; + \`\`\` + > Real-time XO Leaderboard during Shared Doctor Mode +  + + +3. **Stickman Activity – Dashboard Features Bootstrap** + - **Launched key drawing infrastructure**: + - Users can now **create stickman**, **drag**, and **move** the whole figure. + - Proper **distance constraints** between joints maintain anatomical correctness. + - Integrated real-time canvas rendering loop to support: + - Drawing joint previews. + - Added mouse interaction listeners to support **joint selection and dragging**. + + +4. **Stickman Frame Handling + Animation Tools** + - Added **Add Frame**, **Preview Frame**, and **Remove Frame** options via UI. + - Integrated **Play / Pause** logic controlled via speed slider (\`speedpalette.js\`) to control animation playback. + - Introduced **Onion Skinning**—each frame preview shows a translucent version of adjacent frames for better motion consistency. + - Enabled **Template Palette** with selectable pre-built poses (run, dance). + - **Export as Video** and playback scaffold in progress using HTML5 Canvas. + - Links : PR [#1799](https://github.com/llaske/sugarizer/pull/1799) + > Stickman Dashboard UI with Toolbar and Timeline +  + + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Popup messages overloaded users in shared mode. + **Solution:** Added \`networkId\` checks to restrict popup visibility only to the sender. + +--- + +## Key Learnings + +- Gained deeper understanding of **presence synchronization patterns** in collaborative activities. +- Learned best practices for **frame-by-frame animation** and **canvas optimization**. +- Improved on creating **real-time UI updates** and dynamic SVG rendering using data-driven design. + +--- + +## Midterm Summary + +Over the past nine weeks, my journey with Sugar Labs through GSoC has been incredibly rewarding, both technically and personally. Here's a quick recap of my key milestones: + +- **Weeks 01–03:** I dove deep into the world of 3D anatomy, cleaning and merging segmented organ models, improving mesh clarity, and laying the foundation for the interactive Paint Mode in the Human Body activity. +- **Weeks 04–05:** I introduced internationalization with \`i18next.js\`, created a palette system to switch between anatomical models, and improved educational clarity through accurate labeling and skeletal refactoring. +- **Week 06:** I implemented onboarding tutorials, optimized models for performance, and started building shared logic for collaborative Paint Mode. +- **Weeks 07–08:** I built synchronization features for Tour and Doctor modes, including real-time scoring, shared camera states, and adaptive mesh highlighting. I also bootstrapped the new Stickman activity with animation tools and scaffolding. +- **Week 09 (this week):** I improved user experience by fixing shared mode bugs, added a real-time XO leaderboard in Doctor mode, and implemented critical frame-based animation controls like onion skinning and play/pause for Stickman. + +Throughout this phase, I’ve gained: + +- A much deeper understanding of **Three.js**, especially around camera controls, mesh interactions, and rendering pipelines. +- Hands-on experience in designing **real-time collaborative environments**, ensuring consistent state across clients. +- Confidence in writing **modular, scalable JavaScript**, integrating localization, and building UI that’s both intuitive and accessible. +- Awareness of **educational UX design**, where clarity and simplicity matter just as much as functionality. + + +I’m sincerely **grateful to my mentors** Lionel and Samarth for their patient guidance, critical feedback, and unwavering support. I’ve also grown by engaging with the Sugar Labs community, learning from discussions, and reading others’ code. + +This journey so far has not only improved my technical depth but also taught me how to think like an open-source contributor—collaborative, responsible, and focused on impact. I'm excited for the second half of GSoC and all the challenges and learning it will bring. + +Thank you again to everyone who's been part of this experience so far! + +## Next Week’s Roadmap + +- Fix remaining issue on Human Body +- Fix issues on dashboard and frame for Stickman activity +- Handle the adding a new stickman feature +- Handle Journal storage for stickman activity + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +`,Wi=Object.freeze(Object.defineProperty({__proto__:null,default:lt},Symbol.toStringTag,{value:"Module"})),dt=`--- +title: "GSoC '25 Week 7 Update by Elwin Li" +excerpt: "MusicBlocks generation model" +category: "DEVELOPER NEWS" +date: "2025-07-19" +slug: "2025-07-19-gsoc-25-Elwin-Li-week07" +author: "@/constants/MarkdownFiles/authors/elwin-li.md" +tags: "gsoc25,sugarlabs,week7,javaScript editor,debugger,syntax highlighting" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 7 Progress Report by Elwin Li + +**Project:** MusicBlocks Generation Model + +**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) + +**Reporting Period:** 2025-07-12 - 2025-07-19 + +--- + +## Goals for This Week + +- **Goal:** Work on obtaining a dataset for MusicBlocks generation model + +--- + +## This Week’s Achievements + +Before diving into the technical work, I want to share some context on the direction of my project. Last week, I experimented with a prompt-engineered Gemini API call to generate MusicBlocks code from natural language prompts. However, I found that this approach did not work well for examples more complex than simple nursery rhymes. As a result, I decided to explore the possibility of fine-tuning a model specifically for MusicBlocks code generation. + +I spent a significant amount of time this week learning about the process of fine-tuning large language models. Through this research, I discovered that a high-quality dataset is essential for effective fine-tuning. This realization shaped the rest of my week's work, as I shifted my focus toward obtaining and preparing such a dataset. + +This week, I mainly focused on gathering data for the MusicBlocks generation model. I used the example projects in the examples folder as my data source. Since these projects were in blocklist format, I needed to find a way to convert all of them to JavaScript code. + +To accomplish this, I developed a widget that can load projects directly from the examples folder, generate the corresponding JavaScript code, and download it. This streamlined the process of extracting code from a large number of example projects. + +<a href="https://ibb.co/7NTw72yd"><img src="https://i.ibb.co/HpMWmngf/Screenshot-2025-07-20-at-1-04-37-AM.png" alt="Examples Loader Widget"></a> + + +However, I found that only about half of the projects could be successfully converted to JavaScript. Many of the example projects contained blocks that are not currently supported for block-to-code conversion, which limited the amount of usable data I could extract for the model. + +After completing these achievements, I realized that since I didn't have much data available, fine-tuning might not be the most effective approach. Instead, I decided to shift my focus towards Retrieval-Augmented Generation (RAG) as an alternative. I have now started learning about the RAG process and how it could be applied to the MusicBlocks generation task. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** The Gemini API prompt engineering approach only worked for very simple examples and failed on more complex MusicBlocks projects. + + **Solution:** Decided to explore fine-tuning a model for MusicBlocks code generation, which required learning about the fine-tuning process and dataset requirements. + +- **Challenge:** Many example projects could not be converted from blocklist to JavaScript due to unsupported blocks in the block-to-code conversion process. + + **Solution:** Built a widget to automate the conversion and identify which projects could be used, maximizing the amount of usable data. + +- **Challenge:** Realized that the available dataset was too small for effective fine-tuning. + + **Solution:** Shifted focus to learning about Retrieval-Augmented Generation (RAG) as an alternative approach. + +--- + +## Key Learnings + +- Gained hands-on experience with prompt engineering for LLMs and its limitations for domain-specific code generation. +- Learned about the requirements and process for fine-tuning large language models, including the importance of dataset size and quality. +- Improved skills in automating data extraction and conversion workflows using custom widgets. +- Discovered the potential of Retrieval-Augmented Generation (RAG) as a practical alternative to fine-tuning when data is limited. + +--- + +## Next Week’s Roadmap + +- Continue learning about and experimenting with Retrieval-Augmented Generation (RAG) for MusicBlocks code generation. +- Investigate tools and frameworks for implementing RAG in the context of MusicBlocks. +- Explore ways to further expand or enhance the dataset, if possible. +- Begin prototyping a basic RAG pipeline using the data collected so far. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- `,Oi=Object.freeze(Object.defineProperty({__proto__:null,default:dt},Symbol.toStringTag,{value:"Module"})),ct=`--- +title: "GSoC ’25 Week 10 Update by Aditya Kumar Singh" +excerpt: "Improved UX and syncing in Human Body activity, enhanced Stickman dashboard visuals, redesigned proportions, and implemented Journal save & multi-stickman support." +category: "DEVELOPER NEWS" +date: "2025-07-20" +slug: "2025-07-20-gsoc-25-AdityaKrSingh26-week010" +author: "@/constants/MarkdownFiles/authors/aditya-singh.md" +tags: "gsoc25,sugarlabs,week10,AdityaKrSingh26" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 10 Progress Report by Aditya Kumar Singh and Midterm Summary + +**Project:** [Sugarizer](https://github.com/llaske/sugarizer) +**Mentors:** [Lionel Laské](https://github.com/llaske) +**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) +**Reporting Period:** 2025-07-16 - 2025-07-23 + +--- + +## Goals for This Week + +- **Goal 1:** Improve Human Body UX (Tour/Doctor mode randomization, camera reset, leaderboard toggle). +- **Goal 2:** Polish Stickman activity dashboard and frame preview behavior. +- **Goal 3:** Improve stickman appearance and proportions. +- **Goal 4:** Enable multi-stickman support and journal storage. + +--- + +## This Week’s Achievements + +1. **Random Part Selection in Doctor/Tour Modes** + - Ensured every new session randomly selects a body part to focus on. + - The selection is now host-driven and synced to all participants. + \`\`\`javascript + function selectRandomPartForDoctor() { + presenceCorrectIndex = Math.floor(Math.random() * bodyParts.length); + document.dispatchEvent(new CustomEvent("target-updated", { + detail: { part: presenceCorrectIndex } + })); + } + \`\`\` + + +2. **Camera Reset and Leaderboard Cleanup on Exit** + - Fixed host → client camera sync when exiting Tour mode. + - Leaderboard UI now clears correctly when Doctor mode ends. + \`\`\`javascript + function resetTourState() { + if (!window.isHost) { + camera.position.set(defaultX, defaultY, defaultZ); + controls.target.set(0, 1, 0); + controls.update(); + } + hideLeaderboard(); + } + \`\`\` + + +3. **Frame Preview Enhancement in Stickman Activity** + - Previously, users had to add a new frame for the thumbnail preview to refresh. + - Now, any movement or change in the canvas auto-updates the preview. + - **Approach:** + - Detect changes in the canvas (e.g., drag end or part movement). + - Clone the updated canvas to the current frame’s preview. + - This ensures instant visual feedback while animating. + + +4. **Stickman Design Overhaul** + - Revisited the drawing logic and proportions: + - Shorter neck + - Thicker limbs + - Solid, filled circular head + - Inspired by Pivot Animator to offer a more professional, relatable look. + > Updated Stickman Design +  + + +5. **Multi-Stickman Canvas Support** + - Users can now add more than one stickman in the scene. + - Each stickman is an isolated object with its own: + - Position and joint data + - Frame history + - Selectable state + - **Algorithm:** + - Maintain a list of stickman instances. + - On user interaction, determine which stickman is targeted. + - Only that stickman responds to move, draw, and animate actions. + > Multiple Stickman preview in acitvity +  + + +6. **Journal Integration for Stickman** + - Implemented save/load logic to persist stickman data (frames, templates, active character). + - **Approach:** + - On save: Serialize all current stickmen, their frame sequences, and selected templates into a JSON blob. + - On load: Deserialize and reconstruct all visual data, restoring the full session. + - This allows users to save their progress and resume where they left. + + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Preventing multiple stickmen from interfering with each other’s states. + **Solution:** Scoped interaction events to only apply to the selected stickman instance. + +- **Challenge:** Updating previews without triggering unnecessary rendering overhead. + **Solution:** Triggered preview redraws only on meaningful events like drag-end or transformation complete. + +--- + +## Key Learnings + +- Learned how to architect multi-actor systems on a single canvas while maintaining performance. +- Strengthened my understanding of event-driven synchronization in real-time collaborative applications. + +--- + +## Next Week’s Roadmap + +- Fix remaining issue on Human Body +- Increase the size of Stickman +- Show frames only for selected stickman for multiple stickman +- Show joints only for selected stickman for multiple stickman +- Add popup when removing stickman with frames count >1 + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +`,Bi=Object.freeze(Object.defineProperty({__proto__:null,default:ct},Symbol.toStringTag,{value:"Module"})),ut=`--- +title: "GSoC ’25 Week 07 Update by Diwangshu Kakoty" +excerpt: "Reflection Learning Widget in Music Blocks" +category: "DEVELOPER NEWS" +date: "2025-07-20" +slug: "2025-07-20-gsoc-25-diwangshu-week07" +author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" +tags: "gsoc25,sugarlabs,week06,AI" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week 07 Progress Report by Diwangshu Kakoty + +**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) +**Reporting Period:** 2025-07-14 - 2025-07-19 + +--- + +## Goals for This Week + +- **Goal 1:** Implement periodic summary generation. +- **Goal 2:** Upgrading the 'reflection' widget. +- **Goal 3:** Fix bugs occured by these changes. + +--- + +## This Week’s Achievements + +1. **Implement periodic summary generation** + - As mentioned in the previous blog, I’ve now implemented periodic summary generation. Currently, it uses a straightforward prompt that requests a summary after every five bot messages. While this is a simple and somewhat detailed approach, it’s still basic and may not consistently produce accurate results. I’m in the process of testing it. + + - If it proves unreliable, I’ll switch to invoking the LLM with a dedicated prompt template after every five bot messages. This will ensure a structured and consistent summary each time. + +2. **Upgrading the 'reflection' widget** + + - The widget now allows users to interact with all available AI mentors directly within the interface. When a user initiates a conversation, their project code is automatically sent to the server, enabling mentors to provide more context-aware guidance and feedback. For this I developed a '/code' endpoint. This is the flow: + + - Music Blocks sends the project code to the server as a POST request in JSON format. + + - The server processes this data by running a conversion module and then calls the reasoning LLM to generate the corresponding algorithm. + + - It then responds with both the flowchart and the algorithm. + + - The client is responsible for storing this information and including it in requests sent to the /chat endpoint. + + + - I have also enhanced the save functionality. Users can now choose to save their entire conversation history at any point. In addition, the system automatically stores generated summaries and analytical insights, ensuring that important information and progress are preserved for future reference. + +--- + +## Challenges & How I Overcame Them + +- **Challenge :** I faced a minor challenge while implementing the periodic summary. My approach is to start simple and build up as needed, so I initially relied on prompting. However, the LLM wasn’t following the instruction. After some brainstorming, I realized that other instructions like 'Limit your response to 30 words' might have been conflicting with it + + **Solution :** I modified the conflicting prompts and experimented with few-shot prompting, which resolved the issue. +--- + +## Key Learnings + +- Adjusting or refining conflicting prompts, combined with the use of few-shot prompting, can significantly improve an LLM’s output. This highlights the importance of prompt engineering in guiding model behavior and achieving desired results. +--- + +## Next Week’s Roadmap + +- I need to finish building the widget to store user data, such as messages, summaries, and analysis reports using IndexedDB. +- Once that’s completed, I’ll move on to the 'analysis generation' phase. + +--- + +## Resources & References + +- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) +- **Streamlit App:** [Reflection App](https://reflectionapp-2yoxtvn6sknvktme2zorvq.streamlit.app/) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +---`,Ri=Object.freeze(Object.defineProperty({__proto__:null,default:ut},Symbol.toStringTag,{value:"Module"})),ht=`--- +title: "DMP ’25 Week 07 Update by Harshit Verma" +excerpt: "Presented my work on Pippy Debugger to mentors and also started working on developing API endpoint in Sugar-AI." +category: "DEVELOPER NEWS" +date: "2025-07-21" +slug: "2025-07-21-dmp-25-therealharshit-week07" +author: "@/constants/MarkdownFiles/authors/harshit-verma.md" +tags: "dmp25,sugarlabs,week07,therealharshit" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 07 Progress Report by Harshit Verma + +**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) +**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-07-14 - 2025-07-20 + +--- + +## Goals for This Week + +- **Goal 1:** Prepare a presentation for the DMP Midterm Evaluation. +- **Goal 2:** Start working on the \`/debug\` endpoint in Sugar-AI. + +--- + +## This Week’s Achievements + +1. **Prepared a presentation for the DMP Midterm Evaluation.** + - I prepared a comprehensive presentation to showcase the progress of the **Pippy Debugger** at the DMP midterm review. The presentation covered everything from project objectives and methods to current results, challenges, and future plans. + - Additionaly, I also gave a mock presentation of my work to the Sugar Labs mentors. + - [DMP Midterm Presentation](https://docs.google.com/presentation/d/13bAMCpKi6ezlhBEQ7NGR7eszumwpYZnL8dGFLNlnBF8/edit?usp=sharing) + +2. **Started working on developing API endpoint in Sugar-AI** + - Began development of a new \`/debug\` endpoint in Sugar-AI. This endpoint will handle code input and return structured debug suggestions from the LLM. + - I have also started the process of integrating Sugar-AI with Pippy. + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Understaing Sugar-AI’s existing API structure. + **Solution:** I followed the documentaion and my mentors guidance. + +--- + +## Key Learnings + +- How to design and deliver a structured presentation. +- Introduction to Sugar-AI’s internal API design and how to extend it. + +--- + +## Next Week’s Roadmap + +- Finalize the work of \`/debug\` endpoint in Sugar-AI. +- Work on making the LLM response more kids friendly. +- Start working on saving debug history to Sugar Journal. + +--- + +## Resources & References + +**Repository** +- [Pippy](https://github.com/therealharshit/Pippy/tree/DMP2025/Pippy-Debugger) +- [sugar-ai](https://github.com/sugarlabs/sugar-ai) +- [pippy-debugger-server](https://github.com/therealharshit/pippy-debugger-server) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! + +--- +`,zi=Object.freeze(Object.defineProperty({__proto__:null,default:ht},Symbol.toStringTag,{value:"Module"})),gt=`--- +title: "Comprehensive Markdown Syntax Guide" +excerpt: "A complete reference template showcasing all common markdown features and formatting options" +category: "TEMPLATE" +date: "2025-06-13" +slug: "markdown-guide" +author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" +tags: "markdown,reference,guide,syntax,documentation,template" +image: "https://images.unsplash.com/photo-1506744038136-46273834b3fb?w=2070" +--- +<!-- markdownlint-disable --> + +# Comprehensive Markdown Syntax Guide + +This document serves as a complete reference for markdown syntax, demonstrating various formatting elements and features supported by our enhanced markdown parser with GitHub-style rendering. + +## Headings + +# Heading Level 1 +## Heading Level 2 +### Heading Level 3 +#### Heading Level 4 +##### Heading Level 5 +###### Heading Level 6 + +## Text Formatting + +**Bold text** or __also bold text__ + +*Italic text* or _also italic text_ + +***Bold and italic text*** or ___also bold and italic___ + +~~Strikethrough text~~ + +==Highlighted text with custom styling== + +Super^script^ text and Sub~script~ text + +Here's some \`inline code\` within a paragraph for demonstration. + +## Code Examples + +### Inline Code vs Code Blocks + +Single backticks for \`inline code highlighting\` like \`const variable = "value"\` or \`npm install\`. + +### Code Blocks with Language Support + +\`\`\`javascript +// JavaScript example with syntax highlighting +function calculateSum(a, b) { + return a + b; +} + +const result = calculateSum(5, 10); +console.log(\`The sum is: \${result}\`); +\`\`\` + +\`\`\`python +# Python example +def fibonacci(n): + if n <= 1: + return n + return fibonacci(n-1) + fibonacci(n-2) + +# Generate first 10 Fibonacci numbers +for i in range(10): + print(f"F({i}) = {fibonacci(i)}") +\`\`\` + +\`\`\`typescript +// TypeScript example +interface User { + id: number; + name: string; + email: string; +} + +const createUser = (userData: Partial<User>): User => { + return { + id: Date.now(), + name: userData.name || "Anonymous", + email: userData.email || "user@example.com" + }; +}; +\`\`\` + +\`\`\`css +/* CSS example */ +.markdown-content { + font-family: 'Inter', sans-serif; + line-height: 1.6; + color: #333; +} + +.code-block { + background: #f6f8fa; + border-radius: 6px; + padding: 16px; + overflow-x: auto; +} +\`\`\` + +\`\`\`bash +# Bash commands +git clone https://github.com/username/repo.git +cd repo +npm install +npm run dev +\`\`\` + +\`\`\`sql +-- SQL example +SELECT users.name, posts.title, posts.created_at +FROM users +JOIN posts ON users.id = posts.user_id +WHERE posts.published = true +ORDER BY posts.created_at DESC +LIMIT 10; +\`\`\` + +## Links and References + +### Basic Links +[Basic link to example.com](https://example.com) + +[Link with title](https://example.com "Example Website") + +### Auto-links +<https://example.com> + +<email@example.com> + +## Lists + +### Unordered Lists +- Item 1 +- Item 2 + - Nested Item 2.1 + - Nested Item 2.2 + - Deeply nested item +- Item 3 + +Alternative syntax: +* Item 1 +* Item 2 + * Nested item +* Item 3 + +### Ordered Lists +1. First item +2. Second item + 1. Nested item 2.1 + 2. Nested item 2.2 + 1. Deeply nested numbered item +3. Third item + +### Task Lists +- [x] Completed task +- [ ] Incomplete task +- [x] Another completed task +- [ ] Task with **bold text** +- [ ] Task with \`inline code\` + +### Definition Lists +First Term +: Definition of the first term + +Second Term +: Definition of the second term +: Another definition of the second term + +Complex Term +: This is a more complex definition that can include **bold text**, *italic text*, and \`inline code\`. + +## Images and Media + +### Basic Image + + +### Linked Image +[](https://example.com) + +### YouTube Video Embeds + +[youtube: MM-H69cHYMk] + +## Tables + +### Basic Table +| Header 1 | Header 2 | Header 3 | +|----------|:--------:|---------:| +| Default | Centered | Right | +| aligned | aligned | aligned | +| text | text | text | + +### Advanced Table with Formatting +| Command | Description | Example | +| --- | --- | --- | +| \`git status\` | List all new or modified files | Shows modified files in red | +| \`git diff\` | Show file differences not yet staged | \`git diff HEAD~1\` | +| \`git add .\` | Stage all changes | Adds all files to staging | +| \`git commit -m "message"\` | **Commit** with message | Creates new commit | + +### Feature Comparison Table +| Feature | Basic Plan | Pro Plan | Enterprise | +|---------|:----------:|:--------:|:----------:| +| Users | 5 | 25 | Unlimited | +| Storage | 10GB | 100GB | 1TB | +| Support | Email | Priority | 24/7 Phone | +| Price | $10/mo | $25/mo | Custom | + +## Blockquotes + +### Simple Blockquote +> This is a simple blockquote + +### Multi-paragraph Blockquote +> This is a blockquote with multiple paragraphs +> +> Second paragraph in the blockquote + +### Nested Blockquotes +> This is the first level of quoting. +> +> > This is nested blockquote. +> +> Back to the first level. + +### Complex Blockquote +> #### Blockquote with other elements +> +> - Lists inside blockquote +> - Another item with \`inline code\` +> +> **Bold text** inside blockquote with *italic* and \`code\`. +> +> \`\`\`javascript +> // Code block inside blockquote +> console.log("Hello from blockquote!"); +> \`\`\` + +## Horizontal Rules + +Three or more hyphens: + +--- + +Asterisks: + +*** + +Underscores: + +___ + +## GitHub-Style Alerts + +:::note +This is a note alert. Use it to provide additional information that's helpful but not critical. +::: + +:::tip Pro Tip +This is a tip alert. Great for sharing best practices and helpful suggestions! +::: + +:::important Important Notice +This is an important alert. Use it for information that users should definitely pay attention to. +::: + +:::warning Be Careful +This is a warning alert. Use it to highlight potential issues or things to watch out for. +::: + +:::caution Critical Warning +This is a caution alert. Use it for serious warnings about potential problems or security issues. +::: + +## Collapsible Sections + +### Basic Collapsible +:::details Click to expand basic details +This content is hidden by default and can be expanded by clicking the summary. + +You can include: +- **Formatted text** +- \`Code examples\` +- And other markdown elements + +\`\`\`javascript +console.log("Code works too!"); +\`\`\` +::: + +### Advanced Collapsible +:::details Advanced Configuration Options +Here are some advanced configuration options: + +#### Database Settings +- **Host**: localhost +- **Port**: 5432 +- **Database**: myapp_production + +#### Security Configuration +\`\`\`yaml +security: + encryption: AES-256 + hashing: bcrypt + session_timeout: 3600 +\`\`\` + +#### Performance Tuning +| Setting | Development | Production | +|---------|-------------|------------| +| Cache TTL | 60s | 3600s | +| Max Connections | 10 | 100 | +| Timeout | 30s | 10s | +::: + +<details> +<summary>HTML-style Collapsible Section</summary> + +This is using HTML details/summary tags. + +- You can include **formatted text** +- And other elements +- \`Code snippets\` + +\`\`\`python +def hello_world(): + print("Hello from collapsible section!") +\`\`\` + +</details> + +## Extended Features + +### Footnotes + +Here's a sentence with a footnote[^1]. + +Here's another footnote reference[^2]. + +Multiple footnotes in one sentence[^3][^4]. + +[^1]: This is the footnote content with **formatting**. +[^2]: This footnote contains \`code\` and *emphasis*. +[^3]: Short footnote. +[^4]: This is a longer footnote that can contain multiple sentences. It can even contain code blocks and other formatting elements. + +### Emoji Support + +#### Emotions and Reactions +:smile: I'm happy to see this working! +:heart: Love this feature! +:thumbsup: Looks good to me! +:thumbsdown: This needs work. +:eyes: I'm watching this. +:tada: Celebration time! + +#### Technical and Development +:rocket: Let's launch this feature! +:fire: This is awesome! +:star: Five-star quality! +:bug: There's a bug here. +:wrench: Fix needed. +:gear: Configuration required. +:sparkles: New feature! +:package: New release. +:zap: Performance improvement. +:boom: Breaking change. + +#### Communication and Status +:warning: Be careful with this syntax. +:info: Here's some information. +:check: This is correct! +:x: This is wrong. +:bulb: Great idea! +:memo: Take notes. +:link: Related link. +:lock: Secure content. +:unlock: Public content. + +#### Objects and Places +:computer: Development environment. +:phone: Mobile responsive. +:email: Contact information. +:calendar: Scheduled event. +:clock: Timing important. +:house: Home page. +:car: Fast delivery. +:plane: Deploy quickly. +:coffee: Developer fuel. +:pizza: Team lunch. + +### Deletions and Insertions + +~~This text has been deleted~~ and replaced with new content. + +<del>This is also deleted text</del> + +<ins>This text has been inserted</ins> + +## Advanced Formatting Combinations + +### Mixed Formatting Examples + +Here's text with **bold**, *italic*, \`code\`, ==highlighted==, ~~strikethrough~~, and [[Ctrl+A]] keyboard shortcut. + +> **Important Quote**: Use \`console.log()\` for debugging, but remember to ==remove it== before production. ~~Don't use alert().~~ :warning: + +| Feature | Status | Shortcut | Notes | +|---------|--------|----------|--------| +| **Bold** | :check: | [[Ctrl+B]] | Works everywhere | +| *Italic* | :check: | [[Ctrl+I]] | \`_text_\` also works | +| \`Code\` | :check: | [[Ctrl+\`]] | Inline highlighting | +| ==Highlight== | :check: | N/A | Custom feature | + +### Complex List with Everything + +1. **First Item** with \`code\` and [link](https://example.com) + - Nested item with ==highlighting== + - Another nested item with :rocket: emoji + - [ ] Unchecked task with ~~strikethrough~~ + - [x] Completed task with **bold text** + +2. **Second Item** with math: $E = mc^2$ + \`\`\`python + # Code block in list + def example(): + return "Hello World" + \`\`\` + +3. **Third Item** with blockquote: + > This is a quote inside a list item + > with **bold** and *italic* text + +## Accessibility Features + +### Screen Reader Friendly Content + +All images have descriptive alt text: + + +All links have descriptive text: +[Read the complete accessibility guidelines](https://example.com "Complete guide to web accessibility") + +### Semantic HTML Elements + +<details> +<summary>Semantic Structure Information</summary> + +Our markdown parser generates semantic HTML with: +- Proper heading hierarchy +- Accessible form controls +- ARIA labels where appropriate +- Focus management for interactive elements + +</details> + +--- + +### Final Thoughts + +This comprehensive markdown guide demonstrates the full capabilities of our enhanced parser. From basic formatting to advanced features like mathematical expressions and interactive elements, this parser provides a rich, GitHub-style experience. + +Thank you for reading this detailed markdown reference! :heart: :rocket: + +Remember to use the copy button on code blocks to quickly copy examples! :sparkles: + +--- + +*Last updated: 2025-06-13 | Version 2.0 | Contributors: Safwan Sayeed*`,Ui=Object.freeze(Object.defineProperty({__proto__:null,default:gt},Symbol.toStringTag,{value:"Module"})),mt=`--- +title: "GSoC ’25 Week XX Update by Safwan Sayeed" +excerpt: "This is a Template to write Blog Posts for weekly updates" +category: "TEMPLATE" +date: "2025-05-10" +slug: "YYYY-MM-DD-gsoc-25-sa-fw-an-weekXX" +author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" +tags: "gsoc25,sugarlabs,weekXX,sa-fw-an" +image: "assets/Images/GSOC.png" +--- + +<!-- markdownlint-disable --> + +# Week XX Progress Report by Safwan Sayeed + +**Project:** [Project Name](https://github.com/sugarlabs/www-v2) +**Mentors:** [Mentor1](https://github.com/Username), [Mentor2](https://github.com/Username) +**Assisting Mentors:** [Mentor3](https://github.com/Username), [Mentor4](https://github.com/Username) +**Reporting Period:** yyyy-mm-dd - yyyy-mm-dd + +--- + +## Goals for This Week + +- **Goal 1:** Describe the first planned deliverable. +- **Goal 2:** Describe the second planned deliverable. +- **Goal 3:** Describe an additional target. + +--- + +## This Week’s Achievements + +1. **[Task or Feature]** + - What you did and why it matters. + - Links (if any): PR [#123](https://github.com/owner/repo/pull/123), Issue [#456](https://github.com/owner/repo/issues/456). + +2. **[Task or Feature]** + - Brief summary or a video. + [youtube: MM-H69cHYMk] + +3. **[Task or Feature]** + - Add screenshots or diagrams here if useful: +  + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Describe a blocker or difficulty. + **Solution:** Outline your approach or resources used. + +- **Challenge:** Another issue faced. + **Solution:** Steps taken to resolve or next action plan. + +--- + +## Key Learnings + +- Gained familiarity with **XYZ library or tool**. +- Deepened understanding of **SOLID principles**, **architecture modeling**, **DFDs**, etc. +- Improved skills in **testing**, **documentation**, and **collaboration workflows**. + +--- + +## Next Week’s Roadmap + +- Implement **Feature XYZ** and write corresponding tests. +- Refine **technical design** based on mentor feedback. +- Prepare a mini-demo for the community check-in. + +--- + +## Resources & References + +- **PRD:** [Link to Product Requirements Document]({{prd_link}}) +- **Tech Spec & Diagrams:** [Architecture & Specs]({{tech_spec_link}}) +- **Repository:** [github.com/owner/repo](https://github.com/owner/repo) +- Any additional links, diagrams, or attachments. + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. + +--- + +`,Fi=Object.freeze(Object.defineProperty({__proto__:null,default:mt},Symbol.toStringTag,{value:"Module"})),pt=`---\r +title: "DMP ’25 Week 01 Update by Aman Chadha"\r +excerpt: "Working on a RAG model for Music Blocks core files to enhance context-aware retrieval"\r +category: "DEVELOPER NEWS"\r +date: "2025-06-09"\r +slug: "2025-06-09-dmp-25-aman-week01"\r +author: "Aman Chadha"\r +description: "DMP '25 Contributor working on retrieval-augmented generation for Music Blocks"\r +tags: "dmp25,musicblocks,rag,week01"\r +image: "assets/Images/c4gt_DMP.png"\r +---\r +\r +<!--markdownlint-disable-->\r +\r +# Week 01 Progress Report by Aman Chadha\r +\r +**Project:** [JS Internationalization with AI Translation Support](https://github.com/sugarlabs/musicblocks/pull/4459) \r +\r +**Mentors:** [Walter Bender](https://github.com/walterbender)\r +\r +**Reporting Period:** 2025-06-02 - 2025-06-08\r +\r +---\r +\r +## Goals for This Week\r +\r +- Develop a Retrieval-Augmented Generation (RAG) model using the core files of Music Blocks to provide context-aware responses.\r +- Collect and parse .po files, extracting msgid and msgstr pairs along with comments showing usage in source files.\r +- Use AST parsing (with Babel) to gather metadata chunks from source files to improve retrieval relevance.\r +\r +---\r +\r +## This Week’s Achievements\r +\r +1. **RAG Model Development** \r + - Started working on building a RAG model focused on the core Music Blocks files. This aims to give the model context about what Music Blocks is and how it functions, improving answer relevance.\r + \r +2. **Metadata Extraction from .po Files** \r + - Successfully collected msgid and msgstr pairs from translation files.\r + - Parsed comments above the translations to identify which files use each msgstr.\r + \r +3. **AST Parsing and Chunking** \r + - Used Babel to parse Music Blocks source files and extract relevant code chunks.\r + - Stored these chunks with their associated metadata to enable better context retrieval during RAG.\r +\r +---\r +\r +## Challenges & How I Overcame Them\r +\r +- **Challenge:** Parsing complex .po files with varied comment styles and ensuring correct association of usage metadata. \r + **Solution:** Created robust parsing scripts to handle different comment formats and verified chunk associations manually on sample files.\r +\r +- **Challenge:** Extracting meaningful code chunks via AST parsing while maintaining useful granularity. \r + **Solution:** Experimented with different AST traversal strategies and filters to optimize chunk size for retrieval.\r +\r +---\r +\r +## Key Learnings\r +\r +- Gained deeper understanding of the internals of Music Blocks core files and their translation system.\r +- Improved skills with Babel AST parsing and metadata extraction techniques.\r +- Learned the importance of detailed metadata in enhancing RAG model retrieval accuracy.\r +\r +---\r +\r +## Next Week’s Roadmap\r +\r +- Build a demo to showcase the RAG model's ability to answer Music Blocks-related queries with context from core files.\r +- Begin integrating metadata-enriched .po file chunks into the RAG database for improved translation string retrieval.\r +- Optimize chunking and metadata tagging strategy based on initial demo feedback.\r +\r +---\r +\r +## Resources & References\r +\r +- **Music Blocks Repository:** [github.com/your-org/musicblocks](https://github.com/your-org/musicblocks) \r +- **Babel AST Docs:** https://babeljs.io/docs/en/babel-parser \r +- **RAG Model Concepts:** https://arxiv.org/abs/2005.11401 \r +\r +---\r +\r +## Acknowledgments\r +\r +Thanks to my mentors and the DMP community for their guidance and support throughout this work.\r +\r +---\r +\r +## Connect with Me\r +\r +- GitHub: [@aman-chadha](https://github.com/ac-mmi) \r +- Gmail: [aman.chadha.mmi@gmail.com](mailto:aman.chadha.mmi@gmail.com) \r +\r +---\r +`,Ni=Object.freeze(Object.defineProperty({__proto__:null,default:pt},Symbol.toStringTag,{value:"Module"})),bt=`---\r +title: "DMP '25 Week 02 Update by Aman Chadha"\r +excerpt: "Enhanced RAG output format with POS tagging and optimized code chunking for Music Blocks"\r +category: "DEVELOPER NEWS"\r +date: "2025-06-16"\r +slug: "2025-06-16-dmp-25-aman-chadha-week02"\r +author: "@/constants/MarkdownFiles/authors/aman-chadha.md"\r +tags: "dmp25,sugarlabs,week02,aman-chadha"\r +image: "assets/Images/c4gt_DMP.png"\r +---\r +\r +<!-- markdownlint-disable -->\r +\r +# Week 02 Progress Report by Aman Chadha\r +\r +**Project:** [JS Internationalization with AI Translation Support](https://github.com/sugarlabs/musicblocks/pull/4459) \r +**Mentors:** [Walter Bender](https://github.com/walterbender) \r +**Assisting Mentors:** *None this week* \r +**Reporting Period:** 2025-06-09 - 2025-06-16 \r +\r +---\r +\r +## Goals for This Week\r +\r +- **Refactor RAG model output** to a structured dictionary format that includes part-of-speech (POS) tagging.\r +- **Optimize AST-based chunking** by limiting code context to 5 lines above and below translation usage, per mentor feedback.\r +- **Begin functional testing** of the updated RAG pipeline on real-world translation queries.\r +\r +---\r +\r +## This Week's Achievements\r +\r +1. **RAG Output Enhancement** \r + - Refactored the Retrieval-Augmented Generation model to return results as structured dictionaries.\r + - Each entry now includes \`msgid\`, \`msgstr\`, source metadata, and the dominant part of speech, improving retrieval relevance.\r +\r +2. **Code Chunking Optimization** \r + - Reduced each extracted code chunk to include only 5 lines above and below the relevant \`msgid\` usage.\r + - This improves retrieval precision and avoids irrelevant surrounding code. \r + - Implemented using Babel’s AST traversal logic.\r +\r +3. **Initial Model Testing** \r + - Started testing the RAG model using sample translation queries.\r + - Observed noticeable improvements in answer context relevance due to cleaner chunks and richer metadata.\r +\r +---\r +\r +## Challenges & How I Overcame Them\r +\r +- **Challenge:** Integrating POS tagging meaningfully into the RAG data pipeline. \r + **Solution:** Designed a dictionary schema that includes the part-of-speech alongside translation metadata, and verified correctness using test entries.\r +\r +- **Challenge:** Tuning chunk granularity without losing contextual utility. \r + **Solution:** Followed mentor Walter’s advice to use fixed ±5 line windows, and manually verified semantic coherence of resulting chunks.\r +\r +---\r +\r +## Key Learnings\r +\r +- Part-of-speech tagging can significantly improve the contextual strength of retrieved translations.\r +- Smaller, focused code chunks often result in better retrieval precision for RAG applications.\r +- Mentor feedback and collaborative iteration are key to refining both code structure and user outcomes.\r +\r +---\r +\r +## Next Week's Roadmap\r +\r +- Integrate POS-tagged RAG responses into the full i18n fallback translation pipeline.\r +- Expand test coverage to include edge-case translations and re-used \`msgid\`s.\r +- Prepare an internal demo to show RAG-powered retrieval resolving contextually ambiguous translation strings.\r +\r +---\r +\r +## Resources & References\r +\r +- **Repository:** [github.com/sugarlabs/musicblocks](https://github.com/sugarlabs/musicblocks)\r +- **RAG Concepts:** [arxiv.org/abs/2005.11401](https://arxiv.org/abs/2005.11401)\r +- **Babel Parser Docs:** [babeljs.io/docs/en/babel-parser](https://babeljs.io/docs/en/babel-parser)\r +- **spaCy POS Tagging:** [spacy.io/usage/linguistic-features#pos-tagging](https://spacy.io/usage/linguistic-features#pos-tagging)\r +\r +---\r +\r +## Acknowledgments\r +\r +Thanks to my mentor Walter Bender for his guidance on optimizing chunking strategy and enriching the retrieval logic with linguistic features.\r +\r +---\r +\r +## Connect with Me\r +\r +- GitHub: [@aman-chadha](https://github.com/ac-mmi) \r +- Gmail: [aman.chadha.mmi@gmail.com](mailto:aman.chadha.mmi@gmail.com) \r +\r +---\r +`,qi=Object.freeze(Object.defineProperty({__proto__:null,default:bt},Symbol.toStringTag,{value:"Module"})),ft=`---\r +title: "DMP '25 Week 03 Update by Aman Chadha"\r +excerpt: "Translated RAG-generated context strings, initiated batch processing, and planned for automated context regeneration"\r +category: "DEVELOPER NEWS"\r +date: "2025-06-23"\r +slug: "2025-06-23-dmp-25-aman-chadha-week03"\r +author: "@/constants/MarkdownFiles/authors/aman-chadha.md"\r +tags: "dmp25,sugarlabs,week03,aman-chadha"\r +image: "assets/Images/c4gt_DMP.png"\r +---\r +\r +<!-- markdownlint-disable -->\r +\r +# Week 03 Progress Report by Aman Chadha\r +\r +**Project:** [JS Internationalization with AI Translation Support](https://github.com/sugarlabs/musicblocks/pull/4459) \r +**Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/devinulibarri) \r +**Assisting Mentors:** *None this week* \r +**Reporting Period:** 2025-06-17 – 2025-06-23 \r +\r +---\r +\r +## Goals for This Week\r +\r +- Translate a sample set of RAG-generated context strings using AI-powered tools.\r +- Share Japanese translation variants (Kana and Kanji) with mentors for review.\r +- Begin building a batch-processing workflow to generate context for all 1535 msgid entries in the .po files.\r +- Plan an update pipeline to regenerate context for newly added or reused translation strings automatically.\r +\r +---\r +\r +## This Week’s Achievements\r +\r +1. **Translation of RAG-Generated Contexts** \r + - Translated ~70 RAG-generated context descriptions using DeepL.\r + - Shared English and Japanese translations with mentors Walter and Devin for review.\r + - For Japanese, provided both **Kana** and **Kanji** variants to ensure localization accuracy.\r +\r +2. **Batch Processing Pipeline Development** \r + - Initiated work on a batch-processing system to automate RAG context generation for all 1535 msgid entries in the translation .po file.\r + - This will drastically reduce manual overhead and improve coverage.\r +\r +3. **Planning for Context Maintenance Workflow** \r + - Designed a future-proofing plan to automatically detect newly added or reused msgids in pull requests.\r + - Began outlining a GitHub Actions-based workflow to regenerate context chunks when changes are merged into the repo.\r +\r +---\r +\r +## Challenges & How I Overcame Them\r +\r +- **Challenge:** Japanese localization required thoughtful distinction between script types (Kana vs Kanji). \r + **Solution:** Generated both forms using translation tools and consulted native guidance to ensure cultural appropriateness.\r +\r +- **Challenge:** Scaling RAG context generation to 1500+ entries without losing efficiency. \r + **Solution:** Started designing a batch system to streamline the entire generation process and set up hooks for automation in future updates.\r +\r +---\r +\r +## Key Learnings\r +\r +- Multi-language support requires nuanced translation strategies, especially for languages like Japanese.\r +- Batch automation is essential when working with large-scale i18n datasets and AI-generated content.\r +- Proactive planning for long-term maintenance helps keep i18n tooling relevant as the codebase evolves.\r +\r +---\r +\r +## Next Week’s Roadmap\r +\r +- Complete batch-processing implementation for generating RAG context for all msgids.\r +- Add persistence/storage layer to cache generated results and avoid recomputation.\r +- Set up a GitHub workflow for regenerating context on new PRs that modify or add translation strings.\r +\r +---\r +\r +## Resources & References\r +\r +- **Music Blocks Repository:** [github.com/sugarlabs/musicblocks](https://github.com/sugarlabs/musicblocks)\r +- **DeepL Translator API:** [deepl.com/docs-api](https://www.deepl.com/docs-api)\r +- **GitHub Actions Docs:** [docs.github.com/actions](https://docs.github.com/actions)\r +- **RAG Concepts:** [arxiv.org/abs/2005.11401](https://arxiv.org/abs/2005.11401)\r +\r +---\r +\r +## Acknowledgments\r +\r +Thanks to mentors Walter Bender and Devin Ulibarri for their ongoing guidance, especially on translation validation and workflow design.\r +\r +---\r +`,Hi=Object.freeze(Object.defineProperty({__proto__:null,default:ft},Symbol.toStringTag,{value:"Module"})),yt=`---\r +title: "DMP '25 Week 04 Update by Aman Chadha"\r +excerpt: "Completed context generation for all UI strings and submitted Turkish translations using DeepL with RAG-generated context"\r +category: "DEVELOPER NEWS"\r +date: "2025-06-30"\r +slug: "2025-06-30-dmp-25-aman-chadha-week04"\r +author: "@/constants/MarkdownFiles/authors/aman-chadha.md"\r +tags: "dmp25,sugarlabs,week04,aman-chadha"\r +image: "assets/Images/c4gt_DMP.png"\r +---\r +\r +<!-- markdownlint-disable -->\r +\r +# Week 04 Progress Report by Aman Chadha\r +\r +**Project:** [JS Internationalization with AI Translation Support](https://github.com/sugarlabs/musicblocks/pull/4459) \r +**Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/devinulibarri) \r +**Reporting Period:** 2025-06-24 – 2025-06-30 \r +\r +---\r +\r +## Goals for This Week\r +\r +- Complete RAG-based context generation for **all UI strings** in the \`.po\` file.\r +- Translate the Turkish \`.po\` file using DeepL with generated context.\r +- Share Turkish translation with mentors for review and validation of context effectiveness.\r +\r +---\r +\r +## This Week’s Achievements\r +\r +1. **Full Context Generation Completed** \r + - Successfully generated context for all 1,536 active \`msgid\` entries using the RAG (Retrieval-Augmented Generation) model.\r + - Ensured each UI string now has an associated contextual description to guide translators.\r +\r +2. **Turkish Translation via DeepL with Context** \r + - Used the DeepL API to translate the Turkish \`.po\` file, injecting the RAG-generated context for each \`msgid\`.\r + - This serves as a real-world test to evaluate how well contextual guidance improves translation accuracy and usability.\r + - Currently awaiting feedback on the quality of Turkish translations to assess the effectiveness of the context-driven approach.\r +\r +---\r +\r +## Challenges & How I Addressed Them\r +\r +- **Challenge:** Integrating RAG-generated context into \`.po\` translation pipeline. \r + **Solution:** Adapted the \`.po\` processing script to pair each \`msgid\` with its context before sending it to DeepL, ensuring translators benefit from semantic clarity.\r +\r +- **Challenge:** Validating quality of translations in a language I do not speak. \r + **Solution:** Coordinated with mentors to review Turkish output and identify whether contextual enrichment improved translation fidelity.\r +\r +---\r +\r +## Key Learnings\r +\r +- Contextual guidance significantly strengthens AI-driven translation quality, especially for UI-specific phrases.\r +- Systematic pairing of context with each string allows scalable improvements across languages.\r +- Human review remains crucial to validate AI-generated translations and refine context generation methods.\r +\r +---\r +\r +## Next Week’s Roadmap\r +\r +- Collect and analyze mentor feedback on the Turkish \`.po\` file.\r +- Fine-tune the RAG context generation logic based on observed shortcomings, if any.\r +- Generalize the context-injection workflow for use with other languages (e.g., Spanish, French).\r +- Begin documenting the context generation + translation pipeline for future contributors.\r +\r +---\r +\r +## Resources & References\r +\r +- **Music Blocks Repository:** [github.com/sugarlabs/musicblocks](https://github.com/sugarlabs/musicblocks)\r +- **DeepL Translator API:** [deepl.com/docs-api](https://www.deepl.com/docs-api)\r +- **GitHub Actions Docs:** [docs.github.com/actions](https://docs.github.com/actions)\r +- **RAG Concepts:** [arxiv.org/abs/2005.11401](https://arxiv.org/abs/2005.11401)\r +\r +---\r +\r +## Acknowledgments\r +\r +Thanks to mentors Walter Bender and Devin Ulibarri for their feedback, review assistance, and continued support in improving translation workflows.\r +\r +---\r +`,Ki=Object.freeze(Object.defineProperty({__proto__:null,default:yt},Symbol.toStringTag,{value:"Module"})),wt=`--- +title: "DMP '25 Week 01 Update by Anvita Prasad" +excerpt: "Initial research and implementation of Music Blocks tuner feature" +category: "DEVELOPER NEWS" +date: "2025-06-08" +slug: "2025-06-08-DMP-25-AnvitaPrasad-week01" +author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" +tags: "dmp25,sugarlabs,week01,AnvitaPrasad" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 01 Progress Report by Anvita Prasad + +**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) +**Mentors:** [Walter Bender](https://github.com/walterbender) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-02 - 2025-06-08 + +--- + +## Goals for This Week + +- **Goal 1:** Update Tone.js to the latest version +- **Goal 2:** Begin tuner implementation with pitch detection +- **Goal 3:** Create basic tuner visualization + +--- + +## This Week's Achievements + +1. **Updated Tone.js Library** + - Successfully upgraded from version 15.0.4 to 15.1.22 + - Verified compatibility with existing codebase + +2. **Implemented Pitch Detection** + - Integrated YIN algorithm for pitch detection + - Established foundation for note identification + +3. **Created Basic Tuner Interface** + - Implemented 11-segment tuner display + - Added initial cents adjustment UI + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Understanding complex audio processing concepts + **Solution:** Studied Web Audio API documentation and experimented with example code + +--- + +## Key Learnings + +- Gained familiarity with Tone.js API and audio processing +- Learned about pitch detection algorithms and their implementation + +--- + +## Next Week's Roadmap + +- Complete tuner implementation with accurate visualization +- Implement cents adjustment calculations +- Add fine-tuning to pitch detection system +- Test with various audio sources +- Write Week 02 blog post summarizing progress and learnings + +--- + +## Resources & References + +- **Web Audio Resources:** [MDN Web Audio API Guide](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) +- **Pitch Detection:** [PitchDetect Example](https://github.com/cwilso/pitchdetect) +- **Online Tuner Reference:** [Musicca's Online Tuner Guide](https://www.musicca.com/tuner) + +--- + +## Acknowledgments + +Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support. + +---`,Vi=Object.freeze(Object.defineProperty({__proto__:null,default:wt},Symbol.toStringTag,{value:"Module"})),vt=`--- +title: "DMP '25 Week 02 Update by Anvita Prasad" +excerpt: "Research and design of tuner visualization system and cents adjustment UI" +category: "DEVELOPER NEWS" +date: "2025-06-15" +slug: "2025-06-15-DMP-25-AnvitaPrasad-week02" +author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" +tags: "dmp25,sugarlabs,week02,AnvitaPrasad" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 02 Progress Report by Anvita Prasad + +**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) +**Mentors:** [Walter Bender](https://github.com/walterbender) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-09 - 2025-06-15 + +--- + +## Goals for This Week +- **Goal 1:** Design dual-mode tuner interface +- **Goal 2:** Research and prototype cents adjustment UI +- **Goal 3:** Investigate temperament systems and EDO implementations +- **Goal 4:** Implement visual feedback system for pitch detection + +--- + +## This Week's Achievements + +1. **Researched Dual-Mode Tuner Design** + - Analyzed requirements for two proposed tuning modes: + - Specific Target Pitch mode with fixed reference + - Arbitrary mode with dynamic ±50 cents range detection + - Started working on UI mockups for both modes + - Researching effective visual feedback systems for pitch deviation + +2. **Implemented Initial Cents Adjustment Feature** + - Created basic manual cents adjustment UI + - Exploring alternative UI approaches for better user experience + - Studying various tuner implementations for inspiration + +3. **Developed Tuner Visualization System** + - Implemented center-outward segment lighting system + - Left/right segments indicate flat/sharp notes respectively + - Number of lit segments shows pitch deviation magnitude + +4. **Pitch Detection System Research** + - Studied advanced pitch detection methodologies + - Researched FFT spectrum analysis and phase information evaluation + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Difficulty in accurately detecting pitch in real-time + **Solution:** Researched and implemented better audio processing algorithms with help from mentor feedback + +- **Challenge:** Making the tuner interface user-friendly and responsive + **Solution:** Studied existing tuner applications and simplified the visual feedback system + +--- + +## Key Learnings +- Gained deep understanding of Equal Divisions of the Octave (EDO) systems and their implementation challenges +- Learned about various temperament systems (Equal, Just, Werckmeister, Kirnberger) +- Studied advanced audio processing techniques including FFT window optimization and spectrum phase analysis +- Researched UX patterns for precise musical instrument tuning interfaces +- Explored different approaches to visual feedback systems for micro-pitch detection + +--- + +## Next Week's Roadmap +- Complete tuner implementation with accurate visualization +- Finalize and implement the selected cents adjustment UI design +- Write Week 03 blog post summarizing progress and learnings + +--- + +## Resources & References +- **EDO & Tuning Systems:** [Ableton's Guide to EDO Tunings](https://tuning.ableton.com/edo/intro-to-edo/) +- **Online Tuner Reference:** [Musicca's Online Tuner Guide](https://www.musicca.com/tuner) +- **Pitch Detection Implementation:** [PitchDetect JavaScript Implementation](https://github.com/cwilso/PitchDetect/blob/main/js/pitchdetect.js) +- **Research Reference:** [F-Droid Tuner Implementation](https://f-droid.org/en/packages/de.moekadu.tuner/) + +--- + +## Acknowledgments +Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support. + +--- +`,Ji=Object.freeze(Object.defineProperty({__proto__:null,default:vt},Symbol.toStringTag,{value:"Module"})),kt=`--- +title: "DMP '25 Week 05 Update by Anvita Prasad" +excerpt: "Implementation of manual cent adjustment interface and mode-specific icons for the tuner system" +category: "DEVELOPER NEWS" +date: "2025-07-06" +slug: "2025-07-06-DMP-25-AnvitaPrasad-week05" +author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" +tags: "dmp25,sugarlabs,week05,AnvitaPrasad" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 05 Progress Report by Anvita Prasad + +**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) +**Mentors:** [Walter Bender](https://github.com/walterbender) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-06-30 - 2025-07-06 + +--- + +## Goals for This Week +- **Goal 1:** Design and implement a slider for manual cent adjustment +- **Goal 2:** Develop functionality for cent adjustment system +- **Goal 3:** Design and implement mode-specific icons for the tuner interface + + +--- + +## This Week's Achievements + +1. **Mode-Specific Icon Design and Implementation** + - Created distinctive icons for both tuning modes + - Successfully integrated icons into the tuner interface + - Ensured visual consistency with existing Music Blocks design language + +2. **Manual Cent Adjustment Interface Redesign** + - Transitioned from pie menu to slider-based interface + - Implemented basic slider UI for cent adjustment + - Designed interface to accommodate ±50 cents range + - Optimized for both recorded and uploaded samples through the sampler + +3. **Cent Adjustment System Development** + - Implementing core functionality for precise pitch adjustment + - Developed system to handle cent adjustments within ±50 range + - Created framework for real-time pitch modification + +4. **Integration and Testing** + - Successfully integrated new components with existing tuner system + - Conducted initial testing of slider functionality + - Verified icon visibility and clarity in different modes + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Maintaining precise control over cent adjustments while ensuring smooth slider operation +- **Solution:** Implemented a custom scaling algorithm and added intermediate value snapping for better control + + +--- + +## Key Learnings +- Gained deeper understanding of real-time audio processing in web applications +- Discovered best practices for handling micro-pitch adjustments in digital audio systems +- Enhanced knowledge of Web Audio API's capabilities and limitations + +--- + +## Next Week's Roadmap +- Conduct extensive testing with various audio sources and instruments +- Process free/open samples from identified sources +- Design basic categorization system for samples +- Write Week 06 blog post summarizing progress and learnings + +--- + +## Resources & References +- **Audio Processing:** [Web Audio API Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) +- **Cent Calculation:** [Cents to Frequency Ratio Calculator](https://www.sengpielaudio.com/calculator-centsratio.htm) +- **Musical Tuning:** [Musical Acoustics - Cents and Frequency Ratios](https://newt.phys.unsw.edu.au/jw/notes.html) +- **UI Components:** Referenced existing Music Blocks slider implementations for consistency + +--- + +## Acknowledgments +Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support. + +--- `,Xi=Object.freeze(Object.defineProperty({__proto__:null,default:kt},Symbol.toStringTag,{value:"Module"})),St=`--- +title: "DMP '25 Week 06 Update by Anvita Prasad" +excerpt: "Improve Synth and Sample Feature for Music Blocks" +category: "DEVELOPER NEWS" +date: "2025-07-13" +slug: "2025-07-13-DMP-25-AnvitaPrasad-week06" +author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" +tags: "dmp25,sugarlabs,week06,AnvitaPrasad,midterm" +image: "assets/Images/c4gt_DMP.png" +--- + +<!-- markdownlint-disable --> + +# Week 06 Progress Report by Anvita Prasad + +**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) +**Mentors:** [Walter Bender](https://github.com/walterbender) +**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) +**Reporting Period:** 2025-07-07 - 2025-07-13 + +--- + +## Goals for This Week +- **Goal 1:** Implement manual cent adjustment functionality in the sampler widget +- **Goal 2:** Ensure cent adjustments persist when saving samples +- **Goal 3:** Research methods for manual cent adjustment implementation +- **Goal 4:** Collect SVG icons for the set instrument widget +- **Goal 5:** Design basic categorization system for samples + +--- + +## This Week's Achievements + +1. **Cent Adjustment Persistence Implementation** + - Extended the CUSTOMSAMPLES array to include cent adjustment values + - Modified _addSample function to maintain backward compatibility + - Updated __save function to include cent adjustment in block properties + - Enhanced _updateBlocks to display cent adjustments in block text (e.g., "C4 +10¢") + +2. **Playback Rate Calculation System** + - Implemented the mathematical formula for converting cents to playback rate + - Applied consistent calculation throughout the codebase (playbackRate = Math.pow(2, cents/1200)) + - Ensured accurate pitch modification across all sample playback scenarios + +3. **Synth Integration** + - Modified _createSampleSynth function to store cent adjustments with samples + - Updated trigger function to apply adjustments to playback rate during sample playback + - Created framework for real-time pitch modification during performance + +4. **Instrument Organization and Visualization** + - Collected SVG icons for each instrument and instrument family + - Designed a hierarchical structure to better organize the set instruments widget + - Created a more intuitive categorization system for instrument selection + - Improved visual navigation through instrument families + +--- + +## Challenges & How I Overcame Them + +- **Challenge:** Persisting Cent Adjustment Information + **Solution:** In the previous week, I had implemented cent adjustments by modifying the playback rate in real-time, but this information wasn't being stored with the sample. This meant that when a user saved a sample after making cent adjustments, the adjustments were lost, creating inconsistency in musical compositions. I researched two main approaches: storing notes as floating-point MIDI values (e.g., 60.1 for C4+10¢) or storing integer MIDI notes and cent adjustments separately. I chose the second approach for better compatibility with Music Blocks' existing codebase, clearer data representation, and easier UI integration. I'm still testing this implementation to ensure it works correctly across all use cases. + +- **Challenge:** Modifying the Sample Data Structure + **Solution:** I carefully extended the CUSTOMSAMPLES array to include the cent adjustment value while ensuring backward compatibility. This required precise modifications to several core functions that interact with the sample data structure. + +--- + +## Key Learnings +- Audio Processing Fundamentals: Deepened understanding of how cent adjustments affect pitch perception and the mathematical relationship between cents and playback rate. +- Data Persistence Strategies: Learned different approaches to storing and retrieving fine-grained musical parameters, and the trade-offs between integrated vs. separate storage models +- DOM Manipulation for Audio UI: Gained experience creating responsive audio controls that provide visual feedback while manipulating sound parameters in real-time +- Code Refactoring Best Practices: Developed skills in modifying existing functionality while maintaining backward compatibility, especially in a complex music programming environment +- Tone.js Audio API: Enhanced understanding of Tone.js's Sampler implementation and how to manipulate playback parameters like playback rate for pitch adjustments + +--- + +## Midterm Evaluation Summary (Weeks 01–06) + +Over the past six weeks, I've made significant progress on improving Music Blocks' synth and sample features, focusing on enhancing the tuning system and implementing micro-pitch adjustments. I've successfully completed the development of a comprehensive dual-mode tuner system that provides precise pitch feedback and visualization. Additionally, I've implemented a manual cent adjustment feature that allows for microtonality exploration and fine-tuning of samples. These enhancements significantly expand Music Blocks' capabilities for musical education, enabling students to explore pitch relationships beyond standard Western tuning systems and providing educators with powerful tools for teaching advanced musical concepts. + +### Technical Achievements + +1. **Audio Foundation Improvements** + - Updated Tone.js library from version 15.0.4 to 15.1.22 + - Integrated YIN algorithm for accurate pitch detection + - Implemented low-pass filtering to handle high-frequency noise + - Enhanced pitch detection accuracy using parabolic interpolation + +2. **Tuner System Development** + - Created comprehensive dual-mode tuner interface: + - Chromatic mode that automatically finds closest pitch + - Target pitch mode with fixed reference point + - Implemented 11-segment visualization system with center-outward lighting + - Added clear visual feedback for cent deviation + - Designed mode-specific icons and toggle interface + +3. **Cent Adjustment System** + - Evolved from initial pie menu design to more efficient slider interface + - Implemented ±50 cents range adjustment capability + - Created framework for real-time pitch modification + - Developed system to store and apply cent adjustments to samples + - Extended data structures to maintain cent adjustment information + +4. **Integration and Testing** + - Conducted extensive testing with various audio sources + - Created test suite for tuner accuracy verification + - Optimized signal processing for better performance + - Ensured backward compatibility throughout implementation + +### Educational and Creative Impact + +These improvements significantly enhance Music Blocks' capabilities for musical education and exploration: + +- **Microtonality Access**: Students can now explore pitches between standard Western notes, opening doors to world music traditions and experimental composition +- **Improved Accuracy**: The enhanced tuner provides precise feedback for instrument tuning and vocal training +- **Educational Value**: Visual feedback systems help students understand pitch relationships and develop better ear training +- **Creative Possibilities**: Cent adjustments enable more expressive performances and composition with subtle pitch variations + +### Final Thoughts + +The first half of this project has established a solid foundation for Music Blocks' enhanced audio capabilities. The dual-mode tuner and cent adjustment systems provide both technical accuracy and user-friendly interfaces for students and educators. These features have significantly expanded Music Blocks' capacity for musical exploration beyond standard Western tuning. Moving forward, I'll focus on sample organization and multiple sample functionality to further enhance the expressiveness and educational value of the platform. + +--- + +## Next Week's Roadmap +- Implement the basic categorization system for samples +- Process free/open samples from identified sources +- Work on handling multiple samples +- Test the manual cent adjustment feature and finalise the approach +- Write Week 07 blog post summarizing progress and learnings + +--- + +## Resources & References +- **Audio Processing:** [Web Audio API Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) +- **Cent Calculation:** [Cents to Frequency Ratio Calculator](https://www.sengpielaudio.com/calculator-centsratio.htm) +- **Musical Tuning:** [Musical Acoustics - Cents and Frequency Ratios](https://newt.phys.unsw.edu.au/jw/notes.html) +- **Tone.js Documentation:** [Tone.js Sampler](https://tonejs.github.io/docs/14.7.77/Sampler) +- **Audio Sample Processing:** [Microtonality in Digital Audio Workstations](https://www.researchgate.net/publication/327567188_Microtonality_and_the_DAW_A_Design_Study) + +--- + +## Acknowledgments +Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support. + +--- `,$i=Object.freeze(Object.defineProperty({__proto__:null,default:St},Symbol.toStringTag,{value:"Module"})),It=`--- +title: Culture and Pedagogy +slug: culture +author: Sugar Labs Team +lastUpdated: 2025-03-07 +category: Education +--- +<!-- markdownlint-disable --> + +## What makes Sugar different? +It would be nice to define what we are talking about when we say "Sugar," since we have multiple platforms. For example, is this page dedicated to Sugar as a desktop environment, or do we want to make this broader to include web apps, Sugarizer, etc.? + +- **Sugar facilitates sharing and collaboration**: children can write articles, share books, or make music together with a single mouse click. +- **Activities, not applications**: Sugar activities are applicable beyond the scope of the classroom and even Sugar itself. +- **Automatic backup of Activity work**: No worrying about files or folders. Sugar’s Journal makes it almost impossible to lose any data. +- **The Journal records everything you do**: It is a place to reflect upon and evaluate your work. +- **Sugar runs on most computer hardware**, including slower machines. +- **Sugar is Free (Libre) Software**: It is written in Python and easily customized. +- **Sugar is documented by its users**: It is easy to use, and teachers worldwide have created a wealth of pedagogical materials for it. +- **Sugar is written by its users**: 50% of the updates to our latest release came directly from our users. + - It would be nice to have a link here, for reference. + +## What are the benefits of using Sugar? +- **Hundreds of tools for discovery**: Exploring, expressing, and sharing through online research, writing, coding, and more. +- **Built-in collaboration system**: Peer-to-peer learning; always-on support; and single-click sharing. + - What is "always-on support"? +- **A built-in portfolio assessment tool** called Journal that serves as a forum for discussion between children, parents, and teachers. +- **A discoverable learning platform**: It uses simple means to reach complex ends. + - What do we mean by "discoverable"? That we can use the platform to discover ideas? +- **Designed for local appropriation**: Sugar has built-in tools for making changes and improvements and a growing global community of support. + - Twenty-five languages are currently available. +- **An emphasis on learning through doing and debugging**: Engages learners better to tackle authentic problems. +- **Available in a wide variety of forms**: As part of GNU/Linux distributions, as well as LiveCD, LiveUSB, and in a virtual machine for Windows and Mac machines. + +## What are the Sugar advantages? +- **Pedagogical framework** centered around Constructionism learning and founded on student empowerment. +- **Collaboration and journaling features**, uniquely designed by educators for educators and learners. +- **Hundreds of activities**. +- **Large and committed community** of developers, teachers, and learners from all around the globe. + - Perhaps it would be nice to have numbers here, if possible. +- **24/7 community support**. + - What do we mean by this? That we are available by Matrix/IRC? +- **Online and in-person training and workshops available**. +- **Handouts available to use in the classroom**. +- **Teacher-driven development**, rapidly expanding every day. +- **Easily localizable and customizable**. +- **Free/Libre software**: No licensing fees. +- **A global project**: No single point of dependency or failure. + +## A *learning-centric* approach +At Sugar Labs, we strive for a *learning-centric* approach, where teachers mentor students as they engage with powerful ideas, or *instructing less and learning more*. + +At Sugar Labs, we give children access to *knowledge*—through media such as electronic books, the world-wide web, and multimedia—but, more importantly, we give them the tools they need to *create*, to learn about learning, to put knowledge to use, and engage in reflection and critical dialogue. + +With Sugar, we help learners *acquire knowledge* so that they grow as active consumers, critics, and *creators of knowledge*; Sugar welcomes them as members of a vibrant learning community. + +Plus, cross-community collaboration between technologists and teachers ensures that the ideals of student empowerment, freedom, sharing, open critique, and transparency will remain an integral part of Sugar—one that touches the lives of children and their communities all across the world’s classrooms. + +## The Free (Libre) Software culture +The Sugar pedagogy is embodied in the culture of Free/Libre Software; teachers and students are empowered with both the freedom to actively participate and the freedom to be critical. + +Criticism of ideas is a powerful force in learning, as well as in fostering economic development; unleashing this potential is an important part of our mission. +`,Yi=Object.freeze(Object.defineProperty({__proto__:null,default:It},Symbol.toStringTag,{value:"Module"})),At=`--- +title: 'Markdown Test Page' +slug: 'markdown-test' +category: 'MarkdownData' +--- +<!-- markdownlint-disable --> +# The Ultimate Markdown Test Document (NOTE: THIS IS AI GENERATED) + +## Basic Formatting + +This text is **bold** and this is *italic*. You can also have ~~strikethrough text~~ and ==highlighted text== for emphasis. + +You can add super^script^ and sub~script~ text when needed. + +## Links and Code + +Visit [our website](https://example.com) for more information. + +Here's some \`inline code\` within a paragraph for demonstration. + +### Code Block Example + +Below is an example of a JavaScript function: + +\`\`\`javascript +// Returns a greeting for the provided name + +function greet(name) { + + return \`Hello, \${name}!\`; + +} + +console.log(greet("Markdown")); +\`\`\` + +## Lists + +### Unordered Lists + +- First item +- Second item +- Third item + +### Ordered Lists + +1. First ordered item +2. Second ordered item +3. Third ordered item + +### Task Lists + +- [ ] Uncompleted task +- [x] Completed task +- [ ] Another pending task + +## Tables + +| Feature | Supported | Notes | +|----------------|-----------|-------------------------------------| +| Headers | ✅ | With anchor links | +| Bold/Italic | ✅ | Basic formatting | +| Code Blocks | ✅ | With language support | +| Tables | ✅ | Responsive design | +| Lists | ✅ | Unordered, ordered, task lists | + +## Blockquotes with Proper Nesting + +> This is a simple blockquote. + +> This is a multi-line blockquote that continues on the next line. +> This is a multi-line blockquote that continues on the next line. + +## Images with Captions + + + +## Horizontal Rules + +Above this text is regular content. + +---- + +Below is separated by a horizontal rule. + +## Special Features + +### Collapsible Sections + +:::details Click to see hidden content +This content is hidden by default until the user clicks the summary. + +Here you can write additional **markdown content**, include lists, or even code. +Enjoy the hidden content! +::: + +### YouTube Embed + +[youtube: MM-H69cHYMk] + +### Emoji Support + +:smile: I'm happy to see this working! +:rocket: Let's launch this feature! +:warning: Be careful with this syntax. +:thumbsup: Looks good to me! +:heart: Love this feature! +:fire: This is awesome! +:star: Five-star quality! +:info: Here's some information. +:check: This is correct! +:x: This is wrong. + +## Combined Examples + +> This blockquote contains **bold text** and a [link](https://example.com) to example.com. + +- List item with **bold** and *italic* text. +- Item with a [link](https://example.com) and \`inline code\`. +- Item with ==highlighted text== that stands out. + +## Advanced Typography Test + +Water is H~2~O and an ordinal number like 5^th^ is very common. + +This paragraph includes ~~strikethrough text~~ and ==highlighted text== to denote important information. + +## Paragraphs with Line Breaks + +This is a paragraph with +line breaks that are preserved as spaces within the paragraph. + +This is another paragraph +after a blank line. + +### Final Thoughts + +This Markdown file has been designed to demonstrate multiple aspects of our custom Markdown parser. Every section shows different capabilities from formatting to embedded media. + +Thank you for reading this detailed Markdown test document! :heart:`,Qi=Object.freeze(Object.defineProperty({__proto__:null,default:At},Symbol.toStringTag,{value:"Module"})),Lt=`--- +title: Sugar Labs For Parents +slug: parents +author: Sugar Labs Team +lastUpdated: 2025-03-07 +category: Education +--- +<!-- markdownlint-disable --> + +## Background +The Sugar Learning Platform (Sugar) was first developed as the software platform for the One Laptop per Child (OLPC) program, a spin-off project from the MIT Media Lab in 2006. + +The founders of OLPC, Nicholas Negroponte, Seymour Papert, and Walter Bender, promoted the idea that learning is not a luxury and that a lack of an educated society is not just an inconvenience. Learning is fundamental to a free society that aspires to be both prosperous and sustainable. All societies value the role that education plays in economic development, and education is essential to the survival of democratic societies. + +Seymour Papert and Cynthia Solomon, co-inventors of the Logo programming language (along with Wally Feurzeig), described their pioneering efforts to use the Logo language as a vehicle for introducing children to computational thinking. They defined it in terms of heuristics: things to think with and reflect upon. + +In 1971, Papert and Solomon published *“20 Things to do with a Computer”*, a catalog of project ideas ranging from robotics to music to visual arts. This work foreshadowed what today is often referred to as the *Maker Movement*. Almost 50 years ago, children were using Logo as a tool for the autonomous construction of meaningful artifacts and pursuing mastery in solving personally meaningful problems. + +--- + +## Sugar Pedagogy +> **“Learning is hard fun.”** – Marvin Minsky +> **“A six-year-old child can become an expert.”** – Marvin Minsky + +In a 2008 essay questioning “general” education, Marvin Minsky proposed that we *“re-aim our schools towards encouraging children to pursue more focused hobbies and specialties—to provide them with more time for (and earlier experience with) developing more powerful sets of mental skills, which they later can extend to more academic activities.”* + +Minsky encourages children to construct multi-level *cognitive towers*, built upon: +- Instinctive reactions +- Learned reactions +- Deliberate thinking +- Reflective thinking +- Self-reflective thinking +- Self-conscious reflection + +These levels span agencies specializing in areas such as gaining knowledge from experience, planning and causal attribution, the construction of models, and identifying values and ideals. + +A focus on achieving meaningful goals—not just the accumulation of simple knowledge objects—exercises all levels in a cognitive tower, helping children *develop proficiencies that can be used in other domains*. As a model for learning, the levels within Minsky’s cognitive towers represent broadly applicable skills. + +Minsky’s towers are inherently complex and require a learner to be motivated and persistent in their construction—a process he once described as *"hard fun."* + +This aligns with research by Daniel Pink, who reviewed four decades of studies showing that motivation for learning comes from: +1. **Autonomy** – the freedom to explore and express ideas +2. **Mastery** – confidence and space to develop expertise +3. **Purpose** – authentic problem-solving opportunities + +A key insight of Minsky, Papert, and Solomon is to give children tools they can explore, master, and apply to problems they care about. Children using Sugar are **motivated learners**, pursuing meaningful goals that help them build their own “cognitive towers.”`,Zi=Object.freeze(Object.defineProperty({__proto__:null,default:Lt},Symbol.toStringTag,{value:"Module"})),Tt=`--- +title: Sugar Labs For School Administrators +slug: school-admin +author: Sugar Labs Team +lastUpdated: 2025-03-07 +category: Education +--- +<!-- markdownlint-disable --> + +## Student and teacher agency + +Sugar provides the user with affordances (things we designed for the possibility of taking action by the user) and pathways to engage in developing skills. Sugar is not instructional curricula in part because curricula tend to reflect very local norms and needs, and as a consequence, are resistant to global solutions. + +Also, Sugar reflects an explicit rejection of instruction as a pedagogical framework. With Sugar, we try to give agency to the learner, knowing that in all likelihood, the institution of school would likely be trying to take away agency. At each design decision point, we asked ourselves: +- *How will this impact the learning?* +- *How will this impact the autonomy and agency of the learner and the teacher?* + +Agency is made possible in part because of the choice of a software license, the **General Public License (GPL)**, which ensures that the learner has permission to both use Sugar and to modify it. + +We go a step further by giving the learner affordances to engage in software development and debugging, i.e., to exploit the license. We provide a context for encouraging the learner to take initiative, both by deliberately leaving the platform “incomplete” and by providing a social norm in which it is expected to take initiative. Even if it were possible to make Sugar “complete”, we would have chosen not to. We wanted there always to be “itches” needing to be scratched. + +In a related design decision, Sugar was never intended to be an endpoint in and of itself. Rather, we envisioned it as a waypoint along a lifelong journey of learning. We encourage our users to outgrow Sugar and even provide them with a means of advancing from the Sugar desktop, with its tools for exploration, to the **GNOME desktop**, with its more powerful tools for production. + +--- + +## What using Sugar can do for your students and school? + +The **Sugar Learning Platform** was designed to promote collaborative learning through tools and activities that encourage critical thinking. Sugar puts an emphasis on divergent thinking. A related goal is to make that thinking visible to the learner. + +Sugar equally promotes cultures of **expression and reflection**. With Sugar, we provide teachers and learners with a collection of open-ended tools and activities, applicable to problems of their own choosing. + +### Sugar offers an alternative to traditional “office-desktop” software based on three affordances: + +1. **Sharing:** + Collaboration is a first-order experience. The interface always shows the presence of other learners who are available for collaboration. Sugar allows users to dialog, support, critique, and share ideas with each other. + +2. **Reflecting:** + A "journal" records each learner’s activity. It is a built-in space for reflection and assessment of progress. + +3. **Discovering:** + Sugar tries to accommodate a wide variety of users with different levels of skill in terms of reading and language and different levels of experience with computing by providing activities with a "low floor" and, where possible, "no ceiling." + +> **“The only time collaboration is called cheating is when you are in school.” – Walter Bender** + +Sugar drew inspiration for its activities and the fluid interface between activities from observing how the **free software community** collaborates. Software developers chat, socialize, play games, share media, and collaborate on media creation and programming in both formal and informal settings. + +Sugar users are given access to a variety of commonly used tools for collaboration, e.g., **Chat and IRC**. By default, the IRC application opens into the \`#sugar\` channel on \`irc.freenode.net\`, where Sugar developers discuss their work. + +--- + +## Reflection and assessment in the context of Sugar and interoperability with school administrative systems + +In the early days of the development of the Sugar user interface, one of the biggest points of contention with the OLPC advisory board was when we told them that we were not going to use **file browsing** as the primary mode of navigation. We were asked, +*"How will the children learn to use Windows?"* +Our response was, *"Why do they need to learn to use Windows?"* + +Instead of browsing a filesystem, Sugar gives the user a **journal or notebook** into which one’s work is “kept” rather than “saved.” The interface tries to keep things that offer value automatically in the Sugar journal. + +The primary function of the journal is as a **time-based view** of the activities of a learner. As with physical media, such as pen on paper, no explicit "saving" step is needed. The individual journal entries are treated much like pages in a **laboratory notebook**. + +### Assessment in Sugar: +- **Digital Portfolio:** + Sugar journal entries are directly incorporated into **digital portfolios** to support reflection that can help students (as well as teachers and parents) be aware of their own learning. +- **Impact Measurement:** + Sugar acknowledges the need for **measurement and evaluation**. Sugar does not take a position on high-stake testing but advocates for an evaluation that looks more broadly than standardized tests. +- **Custom Metadata for Journal Entries:** + Teachers can know what tools a student may have used and how many iterations they made in creating an artifact. + +--- + +## Where to get resources? + +For more information, visit the **official Sugar Labs website** and explore its resources on **collaborative learning, development tools, and community support**.`,er=Object.freeze(Object.defineProperty({__proto__:null,default:Tt},Symbol.toStringTag,{value:"Module"})),Pt=`--- +title: Student Learning Goals and Sugar +slug: students +author: Sugar Labs Team +lastUpdated: 2025-03-07 +category: Education +--- +<!-- markdownlint-disable --> + +## Student Learning Goals and Sugar + +> *"Learning with Sugar is something a child does, not something that is done to or for a child." – Walter Bender* + +Sugar is a collection of hundreds of tools designed to introduce children to programming, computational thinking, and problem-solving. Sugar has no set curriculum; its best practice is to immerse children in problem-solving and debugging. Children are given agency to work on problems they are passionate about in a context where there is an expectation that there were no predetermined solutions or prescribed paths to a solution. + +As Solomon observed, *“debugging is the greatest learning opportunity of the 21st century.”* While engaged in problem-solving, children are developing and refining the algorithms employed by the agents in the various levels of their cognitive towers. + +While computation and coding are at the heart of Sugar, Sugar is not a programming curriculum: computational thinking goes well beyond the realm of learning to code. While the specific algorithms they discuss—searching, sorting, optimal stopping, predicting, etc.—are useful in and of themselves, the real power of computational thinking lies in its systematic approach to debugging and problem-solving. + +Learning that problems can be addressed systematically is the underlying **“powerful idea”** of programming. The process of writing and then repairing or **debugging** a program provides a basis for active learning through trial and error, regardless of what the problem that is actually being solved. + +--- + +## Learning with Pages in the Wiki + +These books are recommended as a rich source of ideas on how to use Sugar in and out of the classroom: + +- **Sdenka book** +- **Bender, W., Kane, C., Cornish, J., Donahue, N.** (2012). *Learning to Change the World: The Social Impact of One Laptop per Child.* Palgrave Macmillan. +- **Christian, B. and Griffiths, T.** (2016). *Algorithms to Live By: The Computer Science of Human Decisions.* Henry Holt and Co. +- **Hetland, L., Winner, E., Veenema S., and Sheridan, K.M.** (2007). *Studio Thinking: The Real Benefits of Visual Arts Education.* Teachers College Press. +- **Papert, S. & Solomon, C.** (1971). *Twenty Things to Do with a Computer.* *Artificial Intelligence Memo No. 248* and *Logo Memo No. 3.* +- **Pink, D.** (2009). *Drive: The Surprising Truth About What Motivates Us.* Riverhead Press. +- **Stefanakis, E.** (2002). *Multiple Intelligences and Portfolios: A Window into the Learner's Mind.* Greenwood Press. +- **Trinidad, G.** (2013). *Física con XO.*`,nr=Object.freeze(Object.defineProperty({__proto__:null,default:Pt},Symbol.toStringTag,{value:"Module"}));export{Pa as $,na as A,ta as B,aa as C,oa as D,ia as E,ra as F,sa as G,la as H,da as I,ca as J,ua as K,ha as L,ga as M,ma as N,pa as O,ba as P,fa as Q,ya as R,wa as S,va as T,ka as U,Sa as V,Ia as W,Aa as X,La as Y,Ta as Z,Ht as _,Ct as a,Bo as a$,Ca as a0,Ma as a1,xa as a2,Ga as a3,_a as a4,Ea as a5,Da as a6,ja as a7,Wa as a8,Oa as a9,uo as aA,ho as aB,go as aC,mo as aD,po as aE,bo as aF,fo as aG,yo as aH,wo as aI,vo as aJ,ko as aK,So as aL,Io as aM,Ao as aN,Lo as aO,To as aP,Po as aQ,Co as aR,Mo as aS,xo as aT,Go as aU,_o as aV,Eo as aW,Do as aX,jo as aY,Wo as aZ,Oo as a_,Ba as aa,Ra as ab,za as ac,Ua as ad,Fa as ae,Na as af,qa as ag,Ha as ah,Ka as ai,Va as aj,Ja as ak,Xa as al,$a as am,Ya as an,Qa as ao,Za as ap,eo as aq,no as ar,to as as,ao as at,oo as au,io as av,ro as aw,so as ax,lo as ay,co as az,Mt as b,Ji as b$,Ro as b0,zo as b1,Uo as b2,Fo as b3,No as b4,qo as b5,Ho as b6,Ko as b7,Vo as b8,Jo as b9,ki as bA,Si as bB,Ii as bC,Ai as bD,Li as bE,Ti as bF,Pi as bG,Ci as bH,Mi as bI,xi as bJ,Gi as bK,_i as bL,Ei as bM,Di as bN,ji as bO,Wi as bP,Oi as bQ,Bi as bR,Ri as bS,zi as bT,Ui as bU,Fi as bV,Ni as bW,qi as bX,Hi as bY,Ki as bZ,Vi as b_,Xo as ba,$o as bb,Yo as bc,Qo as bd,Zo as be,ei as bf,ni as bg,ti as bh,ai as bi,oi as bj,ii as bk,ri as bl,si as bm,li as bn,di as bo,ci as bp,ui as bq,hi as br,gi as bs,mi as bt,pi as bu,bi as bv,fi as bw,yi as bx,wi as by,vi as bz,xt as c,Xi as c0,$i as c1,Yi as c2,Qi as c3,Zi as c4,er as c5,nr as c6,Gt as d,_t as e,Et as f,Dt as g,jt as h,Rt as i,Wt as j,Ot as k,Nt as l,Bt as m,zt as n,Ut as o,qt as p,Kt as q,Vt as r,Ft as s,Jt as t,Xt as u,$t as v,Yt as w,Qt as x,Zt as y,ea as z}; diff --git a/public/assets/post-assets/2024-annual-report/image1.jpg b/assets/post-assets/2024-annual-report/image1.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image1.jpg rename to assets/post-assets/2024-annual-report/image1.jpg diff --git a/public/assets/post-assets/2024-annual-report/image10.png b/assets/post-assets/2024-annual-report/image10.png similarity index 100% rename from public/assets/post-assets/2024-annual-report/image10.png rename to assets/post-assets/2024-annual-report/image10.png diff --git a/public/assets/post-assets/2024-annual-report/image11.jpg b/assets/post-assets/2024-annual-report/image11.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image11.jpg rename to assets/post-assets/2024-annual-report/image11.jpg diff --git a/public/assets/post-assets/2024-annual-report/image12.jpg b/assets/post-assets/2024-annual-report/image12.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image12.jpg rename to assets/post-assets/2024-annual-report/image12.jpg diff --git a/public/assets/post-assets/2024-annual-report/image13.jpg b/assets/post-assets/2024-annual-report/image13.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image13.jpg rename to assets/post-assets/2024-annual-report/image13.jpg diff --git a/public/assets/post-assets/2024-annual-report/image14.jpg b/assets/post-assets/2024-annual-report/image14.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image14.jpg rename to assets/post-assets/2024-annual-report/image14.jpg diff --git a/public/assets/post-assets/2024-annual-report/image15.png b/assets/post-assets/2024-annual-report/image15.png similarity index 100% rename from public/assets/post-assets/2024-annual-report/image15.png rename to assets/post-assets/2024-annual-report/image15.png diff --git a/public/assets/post-assets/2024-annual-report/image16.jpg b/assets/post-assets/2024-annual-report/image16.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image16.jpg rename to assets/post-assets/2024-annual-report/image16.jpg diff --git a/public/assets/post-assets/2024-annual-report/image17.jpg b/assets/post-assets/2024-annual-report/image17.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image17.jpg rename to assets/post-assets/2024-annual-report/image17.jpg diff --git a/public/assets/post-assets/2024-annual-report/image18.jpg b/assets/post-assets/2024-annual-report/image18.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image18.jpg rename to assets/post-assets/2024-annual-report/image18.jpg diff --git a/public/assets/post-assets/2024-annual-report/image19.jpg b/assets/post-assets/2024-annual-report/image19.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image19.jpg rename to assets/post-assets/2024-annual-report/image19.jpg diff --git a/public/assets/post-assets/2024-annual-report/image2.jpg b/assets/post-assets/2024-annual-report/image2.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image2.jpg rename to assets/post-assets/2024-annual-report/image2.jpg diff --git a/public/assets/post-assets/2024-annual-report/image20.png b/assets/post-assets/2024-annual-report/image20.png similarity index 100% rename from public/assets/post-assets/2024-annual-report/image20.png rename to assets/post-assets/2024-annual-report/image20.png diff --git a/public/assets/post-assets/2024-annual-report/image21.jpg b/assets/post-assets/2024-annual-report/image21.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image21.jpg rename to assets/post-assets/2024-annual-report/image21.jpg diff --git a/public/assets/post-assets/2024-annual-report/image22.jpg b/assets/post-assets/2024-annual-report/image22.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image22.jpg rename to assets/post-assets/2024-annual-report/image22.jpg diff --git a/public/assets/post-assets/2024-annual-report/image23.png b/assets/post-assets/2024-annual-report/image23.png similarity index 100% rename from public/assets/post-assets/2024-annual-report/image23.png rename to assets/post-assets/2024-annual-report/image23.png diff --git a/public/assets/post-assets/2024-annual-report/image24.jpg b/assets/post-assets/2024-annual-report/image24.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image24.jpg rename to assets/post-assets/2024-annual-report/image24.jpg diff --git a/public/assets/post-assets/2024-annual-report/image25.jpg b/assets/post-assets/2024-annual-report/image25.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image25.jpg rename to assets/post-assets/2024-annual-report/image25.jpg diff --git a/public/assets/post-assets/2024-annual-report/image26.jpg b/assets/post-assets/2024-annual-report/image26.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image26.jpg rename to assets/post-assets/2024-annual-report/image26.jpg diff --git a/public/assets/post-assets/2024-annual-report/image27.jpg b/assets/post-assets/2024-annual-report/image27.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image27.jpg rename to assets/post-assets/2024-annual-report/image27.jpg diff --git a/public/assets/post-assets/2024-annual-report/image28.jpg b/assets/post-assets/2024-annual-report/image28.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image28.jpg rename to assets/post-assets/2024-annual-report/image28.jpg diff --git a/public/assets/post-assets/2024-annual-report/image29.png b/assets/post-assets/2024-annual-report/image29.png similarity index 100% rename from public/assets/post-assets/2024-annual-report/image29.png rename to assets/post-assets/2024-annual-report/image29.png diff --git a/public/assets/post-assets/2024-annual-report/image3.jpg b/assets/post-assets/2024-annual-report/image3.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image3.jpg rename to assets/post-assets/2024-annual-report/image3.jpg diff --git a/public/assets/post-assets/2024-annual-report/image30.jpg b/assets/post-assets/2024-annual-report/image30.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image30.jpg rename to assets/post-assets/2024-annual-report/image30.jpg diff --git a/public/assets/post-assets/2024-annual-report/image31.png b/assets/post-assets/2024-annual-report/image31.png similarity index 100% rename from public/assets/post-assets/2024-annual-report/image31.png rename to assets/post-assets/2024-annual-report/image31.png diff --git a/public/assets/post-assets/2024-annual-report/image32.jpg b/assets/post-assets/2024-annual-report/image32.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image32.jpg rename to assets/post-assets/2024-annual-report/image32.jpg diff --git a/public/assets/post-assets/2024-annual-report/image33.jpg b/assets/post-assets/2024-annual-report/image33.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image33.jpg rename to assets/post-assets/2024-annual-report/image33.jpg diff --git a/public/assets/post-assets/2024-annual-report/image34.jpg b/assets/post-assets/2024-annual-report/image34.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image34.jpg rename to assets/post-assets/2024-annual-report/image34.jpg diff --git a/public/assets/post-assets/2024-annual-report/image35.jpg b/assets/post-assets/2024-annual-report/image35.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image35.jpg rename to assets/post-assets/2024-annual-report/image35.jpg diff --git a/public/assets/post-assets/2024-annual-report/image36.jpg b/assets/post-assets/2024-annual-report/image36.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image36.jpg rename to assets/post-assets/2024-annual-report/image36.jpg diff --git a/public/assets/post-assets/2024-annual-report/image37.jpg b/assets/post-assets/2024-annual-report/image37.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image37.jpg rename to assets/post-assets/2024-annual-report/image37.jpg diff --git a/public/assets/post-assets/2024-annual-report/image38.jpg b/assets/post-assets/2024-annual-report/image38.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image38.jpg rename to assets/post-assets/2024-annual-report/image38.jpg diff --git a/public/assets/post-assets/2024-annual-report/image39.jpg b/assets/post-assets/2024-annual-report/image39.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image39.jpg rename to assets/post-assets/2024-annual-report/image39.jpg diff --git a/public/assets/post-assets/2024-annual-report/image4.jpg b/assets/post-assets/2024-annual-report/image4.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image4.jpg rename to assets/post-assets/2024-annual-report/image4.jpg diff --git a/public/assets/post-assets/2024-annual-report/image40.jpg b/assets/post-assets/2024-annual-report/image40.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image40.jpg rename to assets/post-assets/2024-annual-report/image40.jpg diff --git a/public/assets/post-assets/2024-annual-report/image41.jpg b/assets/post-assets/2024-annual-report/image41.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image41.jpg rename to assets/post-assets/2024-annual-report/image41.jpg diff --git a/public/assets/post-assets/2024-annual-report/image42.jpg b/assets/post-assets/2024-annual-report/image42.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image42.jpg rename to assets/post-assets/2024-annual-report/image42.jpg diff --git a/public/assets/post-assets/2024-annual-report/image43.jpg b/assets/post-assets/2024-annual-report/image43.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image43.jpg rename to assets/post-assets/2024-annual-report/image43.jpg diff --git a/public/assets/post-assets/2024-annual-report/image44.jpg b/assets/post-assets/2024-annual-report/image44.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image44.jpg rename to assets/post-assets/2024-annual-report/image44.jpg diff --git a/public/assets/post-assets/2024-annual-report/image45.jpg b/assets/post-assets/2024-annual-report/image45.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image45.jpg rename to assets/post-assets/2024-annual-report/image45.jpg diff --git a/public/assets/post-assets/2024-annual-report/image46.jpg b/assets/post-assets/2024-annual-report/image46.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image46.jpg rename to assets/post-assets/2024-annual-report/image46.jpg diff --git a/public/assets/post-assets/2024-annual-report/image47.jpg b/assets/post-assets/2024-annual-report/image47.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image47.jpg rename to assets/post-assets/2024-annual-report/image47.jpg diff --git a/public/assets/post-assets/2024-annual-report/image48.jpg b/assets/post-assets/2024-annual-report/image48.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image48.jpg rename to assets/post-assets/2024-annual-report/image48.jpg diff --git a/public/assets/post-assets/2024-annual-report/image49.jpg b/assets/post-assets/2024-annual-report/image49.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image49.jpg rename to assets/post-assets/2024-annual-report/image49.jpg diff --git a/public/assets/post-assets/2024-annual-report/image5.png b/assets/post-assets/2024-annual-report/image5.png similarity index 100% rename from public/assets/post-assets/2024-annual-report/image5.png rename to assets/post-assets/2024-annual-report/image5.png diff --git a/public/assets/post-assets/2024-annual-report/image50.jpg b/assets/post-assets/2024-annual-report/image50.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image50.jpg rename to assets/post-assets/2024-annual-report/image50.jpg diff --git a/public/assets/post-assets/2024-annual-report/image51.png b/assets/post-assets/2024-annual-report/image51.png similarity index 100% rename from public/assets/post-assets/2024-annual-report/image51.png rename to assets/post-assets/2024-annual-report/image51.png diff --git a/public/assets/post-assets/2024-annual-report/image6.jpg b/assets/post-assets/2024-annual-report/image6.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image6.jpg rename to assets/post-assets/2024-annual-report/image6.jpg diff --git a/public/assets/post-assets/2024-annual-report/image7.jpg b/assets/post-assets/2024-annual-report/image7.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image7.jpg rename to assets/post-assets/2024-annual-report/image7.jpg diff --git a/public/assets/post-assets/2024-annual-report/image8.png b/assets/post-assets/2024-annual-report/image8.png similarity index 100% rename from public/assets/post-assets/2024-annual-report/image8.png rename to assets/post-assets/2024-annual-report/image8.png diff --git a/public/assets/post-assets/2024-annual-report/image9.jpg b/assets/post-assets/2024-annual-report/image9.jpg similarity index 100% rename from public/assets/post-assets/2024-annual-report/image9.jpg rename to assets/post-assets/2024-annual-report/image9.jpg diff --git a/public/assets/post-assets/abacus.png b/assets/post-assets/abacus.png similarity index 100% rename from public/assets/post-assets/abacus.png rename to assets/post-assets/abacus.png diff --git a/public/assets/post-assets/data.png b/assets/post-assets/data.png similarity index 100% rename from public/assets/post-assets/data.png rename to assets/post-assets/data.png diff --git a/public/assets/post-assets/debugger.png b/assets/post-assets/debugger.png similarity index 100% rename from public/assets/post-assets/debugger.png rename to assets/post-assets/debugger.png diff --git a/public/assets/post-assets/donation-banner.jpg b/assets/post-assets/donation-banner.jpg similarity index 100% rename from public/assets/post-assets/donation-banner.jpg rename to assets/post-assets/donation-banner.jpg diff --git a/public/assets/post-assets/press/ChipotleDevelopmentTeam_RedlandsCyclingClassic.jpg b/assets/post-assets/press/ChipotleDevelopmentTeam_RedlandsCyclingClassic.jpg similarity index 100% rename from public/assets/post-assets/press/ChipotleDevelopmentTeam_RedlandsCyclingClassic.jpg rename to assets/post-assets/press/ChipotleDevelopmentTeam_RedlandsCyclingClassic.jpg diff --git a/public/assets/post-assets/press/Sugar-on-a-Stick-Strawberry.png b/assets/post-assets/press/Sugar-on-a-Stick-Strawberry.png similarity index 100% rename from public/assets/post-assets/press/Sugar-on-a-Stick-Strawberry.png rename to assets/post-assets/press/Sugar-on-a-Stick-Strawberry.png diff --git a/public/assets/post-assets/press/SugarLabsPR-en.20130205.pdf b/assets/post-assets/press/SugarLabsPR-en.20130205.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR-en.20130205.pdf rename to assets/post-assets/press/SugarLabsPR-en.20130205.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR-en.20131015.pdf b/assets/post-assets/press/SugarLabsPR-en.20131015.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR-en.20131015.pdf rename to assets/post-assets/press/SugarLabsPR-en.20131015.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR-en.20140122.pdf b/assets/post-assets/press/SugarLabsPR-en.20140122.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR-en.20140122.pdf rename to assets/post-assets/press/SugarLabsPR-en.20140122.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR-es.20130205.pdf b/assets/post-assets/press/SugarLabsPR-es.20130205.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR-es.20130205.pdf rename to assets/post-assets/press/SugarLabsPR-es.20130205.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR-es.20131015.pdf b/assets/post-assets/press/SugarLabsPR-es.20131015.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR-es.20131015.pdf rename to assets/post-assets/press/SugarLabsPR-es.20131015.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR-es.20140122.pdf b/assets/post-assets/press/SugarLabsPR-es.20140122.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR-es.20140122.pdf rename to assets/post-assets/press/SugarLabsPR-es.20140122.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR-fr.20130205.pdf b/assets/post-assets/press/SugarLabsPR-fr.20130205.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR-fr.20130205.pdf rename to assets/post-assets/press/SugarLabsPR-fr.20130205.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR-fr.20131015.pdf b/assets/post-assets/press/SugarLabsPR-fr.20131015.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR-fr.20131015.pdf rename to assets/post-assets/press/SugarLabsPR-fr.20131015.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR_de_20090316.pdf b/assets/post-assets/press/SugarLabsPR_de_20090316.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR_de_20090316.pdf rename to assets/post-assets/press/SugarLabsPR_de_20090316.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR_en_20090316.pdf b/assets/post-assets/press/SugarLabsPR_en_20090316.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR_en_20090316.pdf rename to assets/post-assets/press/SugarLabsPR_en_20090316.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR_en_20090422.pdf b/assets/post-assets/press/SugarLabsPR_en_20090422.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR_en_20090422.pdf rename to assets/post-assets/press/SugarLabsPR_en_20090422.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR_es_20090316.pdf b/assets/post-assets/press/SugarLabsPR_es_20090316.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR_es_20090316.pdf rename to assets/post-assets/press/SugarLabsPR_es_20090316.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR_fr_20090316.pdf b/assets/post-assets/press/SugarLabsPR_fr_20090316.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR_fr_20090316.pdf rename to assets/post-assets/press/SugarLabsPR_fr_20090316.pdf diff --git a/public/assets/post-assets/press/SugarLabsPR_fr_20090422.pdf b/assets/post-assets/press/SugarLabsPR_fr_20090422.pdf similarity index 100% rename from public/assets/post-assets/press/SugarLabsPR_fr_20090422.pdf rename to assets/post-assets/press/SugarLabsPR_fr_20090422.pdf diff --git a/public/assets/post-assets/press/SugarLabs_GCI_2012_Winners.jpg b/assets/post-assets/press/SugarLabs_GCI_2012_Winners.jpg similarity index 100% rename from public/assets/post-assets/press/SugarLabs_GCI_2012_Winners.jpg rename to assets/post-assets/press/SugarLabs_GCI_2012_Winners.jpg diff --git a/public/assets/post-assets/press/SugarLabs_GCI_2013_Winner_Ignacio.jpg b/assets/post-assets/press/SugarLabs_GCI_2013_Winner_Ignacio.jpg similarity index 100% rename from public/assets/post-assets/press/SugarLabs_GCI_2013_Winner_Ignacio.jpg rename to assets/post-assets/press/SugarLabs_GCI_2013_Winner_Ignacio.jpg diff --git a/public/assets/post-assets/press/SugarLabs_GCI_2013_Winner_Jorge.jpg b/assets/post-assets/press/SugarLabs_GCI_2013_Winner_Jorge.jpg similarity index 100% rename from public/assets/post-assets/press/SugarLabs_GCI_2013_Winner_Jorge.jpg rename to assets/post-assets/press/SugarLabs_GCI_2013_Winner_Jorge.jpg diff --git a/public/assets/post-assets/press/caacupe-turtleartday-captura-pantalla.png b/assets/post-assets/press/caacupe-turtleartday-captura-pantalla.png similarity index 100% rename from public/assets/post-assets/press/caacupe-turtleartday-captura-pantalla.png rename to assets/post-assets/press/caacupe-turtleartday-captura-pantalla.png diff --git a/public/assets/post-assets/press/caacupe-turtleartday.png b/assets/post-assets/press/caacupe-turtleartday.png similarity index 100% rename from public/assets/post-assets/press/caacupe-turtleartday.png rename to assets/post-assets/press/caacupe-turtleartday.png diff --git a/public/assets/post-assets/press/migrate.py b/assets/post-assets/press/migrate.py similarity index 100% rename from public/assets/post-assets/press/migrate.py rename to assets/post-assets/press/migrate.py diff --git a/public/assets/post-assets/press/press.xml b/assets/post-assets/press/press.xml similarity index 100% rename from public/assets/post-assets/press/press.xml rename to assets/post-assets/press/press.xml diff --git a/public/assets/post-assets/press/sugar-on-a-stick.jpg b/assets/post-assets/press/sugar-on-a-stick.jpg similarity index 100% rename from public/assets/post-assets/press/sugar-on-a-stick.jpg rename to assets/post-assets/press/sugar-on-a-stick.jpg diff --git a/public/assets/post-assets/stories/james.jpg b/assets/post-assets/stories/james.jpg similarity index 100% rename from public/assets/post-assets/stories/james.jpg rename to assets/post-assets/stories/james.jpg diff --git a/public/assets/post-assets/stories/process.jpg b/assets/post-assets/stories/process.jpg similarity index 100% rename from public/assets/post-assets/stories/process.jpg rename to assets/post-assets/stories/process.jpg diff --git a/public/assets/post-assets/stories/student1.jpg b/assets/post-assets/stories/student1.jpg similarity index 100% rename from public/assets/post-assets/stories/student1.jpg rename to assets/post-assets/stories/student1.jpg diff --git a/public/assets/post-assets/stories/student4.jpg b/assets/post-assets/stories/student4.jpg similarity index 100% rename from public/assets/post-assets/stories/student4.jpg rename to assets/post-assets/stories/student4.jpg diff --git a/public/assets/post-assets/stories/student5.jpg b/assets/post-assets/stories/student5.jpg similarity index 100% rename from public/assets/post-assets/stories/student5.jpg rename to assets/post-assets/stories/student5.jpg diff --git a/public/assets/post-assets/stories/student6.jpg b/assets/post-assets/stories/student6.jpg similarity index 100% rename from public/assets/post-assets/stories/student6.jpg rename to assets/post-assets/stories/student6.jpg diff --git a/public/assets/post-assets/stories/students2.jpg b/assets/post-assets/stories/students2.jpg similarity index 100% rename from public/assets/post-assets/stories/students2.jpg rename to assets/post-assets/stories/students2.jpg diff --git a/public/assets/post-assets/stories/students3.jpg b/assets/post-assets/stories/students3.jpg similarity index 100% rename from public/assets/post-assets/stories/students3.jpg rename to assets/post-assets/stories/students3.jpg diff --git a/public/assets/post-assets/sugarlabs_soas_usb-two.jpg b/assets/post-assets/sugarlabs_soas_usb-two.jpg similarity index 100% rename from public/assets/post-assets/sugarlabs_soas_usb-two.jpg rename to assets/post-assets/sugarlabs_soas_usb-two.jpg diff --git a/public/assets/social/facebook.svg b/assets/social/facebook.svg similarity index 100% rename from public/assets/social/facebook.svg rename to assets/social/facebook.svg diff --git a/public/assets/social/github.svg b/assets/social/github.svg similarity index 100% rename from public/assets/social/github.svg rename to assets/social/github.svg diff --git a/public/assets/social/instagram.svg b/assets/social/instagram.svg similarity index 100% rename from public/assets/social/instagram.svg rename to assets/social/instagram.svg diff --git a/public/assets/social/linkedin.svg b/assets/social/linkedin.svg similarity index 100% rename from public/assets/social/linkedin.svg rename to assets/social/linkedin.svg diff --git a/public/assets/social/mastodon.svg b/assets/social/mastodon.svg similarity index 100% rename from public/assets/social/mastodon.svg rename to assets/social/mastodon.svg diff --git a/public/assets/social/medium.svg b/assets/social/medium.svg similarity index 100% rename from public/assets/social/medium.svg rename to assets/social/medium.svg diff --git a/public/assets/social/whatsapp.svg b/assets/social/whatsapp.svg similarity index 100% rename from public/assets/social/whatsapp.svg rename to assets/social/whatsapp.svg diff --git a/public/assets/social/x.svg b/assets/social/x.svg similarity index 100% rename from public/assets/social/x.svg rename to assets/social/x.svg diff --git a/public/assets/social/youtube.svg b/assets/social/youtube.svg similarity index 100% rename from public/assets/social/youtube.svg rename to assets/social/youtube.svg diff --git a/public/assets/tax-filings/2019-Form-990EZ.pdf b/assets/tax-filings/2019-Form-990EZ.pdf similarity index 100% rename from public/assets/tax-filings/2019-Form-990EZ.pdf rename to assets/tax-filings/2019-Form-990EZ.pdf diff --git a/public/assets/tax-filings/2020-Form-990EZ.pdf b/assets/tax-filings/2020-Form-990EZ.pdf similarity index 100% rename from public/assets/tax-filings/2020-Form-990EZ.pdf rename to assets/tax-filings/2020-Form-990EZ.pdf diff --git a/public/assets/tax-filings/2021-Form-990EZ.pdf b/assets/tax-filings/2021-Form-990EZ.pdf similarity index 100% rename from public/assets/tax-filings/2021-Form-990EZ.pdf rename to assets/tax-filings/2021-Form-990EZ.pdf diff --git a/public/assets/tax-filings/2022-Form-990EZ.pdf b/assets/tax-filings/2022-Form-990EZ.pdf similarity index 100% rename from public/assets/tax-filings/2022-Form-990EZ.pdf rename to assets/tax-filings/2022-Form-990EZ.pdf diff --git a/public/assets/tax-filings/2023-Form-990EZ.pdf b/assets/tax-filings/2023-Form-990EZ.pdf similarity index 100% rename from public/assets/tax-filings/2023-Form-990EZ.pdf rename to assets/tax-filings/2023-Form-990EZ.pdf diff --git a/assets/vendor-19NJoZqN.js b/assets/vendor-19NJoZqN.js new file mode 100644 index 00000000..a38364c3 --- /dev/null +++ b/assets/vendor-19NJoZqN.js @@ -0,0 +1,274 @@ +function Rl(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var xm={exports:{}},vo={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Nb;function qR(){if(Nb)return vo;Nb=1;var e=Symbol.for("react.transitional.element"),t=Symbol.for("react.fragment");function n(i,u,o){var l=null;if(o!==void 0&&(l=""+o),u.key!==void 0&&(l=""+u.key),"key"in u){o={};for(var f in u)f!=="key"&&(o[f]=u[f])}else o=u;return u=o.ref,{$$typeof:e,type:i,key:l,ref:u!==void 0?u:null,props:o}}return vo.Fragment=t,vo.jsx=n,vo.jsxs=n,vo}var kb;function YR(){return kb||(kb=1,xm.exports=qR()),xm.exports}var Br=YR(),Rm={exports:{}},et={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Lb;function GR(){if(Lb)return et;Lb=1;var e=Symbol.for("react.transitional.element"),t=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),i=Symbol.for("react.strict_mode"),u=Symbol.for("react.profiler"),o=Symbol.for("react.consumer"),l=Symbol.for("react.context"),f=Symbol.for("react.forward_ref"),d=Symbol.for("react.suspense"),h=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),g=Symbol.iterator;function b(S){return S===null||typeof S!="object"?null:(S=g&&S[g]||S["@@iterator"],typeof S=="function"?S:null)}var T={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},A=Object.assign,_={};function O(S,ne,ge){this.props=S,this.context=ne,this.refs=_,this.updater=ge||T}O.prototype.isReactComponent={},O.prototype.setState=function(S,ne){if(typeof S!="object"&&typeof S!="function"&&S!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,S,ne,"setState")},O.prototype.forceUpdate=function(S){this.updater.enqueueForceUpdate(this,S,"forceUpdate")};function C(){}C.prototype=O.prototype;function N(S,ne,ge){this.props=S,this.context=ne,this.refs=_,this.updater=ge||T}var R=N.prototype=new C;R.constructor=N,A(R,O.prototype),R.isPureReactComponent=!0;var Y=Array.isArray,M={H:null,A:null,T:null,S:null,V:null},v=Object.prototype.hasOwnProperty;function J(S,ne,ge,w,Te,Re){return ge=Re.ref,{$$typeof:e,type:S,key:ne,ref:ge!==void 0?ge:null,props:Re}}function P(S,ne){return J(S.type,ne,void 0,void 0,void 0,S.props)}function q(S){return typeof S=="object"&&S!==null&&S.$$typeof===e}function z(S){var ne={"=":"=0",":":"=2"};return"$"+S.replace(/[=:]/g,function(ge){return ne[ge]})}var V=/\/+/g;function F(S,ne){return typeof S=="object"&&S!==null&&S.key!=null?z(""+S.key):ne.toString(36)}function $(){}function Z(S){switch(S.status){case"fulfilled":return S.value;case"rejected":throw S.reason;default:switch(typeof S.status=="string"?S.then($,$):(S.status="pending",S.then(function(ne){S.status==="pending"&&(S.status="fulfilled",S.value=ne)},function(ne){S.status==="pending"&&(S.status="rejected",S.reason=ne)})),S.status){case"fulfilled":return S.value;case"rejected":throw S.reason}}throw S}function L(S,ne,ge,w,Te){var Re=typeof S;(Re==="undefined"||Re==="boolean")&&(S=null);var xe=!1;if(S===null)xe=!0;else switch(Re){case"bigint":case"string":case"number":xe=!0;break;case"object":switch(S.$$typeof){case e:case t:xe=!0;break;case p:return xe=S._init,L(xe(S._payload),ne,ge,w,Te)}}if(xe)return Te=Te(S),xe=w===""?"."+F(S,0):w,Y(Te)?(ge="",xe!=null&&(ge=xe.replace(V,"$&/")+"/"),L(Te,ne,ge,"",function(Nt){return Nt})):Te!=null&&(q(Te)&&(Te=P(Te,ge+(Te.key==null||S&&S.key===Te.key?"":(""+Te.key).replace(V,"$&/")+"/")+xe)),ne.push(Te)),1;xe=0;var We=w===""?".":w+":";if(Y(S))for(var Qe=0;Qe<S.length;Qe++)w=S[Qe],Re=We+F(w,Qe),xe+=L(w,ne,ge,Re,Te);else if(Qe=b(S),typeof Qe=="function")for(S=Qe.call(S),Qe=0;!(w=S.next()).done;)w=w.value,Re=We+F(w,Qe++),xe+=L(w,ne,ge,Re,Te);else if(Re==="object"){if(typeof S.then=="function")return L(Z(S),ne,ge,w,Te);throw ne=String(S),Error("Objects are not valid as a React child (found: "+(ne==="[object Object]"?"object with keys {"+Object.keys(S).join(", ")+"}":ne)+"). If you meant to render a collection of children, use an array instead.")}return xe}function B(S,ne,ge){if(S==null)return S;var w=[],Te=0;return L(S,w,"","",function(Re){return ne.call(ge,Re,Te++)}),w}function K(S){if(S._status===-1){var ne=S._result;ne=ne(),ne.then(function(ge){(S._status===0||S._status===-1)&&(S._status=1,S._result=ge)},function(ge){(S._status===0||S._status===-1)&&(S._status=2,S._result=ge)}),S._status===-1&&(S._status=0,S._result=ne)}if(S._status===1)return S._result.default;throw S._result}var Q=typeof reportError=="function"?reportError:function(S){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var ne=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof S=="object"&&S!==null&&typeof S.message=="string"?String(S.message):String(S),error:S});if(!window.dispatchEvent(ne))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",S);return}console.error(S)};function _e(){}return et.Children={map:B,forEach:function(S,ne,ge){B(S,function(){ne.apply(this,arguments)},ge)},count:function(S){var ne=0;return B(S,function(){ne++}),ne},toArray:function(S){return B(S,function(ne){return ne})||[]},only:function(S){if(!q(S))throw Error("React.Children.only expected to receive a single React element child.");return S}},et.Component=O,et.Fragment=n,et.Profiler=u,et.PureComponent=N,et.StrictMode=i,et.Suspense=d,et.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=M,et.__COMPILER_RUNTIME={__proto__:null,c:function(S){return M.H.useMemoCache(S)}},et.cache=function(S){return function(){return S.apply(null,arguments)}},et.cloneElement=function(S,ne,ge){if(S==null)throw Error("The argument must be a React element, but you passed "+S+".");var w=A({},S.props),Te=S.key,Re=void 0;if(ne!=null)for(xe in ne.ref!==void 0&&(Re=void 0),ne.key!==void 0&&(Te=""+ne.key),ne)!v.call(ne,xe)||xe==="key"||xe==="__self"||xe==="__source"||xe==="ref"&&ne.ref===void 0||(w[xe]=ne[xe]);var xe=arguments.length-2;if(xe===1)w.children=ge;else if(1<xe){for(var We=Array(xe),Qe=0;Qe<xe;Qe++)We[Qe]=arguments[Qe+2];w.children=We}return J(S.type,Te,void 0,void 0,Re,w)},et.createContext=function(S){return S={$$typeof:l,_currentValue:S,_currentValue2:S,_threadCount:0,Provider:null,Consumer:null},S.Provider=S,S.Consumer={$$typeof:o,_context:S},S},et.createElement=function(S,ne,ge){var w,Te={},Re=null;if(ne!=null)for(w in ne.key!==void 0&&(Re=""+ne.key),ne)v.call(ne,w)&&w!=="key"&&w!=="__self"&&w!=="__source"&&(Te[w]=ne[w]);var xe=arguments.length-2;if(xe===1)Te.children=ge;else if(1<xe){for(var We=Array(xe),Qe=0;Qe<xe;Qe++)We[Qe]=arguments[Qe+2];Te.children=We}if(S&&S.defaultProps)for(w in xe=S.defaultProps,xe)Te[w]===void 0&&(Te[w]=xe[w]);return J(S,Re,void 0,void 0,null,Te)},et.createRef=function(){return{current:null}},et.forwardRef=function(S){return{$$typeof:f,render:S}},et.isValidElement=q,et.lazy=function(S){return{$$typeof:p,_payload:{_status:-1,_result:S},_init:K}},et.memo=function(S,ne){return{$$typeof:h,type:S,compare:ne===void 0?null:ne}},et.startTransition=function(S){var ne=M.T,ge={};M.T=ge;try{var w=S(),Te=M.S;Te!==null&&Te(ge,w),typeof w=="object"&&w!==null&&typeof w.then=="function"&&w.then(_e,Q)}catch(Re){Q(Re)}finally{M.T=ne}},et.unstable_useCacheRefresh=function(){return M.H.useCacheRefresh()},et.use=function(S){return M.H.use(S)},et.useActionState=function(S,ne,ge){return M.H.useActionState(S,ne,ge)},et.useCallback=function(S,ne){return M.H.useCallback(S,ne)},et.useContext=function(S){return M.H.useContext(S)},et.useDebugValue=function(){},et.useDeferredValue=function(S,ne){return M.H.useDeferredValue(S,ne)},et.useEffect=function(S,ne,ge){var w=M.H;if(typeof ge=="function")throw Error("useEffect CRUD overload is not enabled in this build of React.");return w.useEffect(S,ne)},et.useId=function(){return M.H.useId()},et.useImperativeHandle=function(S,ne,ge){return M.H.useImperativeHandle(S,ne,ge)},et.useInsertionEffect=function(S,ne){return M.H.useInsertionEffect(S,ne)},et.useLayoutEffect=function(S,ne){return M.H.useLayoutEffect(S,ne)},et.useMemo=function(S,ne){return M.H.useMemo(S,ne)},et.useOptimistic=function(S,ne){return M.H.useOptimistic(S,ne)},et.useReducer=function(S,ne,ge){return M.H.useReducer(S,ne,ge)},et.useRef=function(S){return M.H.useRef(S)},et.useState=function(S){return M.H.useState(S)},et.useSyncExternalStore=function(S,ne,ge){return M.H.useSyncExternalStore(S,ne,ge)},et.useTransition=function(){return M.H.useTransition()},et.version="19.1.0",et}var Mb;function Ca(){return Mb||(Mb=1,Rm.exports=GR()),Rm.exports}var W=Ca();const wj=Rl(W);var wm={exports:{}},Co={},Om={exports:{}},Nm={};/** + * @license React + * scheduler.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Ib;function XR(){return Ib||(Ib=1,function(e){function t(B,K){var Q=B.length;B.push(K);e:for(;0<Q;){var _e=Q-1>>>1,S=B[_e];if(0<u(S,K))B[_e]=K,B[Q]=S,Q=_e;else break e}}function n(B){return B.length===0?null:B[0]}function i(B){if(B.length===0)return null;var K=B[0],Q=B.pop();if(Q!==K){B[0]=Q;e:for(var _e=0,S=B.length,ne=S>>>1;_e<ne;){var ge=2*(_e+1)-1,w=B[ge],Te=ge+1,Re=B[Te];if(0>u(w,Q))Te<S&&0>u(Re,w)?(B[_e]=Re,B[Te]=Q,_e=Te):(B[_e]=w,B[ge]=Q,_e=ge);else if(Te<S&&0>u(Re,Q))B[_e]=Re,B[Te]=Q,_e=Te;else break e}}return K}function u(B,K){var Q=B.sortIndex-K.sortIndex;return Q!==0?Q:B.id-K.id}if(e.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var o=performance;e.unstable_now=function(){return o.now()}}else{var l=Date,f=l.now();e.unstable_now=function(){return l.now()-f}}var d=[],h=[],p=1,g=null,b=3,T=!1,A=!1,_=!1,O=!1,C=typeof setTimeout=="function"?setTimeout:null,N=typeof clearTimeout=="function"?clearTimeout:null,R=typeof setImmediate<"u"?setImmediate:null;function Y(B){for(var K=n(h);K!==null;){if(K.callback===null)i(h);else if(K.startTime<=B)i(h),K.sortIndex=K.expirationTime,t(d,K);else break;K=n(h)}}function M(B){if(_=!1,Y(B),!A)if(n(d)!==null)A=!0,v||(v=!0,F());else{var K=n(h);K!==null&&L(M,K.startTime-B)}}var v=!1,J=-1,P=5,q=-1;function z(){return O?!0:!(e.unstable_now()-q<P)}function V(){if(O=!1,v){var B=e.unstable_now();q=B;var K=!0;try{e:{A=!1,_&&(_=!1,N(J),J=-1),T=!0;var Q=b;try{t:{for(Y(B),g=n(d);g!==null&&!(g.expirationTime>B&&z());){var _e=g.callback;if(typeof _e=="function"){g.callback=null,b=g.priorityLevel;var S=_e(g.expirationTime<=B);if(B=e.unstable_now(),typeof S=="function"){g.callback=S,Y(B),K=!0;break t}g===n(d)&&i(d),Y(B)}else i(d);g=n(d)}if(g!==null)K=!0;else{var ne=n(h);ne!==null&&L(M,ne.startTime-B),K=!1}}break e}finally{g=null,b=Q,T=!1}K=void 0}}finally{K?F():v=!1}}}var F;if(typeof R=="function")F=function(){R(V)};else if(typeof MessageChannel<"u"){var $=new MessageChannel,Z=$.port2;$.port1.onmessage=V,F=function(){Z.postMessage(null)}}else F=function(){C(V,0)};function L(B,K){J=C(function(){B(e.unstable_now())},K)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(B){B.callback=null},e.unstable_forceFrameRate=function(B){0>B||125<B?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):P=0<B?Math.floor(1e3/B):5},e.unstable_getCurrentPriorityLevel=function(){return b},e.unstable_next=function(B){switch(b){case 1:case 2:case 3:var K=3;break;default:K=b}var Q=b;b=K;try{return B()}finally{b=Q}},e.unstable_requestPaint=function(){O=!0},e.unstable_runWithPriority=function(B,K){switch(B){case 1:case 2:case 3:case 4:case 5:break;default:B=3}var Q=b;b=B;try{return K()}finally{b=Q}},e.unstable_scheduleCallback=function(B,K,Q){var _e=e.unstable_now();switch(typeof Q=="object"&&Q!==null?(Q=Q.delay,Q=typeof Q=="number"&&0<Q?_e+Q:_e):Q=_e,B){case 1:var S=-1;break;case 2:S=250;break;case 5:S=1073741823;break;case 4:S=1e4;break;default:S=5e3}return S=Q+S,B={id:p++,callback:K,priorityLevel:B,startTime:Q,expirationTime:S,sortIndex:-1},Q>_e?(B.sortIndex=Q,t(h,B),n(d)===null&&B===n(h)&&(_?(N(J),J=-1):_=!0,L(M,Q-_e))):(B.sortIndex=S,t(d,B),A||T||(A=!0,v||(v=!0,F()))),B},e.unstable_shouldYield=z,e.unstable_wrapCallback=function(B){var K=b;return function(){var Q=b;b=K;try{return B.apply(this,arguments)}finally{b=Q}}}}(Nm)),Nm}var Pb;function KR(){return Pb||(Pb=1,Om.exports=XR()),Om.exports}var km={exports:{}},kn={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Fb;function WR(){if(Fb)return kn;Fb=1;var e=Ca();function t(d){var h="https://react.dev/errors/"+d;if(1<arguments.length){h+="?args[]="+encodeURIComponent(arguments[1]);for(var p=2;p<arguments.length;p++)h+="&args[]="+encodeURIComponent(arguments[p])}return"Minified React error #"+d+"; visit "+h+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function n(){}var i={d:{f:n,r:function(){throw Error(t(522))},D:n,C:n,L:n,m:n,X:n,S:n,M:n},p:0,findDOMNode:null},u=Symbol.for("react.portal");function o(d,h,p){var g=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:u,key:g==null?null:""+g,children:d,containerInfo:h,implementation:p}}var l=e.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function f(d,h){if(d==="font")return"";if(typeof h=="string")return h==="use-credentials"?h:""}return kn.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=i,kn.createPortal=function(d,h){var p=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!h||h.nodeType!==1&&h.nodeType!==9&&h.nodeType!==11)throw Error(t(299));return o(d,h,null,p)},kn.flushSync=function(d){var h=l.T,p=i.p;try{if(l.T=null,i.p=2,d)return d()}finally{l.T=h,i.p=p,i.d.f()}},kn.preconnect=function(d,h){typeof d=="string"&&(h?(h=h.crossOrigin,h=typeof h=="string"?h==="use-credentials"?h:"":void 0):h=null,i.d.C(d,h))},kn.prefetchDNS=function(d){typeof d=="string"&&i.d.D(d)},kn.preinit=function(d,h){if(typeof d=="string"&&h&&typeof h.as=="string"){var p=h.as,g=f(p,h.crossOrigin),b=typeof h.integrity=="string"?h.integrity:void 0,T=typeof h.fetchPriority=="string"?h.fetchPriority:void 0;p==="style"?i.d.S(d,typeof h.precedence=="string"?h.precedence:void 0,{crossOrigin:g,integrity:b,fetchPriority:T}):p==="script"&&i.d.X(d,{crossOrigin:g,integrity:b,fetchPriority:T,nonce:typeof h.nonce=="string"?h.nonce:void 0})}},kn.preinitModule=function(d,h){if(typeof d=="string")if(typeof h=="object"&&h!==null){if(h.as==null||h.as==="script"){var p=f(h.as,h.crossOrigin);i.d.M(d,{crossOrigin:p,integrity:typeof h.integrity=="string"?h.integrity:void 0,nonce:typeof h.nonce=="string"?h.nonce:void 0})}}else h==null&&i.d.M(d)},kn.preload=function(d,h){if(typeof d=="string"&&typeof h=="object"&&h!==null&&typeof h.as=="string"){var p=h.as,g=f(p,h.crossOrigin);i.d.L(d,p,{crossOrigin:g,integrity:typeof h.integrity=="string"?h.integrity:void 0,nonce:typeof h.nonce=="string"?h.nonce:void 0,type:typeof h.type=="string"?h.type:void 0,fetchPriority:typeof h.fetchPriority=="string"?h.fetchPriority:void 0,referrerPolicy:typeof h.referrerPolicy=="string"?h.referrerPolicy:void 0,imageSrcSet:typeof h.imageSrcSet=="string"?h.imageSrcSet:void 0,imageSizes:typeof h.imageSizes=="string"?h.imageSizes:void 0,media:typeof h.media=="string"?h.media:void 0})}},kn.preloadModule=function(d,h){if(typeof d=="string")if(h){var p=f(h.as,h.crossOrigin);i.d.m(d,{as:typeof h.as=="string"&&h.as!=="script"?h.as:void 0,crossOrigin:p,integrity:typeof h.integrity=="string"?h.integrity:void 0})}else i.d.m(d)},kn.requestFormReset=function(d){i.d.r(d)},kn.unstable_batchedUpdates=function(d,h){return d(h)},kn.useFormState=function(d,h,p){return l.H.useFormState(d,h,p)},kn.useFormStatus=function(){return l.H.useHostTransitionStatus()},kn.version="19.1.0",kn}var Bb;function B2(){if(Bb)return km.exports;Bb=1;function e(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}return e(),km.exports=WR(),km.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Ub;function QR(){if(Ub)return Co;Ub=1;var e=KR(),t=Ca(),n=B2();function i(r){var a="https://react.dev/errors/"+r;if(1<arguments.length){a+="?args[]="+encodeURIComponent(arguments[1]);for(var s=2;s<arguments.length;s++)a+="&args[]="+encodeURIComponent(arguments[s])}return"Minified React error #"+r+"; visit "+a+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function u(r){return!(!r||r.nodeType!==1&&r.nodeType!==9&&r.nodeType!==11)}function o(r){var a=r,s=r;if(r.alternate)for(;a.return;)a=a.return;else{r=a;do a=r,(a.flags&4098)!==0&&(s=a.return),r=a.return;while(r)}return a.tag===3?s:null}function l(r){if(r.tag===13){var a=r.memoizedState;if(a===null&&(r=r.alternate,r!==null&&(a=r.memoizedState)),a!==null)return a.dehydrated}return null}function f(r){if(o(r)!==r)throw Error(i(188))}function d(r){var a=r.alternate;if(!a){if(a=o(r),a===null)throw Error(i(188));return a!==r?null:r}for(var s=r,c=a;;){var m=s.return;if(m===null)break;var E=m.alternate;if(E===null){if(c=m.return,c!==null){s=c;continue}break}if(m.child===E.child){for(E=m.child;E;){if(E===s)return f(m),r;if(E===c)return f(m),a;E=E.sibling}throw Error(i(188))}if(s.return!==c.return)s=m,c=E;else{for(var D=!1,x=m.child;x;){if(x===s){D=!0,s=m,c=E;break}if(x===c){D=!0,c=m,s=E;break}x=x.sibling}if(!D){for(x=E.child;x;){if(x===s){D=!0,s=E,c=m;break}if(x===c){D=!0,c=E,s=m;break}x=x.sibling}if(!D)throw Error(i(189))}}if(s.alternate!==c)throw Error(i(190))}if(s.tag!==3)throw Error(i(188));return s.stateNode.current===s?r:a}function h(r){var a=r.tag;if(a===5||a===26||a===27||a===6)return r;for(r=r.child;r!==null;){if(a=h(r),a!==null)return a;r=r.sibling}return null}var p=Object.assign,g=Symbol.for("react.element"),b=Symbol.for("react.transitional.element"),T=Symbol.for("react.portal"),A=Symbol.for("react.fragment"),_=Symbol.for("react.strict_mode"),O=Symbol.for("react.profiler"),C=Symbol.for("react.provider"),N=Symbol.for("react.consumer"),R=Symbol.for("react.context"),Y=Symbol.for("react.forward_ref"),M=Symbol.for("react.suspense"),v=Symbol.for("react.suspense_list"),J=Symbol.for("react.memo"),P=Symbol.for("react.lazy"),q=Symbol.for("react.activity"),z=Symbol.for("react.memo_cache_sentinel"),V=Symbol.iterator;function F(r){return r===null||typeof r!="object"?null:(r=V&&r[V]||r["@@iterator"],typeof r=="function"?r:null)}var $=Symbol.for("react.client.reference");function Z(r){if(r==null)return null;if(typeof r=="function")return r.$$typeof===$?null:r.displayName||r.name||null;if(typeof r=="string")return r;switch(r){case A:return"Fragment";case O:return"Profiler";case _:return"StrictMode";case M:return"Suspense";case v:return"SuspenseList";case q:return"Activity"}if(typeof r=="object")switch(r.$$typeof){case T:return"Portal";case R:return(r.displayName||"Context")+".Provider";case N:return(r._context.displayName||"Context")+".Consumer";case Y:var a=r.render;return r=r.displayName,r||(r=a.displayName||a.name||"",r=r!==""?"ForwardRef("+r+")":"ForwardRef"),r;case J:return a=r.displayName||null,a!==null?a:Z(r.type)||"Memo";case P:a=r._payload,r=r._init;try{return Z(r(a))}catch{}}return null}var L=Array.isArray,B=t.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,K=n.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,Q={pending:!1,data:null,method:null,action:null},_e=[],S=-1;function ne(r){return{current:r}}function ge(r){0>S||(r.current=_e[S],_e[S]=null,S--)}function w(r,a){S++,_e[S]=r.current,r.current=a}var Te=ne(null),Re=ne(null),xe=ne(null),We=ne(null);function Qe(r,a){switch(w(xe,a),w(Re,r),w(Te,null),a.nodeType){case 9:case 11:r=(r=a.documentElement)&&(r=r.namespaceURI)?ab(r):0;break;default:if(r=a.tagName,a=a.namespaceURI)a=ab(a),r=ub(a,r);else switch(r){case"svg":r=1;break;case"math":r=2;break;default:r=0}}ge(Te),w(Te,r)}function Nt(){ge(Te),ge(Re),ge(xe)}function mt(r){r.memoizedState!==null&&w(We,r);var a=Te.current,s=ub(a,r.type);a!==s&&(w(Re,r),w(Te,s))}function qt(r){Re.current===r&&(ge(Te),ge(Re)),We.current===r&&(ge(We),bo._currentValue=Q)}var ln=Object.prototype.hasOwnProperty,Ar=e.unstable_scheduleCallback,tn=e.unstable_cancelCallback,ni=e.unstable_shouldYield,ri=e.unstable_requestPaint,Yt=e.unstable_now,ii=e.unstable_getCurrentPriorityLevel,Sr=e.unstable_ImmediatePriority,ai=e.unstable_UserBlockingPriority,jr=e.unstable_NormalPriority,ur=e.unstable_LowPriority,Yn=e.unstable_IdlePriority,Dr=e.log,Gn=e.unstable_setDisableYieldValue,le=null,Ee=null;function Pe(r){if(typeof Dr=="function"&&Gn(r),Ee&&typeof Ee.setStrictMode=="function")try{Ee.setStrictMode(le,r)}catch{}}var ze=Math.clz32?Math.clz32:Cn,ht=Math.log,Ft=Math.LN2;function Cn(r){return r>>>=0,r===0?32:31-(ht(r)/Ft|0)|0}var Wt=256,Gt=4194304;function Qt(r){var a=r&42;if(a!==0)return a;switch(r&-r){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return r&4194048;case 4194304:case 8388608:case 16777216:case 33554432:return r&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return r}}function Bt(r,a,s){var c=r.pendingLanes;if(c===0)return 0;var m=0,E=r.suspendedLanes,D=r.pingedLanes;r=r.warmLanes;var x=c&134217727;return x!==0?(c=x&~E,c!==0?m=Qt(c):(D&=x,D!==0?m=Qt(D):s||(s=x&~r,s!==0&&(m=Qt(s))))):(x=c&~E,x!==0?m=Qt(x):D!==0?m=Qt(D):s||(s=c&~r,s!==0&&(m=Qt(s)))),m===0?0:a!==0&&a!==m&&(a&E)===0&&(E=m&-m,s=a&-a,E>=s||E===32&&(s&4194048)!==0)?a:m}function nn(r,a){return(r.pendingLanes&~(r.suspendedLanes&~r.pingedLanes)&a)===0}function On(r,a){switch(r){case 1:case 2:case 4:case 8:case 64:return a+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return a+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function qr(){var r=Wt;return Wt<<=1,(Wt&4194048)===0&&(Wt=256),r}function Ti(){var r=Gt;return Gt<<=1,(Gt&62914560)===0&&(Gt=4194304),r}function Vi(r){for(var a=[],s=0;31>s;s++)a.push(r);return a}function sr(r,a){r.pendingLanes|=a,a!==268435456&&(r.suspendedLanes=0,r.pingedLanes=0,r.warmLanes=0)}function gu(r,a,s,c,m,E){var D=r.pendingLanes;r.pendingLanes=s,r.suspendedLanes=0,r.pingedLanes=0,r.warmLanes=0,r.expiredLanes&=s,r.entangledLanes&=s,r.errorRecoveryDisabledLanes&=s,r.shellSuspendCounter=0;var x=r.entanglements,H=r.expirationTimes,ae=r.hiddenUpdates;for(s=D&~s;0<s;){var de=31-ze(s),me=1<<de;x[de]=0,H[de]=-1;var ue=ae[de];if(ue!==null)for(ae[de]=null,de=0;de<ue.length;de++){var oe=ue[de];oe!==null&&(oe.lane&=-536870913)}s&=~me}c!==0&&Ai(r,c,0),E!==0&&m===0&&r.tag!==0&&(r.suspendedLanes|=E&~(D&~a))}function Ai(r,a,s){r.pendingLanes|=a,r.suspendedLanes&=~a;var c=31-ze(a);r.entangledLanes|=a,r.entanglements[c]=r.entanglements[c]|1073741824|s&4194090}function kt(r,a){var s=r.entangledLanes|=a;for(r=r.entanglements;s;){var c=31-ze(s),m=1<<c;m&a|r[c]&a&&(r[c]|=a),s&=~m}}function vr(r){switch(r){case 2:r=1;break;case 8:r=4;break;case 32:r=16;break;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:r=128;break;case 268435456:r=134217728;break;default:r=0}return r}function Oa(r){return r&=-r,2<r?8<r?(r&134217727)!==0?32:268435456:8:2}function j(){var r=K.p;return r!==0?r:(r=window.event,r===void 0?32:Cb(r.type))}function te(r,a){var s=K.p;try{return K.p=r,a()}finally{K.p=s}}var se=Math.random().toString(36).slice(2),pe="__reactFiber$"+se,Ce="__reactProps$"+se,we="__reactContainer$"+se,Fe="__reactEvents$"+se,Ne="__reactListeners$"+se,Be="__reactHandles$"+se,ke="__reactResources$"+se,je="__reactMarker$"+se;function Ue(r){delete r[pe],delete r[Ce],delete r[Fe],delete r[Ne],delete r[Be]}function Ge(r){var a=r[pe];if(a)return a;for(var s=r.parentNode;s;){if(a=s[we]||s[pe]){if(s=a.alternate,a.child!==null||s!==null&&s.child!==null)for(r=cb(r);r!==null;){if(s=r[pe])return s;r=cb(r)}return a}r=s,s=r.parentNode}return null}function dt(r){if(r=r[pe]||r[we]){var a=r.tag;if(a===5||a===6||a===13||a===26||a===27||a===3)return r}return null}function Dt(r){var a=r.tag;if(a===5||a===26||a===27||a===6)return r.stateNode;throw Error(i(33))}function Lt(r){var a=r[ke];return a||(a=r[ke]={hoistableStyles:new Map,hoistableScripts:new Map}),a}function pt(r){r[je]=!0}var Se=new Set,G={};function ye(r,a){Oe(r,a),Oe(r+"Capture",a)}function Oe(r,a){for(G[r]=a,r=0;r<a.length;r++)Se.add(a[r])}var rt=RegExp("^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$"),Ut={},vt={};function cn(r){return ln.call(vt,r)?!0:ln.call(Ut,r)?!1:rt.test(r)?vt[r]=!0:(Ut[r]=!0,!1)}function $t(r,a,s){if(cn(a))if(s===null)r.removeAttribute(a);else{switch(typeof s){case"undefined":case"function":case"symbol":r.removeAttribute(a);return;case"boolean":var c=a.toLowerCase().slice(0,5);if(c!=="data-"&&c!=="aria-"){r.removeAttribute(a);return}}r.setAttribute(a,""+s)}}function Bn(r,a,s){if(s===null)r.removeAttribute(a);else{switch(typeof s){case"undefined":case"function":case"symbol":case"boolean":r.removeAttribute(a);return}r.setAttribute(a,""+s)}}function $e(r,a,s,c){if(c===null)r.removeAttribute(s);else{switch(typeof c){case"undefined":case"function":case"symbol":case"boolean":r.removeAttribute(s);return}r.setAttributeNS(a,s,""+c)}}var yt,Xn;function Kn(r){if(yt===void 0)try{throw Error()}catch(s){var a=s.stack.trim().match(/\n( *(at )?)/);yt=a&&a[1]||"",Xn=-1<s.stack.indexOf(` + at`)?" (<anonymous>)":-1<s.stack.indexOf("@")?"@unknown:0:0":""}return` +`+yt+r+Xn}var Na=!1;function Ht(r,a){if(!r||Na)return"";Na=!0;var s=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var c={DetermineComponentFrameRoot:function(){try{if(a){var me=function(){throw Error()};if(Object.defineProperty(me.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(me,[])}catch(oe){var ue=oe}Reflect.construct(r,[],me)}else{try{me.call()}catch(oe){ue=oe}r.call(me.prototype)}}else{try{throw Error()}catch(oe){ue=oe}(me=r())&&typeof me.catch=="function"&&me.catch(function(){})}}catch(oe){if(oe&&ue&&typeof oe.stack=="string")return[oe.stack,ue.stack]}return[null,null]}};c.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var m=Object.getOwnPropertyDescriptor(c.DetermineComponentFrameRoot,"name");m&&m.configurable&&Object.defineProperty(c.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var E=c.DetermineComponentFrameRoot(),D=E[0],x=E[1];if(D&&x){var H=D.split(` +`),ae=x.split(` +`);for(m=c=0;c<H.length&&!H[c].includes("DetermineComponentFrameRoot");)c++;for(;m<ae.length&&!ae[m].includes("DetermineComponentFrameRoot");)m++;if(c===H.length||m===ae.length)for(c=H.length-1,m=ae.length-1;1<=c&&0<=m&&H[c]!==ae[m];)m--;for(;1<=c&&0<=m;c--,m--)if(H[c]!==ae[m]){if(c!==1||m!==1)do if(c--,m--,0>m||H[c]!==ae[m]){var de=` +`+H[c].replace(" at new "," at ");return r.displayName&&de.includes("<anonymous>")&&(de=de.replace("<anonymous>",r.displayName)),de}while(1<=c&&0<=m);break}}}finally{Na=!1,Error.prepareStackTrace=s}return(s=r?r.displayName||r.name:"")?Kn(s):""}function ji(r){switch(r.tag){case 26:case 27:case 5:return Kn(r.type);case 16:return Kn("Lazy");case 13:return Kn("Suspense");case 19:return Kn("SuspenseList");case 0:case 15:return Ht(r.type,!1);case 11:return Ht(r.type.render,!1);case 1:return Ht(r.type,!0);case 31:return Kn("Activity");default:return""}}function Os(r){try{var a="";do a+=ji(r),r=r.return;while(r);return a}catch(s){return` +Error generating stack: `+s.message+` +`+s.stack}}function Wn(r){switch(typeof r){case"bigint":case"boolean":case"number":case"string":case"undefined":return r;case"object":return r;default:return""}}function e1(r){var a=r.type;return(r=r.nodeName)&&r.toLowerCase()==="input"&&(a==="checkbox"||a==="radio")}function Ux(r){var a=e1(r)?"checked":"value",s=Object.getOwnPropertyDescriptor(r.constructor.prototype,a),c=""+r[a];if(!r.hasOwnProperty(a)&&typeof s<"u"&&typeof s.get=="function"&&typeof s.set=="function"){var m=s.get,E=s.set;return Object.defineProperty(r,a,{configurable:!0,get:function(){return m.call(this)},set:function(D){c=""+D,E.call(this,D)}}),Object.defineProperty(r,a,{enumerable:s.enumerable}),{getValue:function(){return c},setValue:function(D){c=""+D},stopTracking:function(){r._valueTracker=null,delete r[a]}}}}function ql(r){r._valueTracker||(r._valueTracker=Ux(r))}function t1(r){if(!r)return!1;var a=r._valueTracker;if(!a)return!0;var s=a.getValue(),c="";return r&&(c=e1(r)?r.checked?"true":"false":r.value),r=c,r!==s?(a.setValue(r),!0):!1}function Yl(r){if(r=r||(typeof document<"u"?document:void 0),typeof r>"u")return null;try{return r.activeElement||r.body}catch{return r.body}}var Hx=/[\n"\\]/g;function Cr(r){return r.replace(Hx,function(a){return"\\"+a.charCodeAt(0).toString(16)+" "})}function vd(r,a,s,c,m,E,D,x){r.name="",D!=null&&typeof D!="function"&&typeof D!="symbol"&&typeof D!="boolean"?r.type=D:r.removeAttribute("type"),a!=null?D==="number"?(a===0&&r.value===""||r.value!=a)&&(r.value=""+Wn(a)):r.value!==""+Wn(a)&&(r.value=""+Wn(a)):D!=="submit"&&D!=="reset"||r.removeAttribute("value"),a!=null?Cd(r,D,Wn(a)):s!=null?Cd(r,D,Wn(s)):c!=null&&r.removeAttribute("value"),m==null&&E!=null&&(r.defaultChecked=!!E),m!=null&&(r.checked=m&&typeof m!="function"&&typeof m!="symbol"),x!=null&&typeof x!="function"&&typeof x!="symbol"&&typeof x!="boolean"?r.name=""+Wn(x):r.removeAttribute("name")}function n1(r,a,s,c,m,E,D,x){if(E!=null&&typeof E!="function"&&typeof E!="symbol"&&typeof E!="boolean"&&(r.type=E),a!=null||s!=null){if(!(E!=="submit"&&E!=="reset"||a!=null))return;s=s!=null?""+Wn(s):"",a=a!=null?""+Wn(a):s,x||a===r.value||(r.value=a),r.defaultValue=a}c=c??m,c=typeof c!="function"&&typeof c!="symbol"&&!!c,r.checked=x?r.checked:!!c,r.defaultChecked=!!c,D!=null&&typeof D!="function"&&typeof D!="symbol"&&typeof D!="boolean"&&(r.name=D)}function Cd(r,a,s){a==="number"&&Yl(r.ownerDocument)===r||r.defaultValue===""+s||(r.defaultValue=""+s)}function Eu(r,a,s,c){if(r=r.options,a){a={};for(var m=0;m<s.length;m++)a["$"+s[m]]=!0;for(s=0;s<r.length;s++)m=a.hasOwnProperty("$"+r[s].value),r[s].selected!==m&&(r[s].selected=m),m&&c&&(r[s].defaultSelected=!0)}else{for(s=""+Wn(s),a=null,m=0;m<r.length;m++){if(r[m].value===s){r[m].selected=!0,c&&(r[m].defaultSelected=!0);return}a!==null||r[m].disabled||(a=r[m])}a!==null&&(a.selected=!0)}}function r1(r,a,s){if(a!=null&&(a=""+Wn(a),a!==r.value&&(r.value=a),s==null)){r.defaultValue!==a&&(r.defaultValue=a);return}r.defaultValue=s!=null?""+Wn(s):""}function i1(r,a,s,c){if(a==null){if(c!=null){if(s!=null)throw Error(i(92));if(L(c)){if(1<c.length)throw Error(i(93));c=c[0]}s=c}s==null&&(s=""),a=s}s=Wn(a),r.defaultValue=s,c=r.textContent,c===s&&c!==""&&c!==null&&(r.value=c)}function yu(r,a){if(a){var s=r.firstChild;if(s&&s===r.lastChild&&s.nodeType===3){s.nodeValue=a;return}}r.textContent=a}var zx=new Set("animationIterationCount aspectRatio borderImageOutset borderImageSlice borderImageWidth boxFlex boxFlexGroup boxOrdinalGroup columnCount columns flex flexGrow flexPositive flexShrink flexNegative flexOrder gridArea gridRow gridRowEnd gridRowSpan gridRowStart gridColumn gridColumnEnd gridColumnSpan gridColumnStart fontWeight lineClamp lineHeight opacity order orphans scale tabSize widows zIndex zoom fillOpacity floodOpacity stopOpacity strokeDasharray strokeDashoffset strokeMiterlimit strokeOpacity strokeWidth MozAnimationIterationCount MozBoxFlex MozBoxFlexGroup MozLineClamp msAnimationIterationCount msFlex msZoom msFlexGrow msFlexNegative msFlexOrder msFlexPositive msFlexShrink msGridColumn msGridColumnSpan msGridRow msGridRowSpan WebkitAnimationIterationCount WebkitBoxFlex WebKitBoxFlexGroup WebkitBoxOrdinalGroup WebkitColumnCount WebkitColumns WebkitFlex WebkitFlexGrow WebkitFlexPositive WebkitFlexShrink WebkitLineClamp".split(" "));function a1(r,a,s){var c=a.indexOf("--")===0;s==null||typeof s=="boolean"||s===""?c?r.setProperty(a,""):a==="float"?r.cssFloat="":r[a]="":c?r.setProperty(a,s):typeof s!="number"||s===0||zx.has(a)?a==="float"?r.cssFloat=s:r[a]=(""+s).trim():r[a]=s+"px"}function u1(r,a,s){if(a!=null&&typeof a!="object")throw Error(i(62));if(r=r.style,s!=null){for(var c in s)!s.hasOwnProperty(c)||a!=null&&a.hasOwnProperty(c)||(c.indexOf("--")===0?r.setProperty(c,""):c==="float"?r.cssFloat="":r[c]="");for(var m in a)c=a[m],a.hasOwnProperty(m)&&s[m]!==c&&a1(r,m,c)}else for(var E in a)a.hasOwnProperty(E)&&a1(r,E,a[E])}function _d(r){if(r.indexOf("-")===-1)return!1;switch(r){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}}var Vx=new Map([["acceptCharset","accept-charset"],["htmlFor","for"],["httpEquiv","http-equiv"],["crossOrigin","crossorigin"],["accentHeight","accent-height"],["alignmentBaseline","alignment-baseline"],["arabicForm","arabic-form"],["baselineShift","baseline-shift"],["capHeight","cap-height"],["clipPath","clip-path"],["clipRule","clip-rule"],["colorInterpolation","color-interpolation"],["colorInterpolationFilters","color-interpolation-filters"],["colorProfile","color-profile"],["colorRendering","color-rendering"],["dominantBaseline","dominant-baseline"],["enableBackground","enable-background"],["fillOpacity","fill-opacity"],["fillRule","fill-rule"],["floodColor","flood-color"],["floodOpacity","flood-opacity"],["fontFamily","font-family"],["fontSize","font-size"],["fontSizeAdjust","font-size-adjust"],["fontStretch","font-stretch"],["fontStyle","font-style"],["fontVariant","font-variant"],["fontWeight","font-weight"],["glyphName","glyph-name"],["glyphOrientationHorizontal","glyph-orientation-horizontal"],["glyphOrientationVertical","glyph-orientation-vertical"],["horizAdvX","horiz-adv-x"],["horizOriginX","horiz-origin-x"],["imageRendering","image-rendering"],["letterSpacing","letter-spacing"],["lightingColor","lighting-color"],["markerEnd","marker-end"],["markerMid","marker-mid"],["markerStart","marker-start"],["overlinePosition","overline-position"],["overlineThickness","overline-thickness"],["paintOrder","paint-order"],["panose-1","panose-1"],["pointerEvents","pointer-events"],["renderingIntent","rendering-intent"],["shapeRendering","shape-rendering"],["stopColor","stop-color"],["stopOpacity","stop-opacity"],["strikethroughPosition","strikethrough-position"],["strikethroughThickness","strikethrough-thickness"],["strokeDasharray","stroke-dasharray"],["strokeDashoffset","stroke-dashoffset"],["strokeLinecap","stroke-linecap"],["strokeLinejoin","stroke-linejoin"],["strokeMiterlimit","stroke-miterlimit"],["strokeOpacity","stroke-opacity"],["strokeWidth","stroke-width"],["textAnchor","text-anchor"],["textDecoration","text-decoration"],["textRendering","text-rendering"],["transformOrigin","transform-origin"],["underlinePosition","underline-position"],["underlineThickness","underline-thickness"],["unicodeBidi","unicode-bidi"],["unicodeRange","unicode-range"],["unitsPerEm","units-per-em"],["vAlphabetic","v-alphabetic"],["vHanging","v-hanging"],["vIdeographic","v-ideographic"],["vMathematical","v-mathematical"],["vectorEffect","vector-effect"],["vertAdvY","vert-adv-y"],["vertOriginX","vert-origin-x"],["vertOriginY","vert-origin-y"],["wordSpacing","word-spacing"],["writingMode","writing-mode"],["xmlnsXlink","xmlns:xlink"],["xHeight","x-height"]]),jx=/^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i;function Gl(r){return jx.test(""+r)?"javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')":r}var xd=null;function Rd(r){return r=r.target||r.srcElement||window,r.correspondingUseElement&&(r=r.correspondingUseElement),r.nodeType===3?r.parentNode:r}var bu=null,Tu=null;function s1(r){var a=dt(r);if(a&&(r=a.stateNode)){var s=r[Ce]||null;e:switch(r=a.stateNode,a.type){case"input":if(vd(r,s.value,s.defaultValue,s.defaultValue,s.checked,s.defaultChecked,s.type,s.name),a=s.name,s.type==="radio"&&a!=null){for(s=r;s.parentNode;)s=s.parentNode;for(s=s.querySelectorAll('input[name="'+Cr(""+a)+'"][type="radio"]'),a=0;a<s.length;a++){var c=s[a];if(c!==r&&c.form===r.form){var m=c[Ce]||null;if(!m)throw Error(i(90));vd(c,m.value,m.defaultValue,m.defaultValue,m.checked,m.defaultChecked,m.type,m.name)}}for(a=0;a<s.length;a++)c=s[a],c.form===r.form&&t1(c)}break e;case"textarea":r1(r,s.value,s.defaultValue);break e;case"select":a=s.value,a!=null&&Eu(r,!!s.multiple,a,!1)}}}var wd=!1;function o1(r,a,s){if(wd)return r(a,s);wd=!0;try{var c=r(a);return c}finally{if(wd=!1,(bu!==null||Tu!==null)&&(Nc(),bu&&(a=bu,r=Tu,Tu=bu=null,s1(a),r)))for(a=0;a<r.length;a++)s1(r[a])}}function Ns(r,a){var s=r.stateNode;if(s===null)return null;var c=s[Ce]||null;if(c===null)return null;s=c[a];e:switch(a){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(c=!c.disabled)||(r=r.type,c=!(r==="button"||r==="input"||r==="select"||r==="textarea")),r=!c;break e;default:r=!1}if(r)return null;if(s&&typeof s!="function")throw Error(i(231,a,typeof s));return s}var Si=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Od=!1;if(Si)try{var ks={};Object.defineProperty(ks,"passive",{get:function(){Od=!0}}),window.addEventListener("test",ks,ks),window.removeEventListener("test",ks,ks)}catch{Od=!1}var qi=null,Nd=null,Xl=null;function l1(){if(Xl)return Xl;var r,a=Nd,s=a.length,c,m="value"in qi?qi.value:qi.textContent,E=m.length;for(r=0;r<s&&a[r]===m[r];r++);var D=s-r;for(c=1;c<=D&&a[s-c]===m[E-c];c++);return Xl=m.slice(r,1<c?1-c:void 0)}function Kl(r){var a=r.keyCode;return"charCode"in r?(r=r.charCode,r===0&&a===13&&(r=13)):r=a,r===10&&(r=13),32<=r||r===13?r:0}function Wl(){return!0}function c1(){return!1}function Qn(r){function a(s,c,m,E,D){this._reactName=s,this._targetInst=m,this.type=c,this.nativeEvent=E,this.target=D,this.currentTarget=null;for(var x in r)r.hasOwnProperty(x)&&(s=r[x],this[x]=s?s(E):E[x]);return this.isDefaultPrevented=(E.defaultPrevented!=null?E.defaultPrevented:E.returnValue===!1)?Wl:c1,this.isPropagationStopped=c1,this}return p(a.prototype,{preventDefault:function(){this.defaultPrevented=!0;var s=this.nativeEvent;s&&(s.preventDefault?s.preventDefault():typeof s.returnValue!="unknown"&&(s.returnValue=!1),this.isDefaultPrevented=Wl)},stopPropagation:function(){var s=this.nativeEvent;s&&(s.stopPropagation?s.stopPropagation():typeof s.cancelBubble!="unknown"&&(s.cancelBubble=!0),this.isPropagationStopped=Wl)},persist:function(){},isPersistent:Wl}),a}var ka={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(r){return r.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},Ql=Qn(ka),Ls=p({},ka,{view:0,detail:0}),qx=Qn(Ls),kd,Ld,Ms,$l=p({},Ls,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Id,button:0,buttons:0,relatedTarget:function(r){return r.relatedTarget===void 0?r.fromElement===r.srcElement?r.toElement:r.fromElement:r.relatedTarget},movementX:function(r){return"movementX"in r?r.movementX:(r!==Ms&&(Ms&&r.type==="mousemove"?(kd=r.screenX-Ms.screenX,Ld=r.screenY-Ms.screenY):Ld=kd=0,Ms=r),kd)},movementY:function(r){return"movementY"in r?r.movementY:Ld}}),f1=Qn($l),Yx=p({},$l,{dataTransfer:0}),Gx=Qn(Yx),Xx=p({},Ls,{relatedTarget:0}),Md=Qn(Xx),Kx=p({},ka,{animationName:0,elapsedTime:0,pseudoElement:0}),Wx=Qn(Kx),Qx=p({},ka,{clipboardData:function(r){return"clipboardData"in r?r.clipboardData:window.clipboardData}}),$x=Qn(Qx),Zx=p({},ka,{data:0}),d1=Qn(Zx),Jx={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},e3={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},t3={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function n3(r){var a=this.nativeEvent;return a.getModifierState?a.getModifierState(r):(r=t3[r])?!!a[r]:!1}function Id(){return n3}var r3=p({},Ls,{key:function(r){if(r.key){var a=Jx[r.key]||r.key;if(a!=="Unidentified")return a}return r.type==="keypress"?(r=Kl(r),r===13?"Enter":String.fromCharCode(r)):r.type==="keydown"||r.type==="keyup"?e3[r.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Id,charCode:function(r){return r.type==="keypress"?Kl(r):0},keyCode:function(r){return r.type==="keydown"||r.type==="keyup"?r.keyCode:0},which:function(r){return r.type==="keypress"?Kl(r):r.type==="keydown"||r.type==="keyup"?r.keyCode:0}}),i3=Qn(r3),a3=p({},$l,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0}),h1=Qn(a3),u3=p({},Ls,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Id}),s3=Qn(u3),o3=p({},ka,{propertyName:0,elapsedTime:0,pseudoElement:0}),l3=Qn(o3),c3=p({},$l,{deltaX:function(r){return"deltaX"in r?r.deltaX:"wheelDeltaX"in r?-r.wheelDeltaX:0},deltaY:function(r){return"deltaY"in r?r.deltaY:"wheelDeltaY"in r?-r.wheelDeltaY:"wheelDelta"in r?-r.wheelDelta:0},deltaZ:0,deltaMode:0}),f3=Qn(c3),d3=p({},ka,{newState:0,oldState:0}),h3=Qn(d3),m3=[9,13,27,32],Pd=Si&&"CompositionEvent"in window,Is=null;Si&&"documentMode"in document&&(Is=document.documentMode);var p3=Si&&"TextEvent"in window&&!Is,m1=Si&&(!Pd||Is&&8<Is&&11>=Is),p1=" ",g1=!1;function E1(r,a){switch(r){case"keyup":return m3.indexOf(a.keyCode)!==-1;case"keydown":return a.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function y1(r){return r=r.detail,typeof r=="object"&&"data"in r?r.data:null}var Au=!1;function g3(r,a){switch(r){case"compositionend":return y1(a);case"keypress":return a.which!==32?null:(g1=!0,p1);case"textInput":return r=a.data,r===p1&&g1?null:r;default:return null}}function E3(r,a){if(Au)return r==="compositionend"||!Pd&&E1(r,a)?(r=l1(),Xl=Nd=qi=null,Au=!1,r):null;switch(r){case"paste":return null;case"keypress":if(!(a.ctrlKey||a.altKey||a.metaKey)||a.ctrlKey&&a.altKey){if(a.char&&1<a.char.length)return a.char;if(a.which)return String.fromCharCode(a.which)}return null;case"compositionend":return m1&&a.locale!=="ko"?null:a.data;default:return null}}var y3={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function b1(r){var a=r&&r.nodeName&&r.nodeName.toLowerCase();return a==="input"?!!y3[r.type]:a==="textarea"}function T1(r,a,s,c){bu?Tu?Tu.push(c):Tu=[c]:bu=c,a=Fc(a,"onChange"),0<a.length&&(s=new Ql("onChange","change",null,s,c),r.push({event:s,listeners:a}))}var Ps=null,Fs=null;function b3(r){eb(r,0)}function Zl(r){var a=Dt(r);if(t1(a))return r}function A1(r,a){if(r==="change")return a}var S1=!1;if(Si){var Fd;if(Si){var Bd="oninput"in document;if(!Bd){var D1=document.createElement("div");D1.setAttribute("oninput","return;"),Bd=typeof D1.oninput=="function"}Fd=Bd}else Fd=!1;S1=Fd&&(!document.documentMode||9<document.documentMode)}function v1(){Ps&&(Ps.detachEvent("onpropertychange",C1),Fs=Ps=null)}function C1(r){if(r.propertyName==="value"&&Zl(Fs)){var a=[];T1(a,Fs,r,Rd(r)),o1(b3,a)}}function T3(r,a,s){r==="focusin"?(v1(),Ps=a,Fs=s,Ps.attachEvent("onpropertychange",C1)):r==="focusout"&&v1()}function A3(r){if(r==="selectionchange"||r==="keyup"||r==="keydown")return Zl(Fs)}function S3(r,a){if(r==="click")return Zl(a)}function D3(r,a){if(r==="input"||r==="change")return Zl(a)}function v3(r,a){return r===a&&(r!==0||1/r===1/a)||r!==r&&a!==a}var or=typeof Object.is=="function"?Object.is:v3;function Bs(r,a){if(or(r,a))return!0;if(typeof r!="object"||r===null||typeof a!="object"||a===null)return!1;var s=Object.keys(r),c=Object.keys(a);if(s.length!==c.length)return!1;for(c=0;c<s.length;c++){var m=s[c];if(!ln.call(a,m)||!or(r[m],a[m]))return!1}return!0}function _1(r){for(;r&&r.firstChild;)r=r.firstChild;return r}function x1(r,a){var s=_1(r);r=0;for(var c;s;){if(s.nodeType===3){if(c=r+s.textContent.length,r<=a&&c>=a)return{node:s,offset:a-r};r=c}e:{for(;s;){if(s.nextSibling){s=s.nextSibling;break e}s=s.parentNode}s=void 0}s=_1(s)}}function R1(r,a){return r&&a?r===a?!0:r&&r.nodeType===3?!1:a&&a.nodeType===3?R1(r,a.parentNode):"contains"in r?r.contains(a):r.compareDocumentPosition?!!(r.compareDocumentPosition(a)&16):!1:!1}function w1(r){r=r!=null&&r.ownerDocument!=null&&r.ownerDocument.defaultView!=null?r.ownerDocument.defaultView:window;for(var a=Yl(r.document);a instanceof r.HTMLIFrameElement;){try{var s=typeof a.contentWindow.location.href=="string"}catch{s=!1}if(s)r=a.contentWindow;else break;a=Yl(r.document)}return a}function Ud(r){var a=r&&r.nodeName&&r.nodeName.toLowerCase();return a&&(a==="input"&&(r.type==="text"||r.type==="search"||r.type==="tel"||r.type==="url"||r.type==="password")||a==="textarea"||r.contentEditable==="true")}var C3=Si&&"documentMode"in document&&11>=document.documentMode,Su=null,Hd=null,Us=null,zd=!1;function O1(r,a,s){var c=s.window===s?s.document:s.nodeType===9?s:s.ownerDocument;zd||Su==null||Su!==Yl(c)||(c=Su,"selectionStart"in c&&Ud(c)?c={start:c.selectionStart,end:c.selectionEnd}:(c=(c.ownerDocument&&c.ownerDocument.defaultView||window).getSelection(),c={anchorNode:c.anchorNode,anchorOffset:c.anchorOffset,focusNode:c.focusNode,focusOffset:c.focusOffset}),Us&&Bs(Us,c)||(Us=c,c=Fc(Hd,"onSelect"),0<c.length&&(a=new Ql("onSelect","select",null,a,s),r.push({event:a,listeners:c}),a.target=Su)))}function La(r,a){var s={};return s[r.toLowerCase()]=a.toLowerCase(),s["Webkit"+r]="webkit"+a,s["Moz"+r]="moz"+a,s}var Du={animationend:La("Animation","AnimationEnd"),animationiteration:La("Animation","AnimationIteration"),animationstart:La("Animation","AnimationStart"),transitionrun:La("Transition","TransitionRun"),transitionstart:La("Transition","TransitionStart"),transitioncancel:La("Transition","TransitionCancel"),transitionend:La("Transition","TransitionEnd")},Vd={},N1={};Si&&(N1=document.createElement("div").style,"AnimationEvent"in window||(delete Du.animationend.animation,delete Du.animationiteration.animation,delete Du.animationstart.animation),"TransitionEvent"in window||delete Du.transitionend.transition);function Ma(r){if(Vd[r])return Vd[r];if(!Du[r])return r;var a=Du[r],s;for(s in a)if(a.hasOwnProperty(s)&&s in N1)return Vd[r]=a[s];return r}var k1=Ma("animationend"),L1=Ma("animationiteration"),M1=Ma("animationstart"),_3=Ma("transitionrun"),x3=Ma("transitionstart"),R3=Ma("transitioncancel"),I1=Ma("transitionend"),P1=new Map,jd="abort auxClick beforeToggle cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");jd.push("scrollEnd");function Yr(r,a){P1.set(r,a),ye(a,[r])}var F1=new WeakMap;function _r(r,a){if(typeof r=="object"&&r!==null){var s=F1.get(r);return s!==void 0?s:(a={value:r,source:a,stack:Os(a)},F1.set(r,a),a)}return{value:r,source:a,stack:Os(a)}}var xr=[],vu=0,qd=0;function Jl(){for(var r=vu,a=qd=vu=0;a<r;){var s=xr[a];xr[a++]=null;var c=xr[a];xr[a++]=null;var m=xr[a];xr[a++]=null;var E=xr[a];if(xr[a++]=null,c!==null&&m!==null){var D=c.pending;D===null?m.next=m:(m.next=D.next,D.next=m),c.pending=m}E!==0&&B1(s,m,E)}}function ec(r,a,s,c){xr[vu++]=r,xr[vu++]=a,xr[vu++]=s,xr[vu++]=c,qd|=c,r.lanes|=c,r=r.alternate,r!==null&&(r.lanes|=c)}function Yd(r,a,s,c){return ec(r,a,s,c),tc(r)}function Cu(r,a){return ec(r,null,null,a),tc(r)}function B1(r,a,s){r.lanes|=s;var c=r.alternate;c!==null&&(c.lanes|=s);for(var m=!1,E=r.return;E!==null;)E.childLanes|=s,c=E.alternate,c!==null&&(c.childLanes|=s),E.tag===22&&(r=E.stateNode,r===null||r._visibility&1||(m=!0)),r=E,E=E.return;return r.tag===3?(E=r.stateNode,m&&a!==null&&(m=31-ze(s),r=E.hiddenUpdates,c=r[m],c===null?r[m]=[a]:c.push(a),a.lane=s|536870912),E):null}function tc(r){if(50<co)throw co=0,$h=null,Error(i(185));for(var a=r.return;a!==null;)r=a,a=r.return;return r.tag===3?r.stateNode:null}var _u={};function w3(r,a,s,c){this.tag=r,this.key=s,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.refCleanup=this.ref=null,this.pendingProps=a,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=c,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function lr(r,a,s,c){return new w3(r,a,s,c)}function Gd(r){return r=r.prototype,!(!r||!r.isReactComponent)}function Di(r,a){var s=r.alternate;return s===null?(s=lr(r.tag,a,r.key,r.mode),s.elementType=r.elementType,s.type=r.type,s.stateNode=r.stateNode,s.alternate=r,r.alternate=s):(s.pendingProps=a,s.type=r.type,s.flags=0,s.subtreeFlags=0,s.deletions=null),s.flags=r.flags&65011712,s.childLanes=r.childLanes,s.lanes=r.lanes,s.child=r.child,s.memoizedProps=r.memoizedProps,s.memoizedState=r.memoizedState,s.updateQueue=r.updateQueue,a=r.dependencies,s.dependencies=a===null?null:{lanes:a.lanes,firstContext:a.firstContext},s.sibling=r.sibling,s.index=r.index,s.ref=r.ref,s.refCleanup=r.refCleanup,s}function U1(r,a){r.flags&=65011714;var s=r.alternate;return s===null?(r.childLanes=0,r.lanes=a,r.child=null,r.subtreeFlags=0,r.memoizedProps=null,r.memoizedState=null,r.updateQueue=null,r.dependencies=null,r.stateNode=null):(r.childLanes=s.childLanes,r.lanes=s.lanes,r.child=s.child,r.subtreeFlags=0,r.deletions=null,r.memoizedProps=s.memoizedProps,r.memoizedState=s.memoizedState,r.updateQueue=s.updateQueue,r.type=s.type,a=s.dependencies,r.dependencies=a===null?null:{lanes:a.lanes,firstContext:a.firstContext}),r}function nc(r,a,s,c,m,E){var D=0;if(c=r,typeof r=="function")Gd(r)&&(D=1);else if(typeof r=="string")D=NR(r,s,Te.current)?26:r==="html"||r==="head"||r==="body"?27:5;else e:switch(r){case q:return r=lr(31,s,a,m),r.elementType=q,r.lanes=E,r;case A:return Ia(s.children,m,E,a);case _:D=8,m|=24;break;case O:return r=lr(12,s,a,m|2),r.elementType=O,r.lanes=E,r;case M:return r=lr(13,s,a,m),r.elementType=M,r.lanes=E,r;case v:return r=lr(19,s,a,m),r.elementType=v,r.lanes=E,r;default:if(typeof r=="object"&&r!==null)switch(r.$$typeof){case C:case R:D=10;break e;case N:D=9;break e;case Y:D=11;break e;case J:D=14;break e;case P:D=16,c=null;break e}D=29,s=Error(i(130,r===null?"null":typeof r,"")),c=null}return a=lr(D,s,a,m),a.elementType=r,a.type=c,a.lanes=E,a}function Ia(r,a,s,c){return r=lr(7,r,c,a),r.lanes=s,r}function Xd(r,a,s){return r=lr(6,r,null,a),r.lanes=s,r}function Kd(r,a,s){return a=lr(4,r.children!==null?r.children:[],r.key,a),a.lanes=s,a.stateNode={containerInfo:r.containerInfo,pendingChildren:null,implementation:r.implementation},a}var xu=[],Ru=0,rc=null,ic=0,Rr=[],wr=0,Pa=null,vi=1,Ci="";function Fa(r,a){xu[Ru++]=ic,xu[Ru++]=rc,rc=r,ic=a}function H1(r,a,s){Rr[wr++]=vi,Rr[wr++]=Ci,Rr[wr++]=Pa,Pa=r;var c=vi;r=Ci;var m=32-ze(c)-1;c&=~(1<<m),s+=1;var E=32-ze(a)+m;if(30<E){var D=m-m%5;E=(c&(1<<D)-1).toString(32),c>>=D,m-=D,vi=1<<32-ze(a)+m|s<<m|c,Ci=E+r}else vi=1<<E|s<<m|c,Ci=r}function Wd(r){r.return!==null&&(Fa(r,1),H1(r,1,0))}function Qd(r){for(;r===rc;)rc=xu[--Ru],xu[Ru]=null,ic=xu[--Ru],xu[Ru]=null;for(;r===Pa;)Pa=Rr[--wr],Rr[wr]=null,Ci=Rr[--wr],Rr[wr]=null,vi=Rr[--wr],Rr[wr]=null}var Un=null,Zt=null,Tt=!1,Ba=null,ui=!1,$d=Error(i(519));function Ua(r){var a=Error(i(418,""));throw Vs(_r(a,r)),$d}function z1(r){var a=r.stateNode,s=r.type,c=r.memoizedProps;switch(a[pe]=r,a[Ce]=c,s){case"dialog":ct("cancel",a),ct("close",a);break;case"iframe":case"object":case"embed":ct("load",a);break;case"video":case"audio":for(s=0;s<ho.length;s++)ct(ho[s],a);break;case"source":ct("error",a);break;case"img":case"image":case"link":ct("error",a),ct("load",a);break;case"details":ct("toggle",a);break;case"input":ct("invalid",a),n1(a,c.value,c.defaultValue,c.checked,c.defaultChecked,c.type,c.name,!0),ql(a);break;case"select":ct("invalid",a);break;case"textarea":ct("invalid",a),i1(a,c.value,c.defaultValue,c.children),ql(a)}s=c.children,typeof s!="string"&&typeof s!="number"&&typeof s!="bigint"||a.textContent===""+s||c.suppressHydrationWarning===!0||ib(a.textContent,s)?(c.popover!=null&&(ct("beforetoggle",a),ct("toggle",a)),c.onScroll!=null&&ct("scroll",a),c.onScrollEnd!=null&&ct("scrollend",a),c.onClick!=null&&(a.onclick=Bc),a=!0):a=!1,a||Ua(r)}function V1(r){for(Un=r.return;Un;)switch(Un.tag){case 5:case 13:ui=!1;return;case 27:case 3:ui=!0;return;default:Un=Un.return}}function Hs(r){if(r!==Un)return!1;if(!Tt)return V1(r),Tt=!0,!1;var a=r.tag,s;if((s=a!==3&&a!==27)&&((s=a===5)&&(s=r.type,s=!(s!=="form"&&s!=="button")||hm(r.type,r.memoizedProps)),s=!s),s&&Zt&&Ua(r),V1(r),a===13){if(r=r.memoizedState,r=r!==null?r.dehydrated:null,!r)throw Error(i(317));e:{for(r=r.nextSibling,a=0;r;){if(r.nodeType===8)if(s=r.data,s==="/$"){if(a===0){Zt=Xr(r.nextSibling);break e}a--}else s!=="$"&&s!=="$!"&&s!=="$?"||a++;r=r.nextSibling}Zt=null}}else a===27?(a=Zt,ua(r.type)?(r=Em,Em=null,Zt=r):Zt=a):Zt=Un?Xr(r.stateNode.nextSibling):null;return!0}function zs(){Zt=Un=null,Tt=!1}function j1(){var r=Ba;return r!==null&&(Jn===null?Jn=r:Jn.push.apply(Jn,r),Ba=null),r}function Vs(r){Ba===null?Ba=[r]:Ba.push(r)}var Zd=ne(null),Ha=null,_i=null;function Yi(r,a,s){w(Zd,a._currentValue),a._currentValue=s}function xi(r){r._currentValue=Zd.current,ge(Zd)}function Jd(r,a,s){for(;r!==null;){var c=r.alternate;if((r.childLanes&a)!==a?(r.childLanes|=a,c!==null&&(c.childLanes|=a)):c!==null&&(c.childLanes&a)!==a&&(c.childLanes|=a),r===s)break;r=r.return}}function eh(r,a,s,c){var m=r.child;for(m!==null&&(m.return=r);m!==null;){var E=m.dependencies;if(E!==null){var D=m.child;E=E.firstContext;e:for(;E!==null;){var x=E;E=m;for(var H=0;H<a.length;H++)if(x.context===a[H]){E.lanes|=s,x=E.alternate,x!==null&&(x.lanes|=s),Jd(E.return,s,r),c||(D=null);break e}E=x.next}}else if(m.tag===18){if(D=m.return,D===null)throw Error(i(341));D.lanes|=s,E=D.alternate,E!==null&&(E.lanes|=s),Jd(D,s,r),D=null}else D=m.child;if(D!==null)D.return=m;else for(D=m;D!==null;){if(D===r){D=null;break}if(m=D.sibling,m!==null){m.return=D.return,D=m;break}D=D.return}m=D}}function js(r,a,s,c){r=null;for(var m=a,E=!1;m!==null;){if(!E){if((m.flags&524288)!==0)E=!0;else if((m.flags&262144)!==0)break}if(m.tag===10){var D=m.alternate;if(D===null)throw Error(i(387));if(D=D.memoizedProps,D!==null){var x=m.type;or(m.pendingProps.value,D.value)||(r!==null?r.push(x):r=[x])}}else if(m===We.current){if(D=m.alternate,D===null)throw Error(i(387));D.memoizedState.memoizedState!==m.memoizedState.memoizedState&&(r!==null?r.push(bo):r=[bo])}m=m.return}r!==null&&eh(a,r,s,c),a.flags|=262144}function ac(r){for(r=r.firstContext;r!==null;){if(!or(r.context._currentValue,r.memoizedValue))return!0;r=r.next}return!1}function za(r){Ha=r,_i=null,r=r.dependencies,r!==null&&(r.firstContext=null)}function Nn(r){return q1(Ha,r)}function uc(r,a){return Ha===null&&za(r),q1(r,a)}function q1(r,a){var s=a._currentValue;if(a={context:a,memoizedValue:s,next:null},_i===null){if(r===null)throw Error(i(308));_i=a,r.dependencies={lanes:0,firstContext:a},r.flags|=524288}else _i=_i.next=a;return s}var O3=typeof AbortController<"u"?AbortController:function(){var r=[],a=this.signal={aborted:!1,addEventListener:function(s,c){r.push(c)}};this.abort=function(){a.aborted=!0,r.forEach(function(s){return s()})}},N3=e.unstable_scheduleCallback,k3=e.unstable_NormalPriority,En={$$typeof:R,Consumer:null,Provider:null,_currentValue:null,_currentValue2:null,_threadCount:0};function th(){return{controller:new O3,data:new Map,refCount:0}}function qs(r){r.refCount--,r.refCount===0&&N3(k3,function(){r.controller.abort()})}var Ys=null,nh=0,wu=0,Ou=null;function L3(r,a){if(Ys===null){var s=Ys=[];nh=0,wu=im(),Ou={status:"pending",value:void 0,then:function(c){s.push(c)}}}return nh++,a.then(Y1,Y1),a}function Y1(){if(--nh===0&&Ys!==null){Ou!==null&&(Ou.status="fulfilled");var r=Ys;Ys=null,wu=0,Ou=null;for(var a=0;a<r.length;a++)(0,r[a])()}}function M3(r,a){var s=[],c={status:"pending",value:null,reason:null,then:function(m){s.push(m)}};return r.then(function(){c.status="fulfilled",c.value=a;for(var m=0;m<s.length;m++)(0,s[m])(a)},function(m){for(c.status="rejected",c.reason=m,m=0;m<s.length;m++)(0,s[m])(void 0)}),c}var G1=B.S;B.S=function(r,a){typeof a=="object"&&a!==null&&typeof a.then=="function"&&L3(r,a),G1!==null&&G1(r,a)};var Va=ne(null);function rh(){var r=Va.current;return r!==null?r:Mt.pooledCache}function sc(r,a){a===null?w(Va,Va.current):w(Va,a.pool)}function X1(){var r=rh();return r===null?null:{parent:En._currentValue,pool:r}}var Gs=Error(i(460)),K1=Error(i(474)),oc=Error(i(542)),ih={then:function(){}};function W1(r){return r=r.status,r==="fulfilled"||r==="rejected"}function lc(){}function Q1(r,a,s){switch(s=r[s],s===void 0?r.push(a):s!==a&&(a.then(lc,lc),a=s),a.status){case"fulfilled":return a.value;case"rejected":throw r=a.reason,Z1(r),r;default:if(typeof a.status=="string")a.then(lc,lc);else{if(r=Mt,r!==null&&100<r.shellSuspendCounter)throw Error(i(482));r=a,r.status="pending",r.then(function(c){if(a.status==="pending"){var m=a;m.status="fulfilled",m.value=c}},function(c){if(a.status==="pending"){var m=a;m.status="rejected",m.reason=c}})}switch(a.status){case"fulfilled":return a.value;case"rejected":throw r=a.reason,Z1(r),r}throw Xs=a,Gs}}var Xs=null;function $1(){if(Xs===null)throw Error(i(459));var r=Xs;return Xs=null,r}function Z1(r){if(r===Gs||r===oc)throw Error(i(483))}var Gi=!1;function ah(r){r.updateQueue={baseState:r.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function uh(r,a){r=r.updateQueue,a.updateQueue===r&&(a.updateQueue={baseState:r.baseState,firstBaseUpdate:r.firstBaseUpdate,lastBaseUpdate:r.lastBaseUpdate,shared:r.shared,callbacks:null})}function Xi(r){return{lane:r,tag:0,payload:null,callback:null,next:null}}function Ki(r,a,s){var c=r.updateQueue;if(c===null)return null;if(c=c.shared,(At&2)!==0){var m=c.pending;return m===null?a.next=a:(a.next=m.next,m.next=a),c.pending=a,a=tc(r),B1(r,null,s),a}return ec(r,c,a,s),tc(r)}function Ks(r,a,s){if(a=a.updateQueue,a!==null&&(a=a.shared,(s&4194048)!==0)){var c=a.lanes;c&=r.pendingLanes,s|=c,a.lanes=s,kt(r,s)}}function sh(r,a){var s=r.updateQueue,c=r.alternate;if(c!==null&&(c=c.updateQueue,s===c)){var m=null,E=null;if(s=s.firstBaseUpdate,s!==null){do{var D={lane:s.lane,tag:s.tag,payload:s.payload,callback:null,next:null};E===null?m=E=D:E=E.next=D,s=s.next}while(s!==null);E===null?m=E=a:E=E.next=a}else m=E=a;s={baseState:c.baseState,firstBaseUpdate:m,lastBaseUpdate:E,shared:c.shared,callbacks:c.callbacks},r.updateQueue=s;return}r=s.lastBaseUpdate,r===null?s.firstBaseUpdate=a:r.next=a,s.lastBaseUpdate=a}var oh=!1;function Ws(){if(oh){var r=Ou;if(r!==null)throw r}}function Qs(r,a,s,c){oh=!1;var m=r.updateQueue;Gi=!1;var E=m.firstBaseUpdate,D=m.lastBaseUpdate,x=m.shared.pending;if(x!==null){m.shared.pending=null;var H=x,ae=H.next;H.next=null,D===null?E=ae:D.next=ae,D=H;var de=r.alternate;de!==null&&(de=de.updateQueue,x=de.lastBaseUpdate,x!==D&&(x===null?de.firstBaseUpdate=ae:x.next=ae,de.lastBaseUpdate=H))}if(E!==null){var me=m.baseState;D=0,de=ae=H=null,x=E;do{var ue=x.lane&-536870913,oe=ue!==x.lane;if(oe?(gt&ue)===ue:(c&ue)===ue){ue!==0&&ue===wu&&(oh=!0),de!==null&&(de=de.next={lane:0,tag:x.tag,payload:x.payload,callback:null,next:null});e:{var Xe=r,qe=x;ue=a;var xt=s;switch(qe.tag){case 1:if(Xe=qe.payload,typeof Xe=="function"){me=Xe.call(xt,me,ue);break e}me=Xe;break e;case 3:Xe.flags=Xe.flags&-65537|128;case 0:if(Xe=qe.payload,ue=typeof Xe=="function"?Xe.call(xt,me,ue):Xe,ue==null)break e;me=p({},me,ue);break e;case 2:Gi=!0}}ue=x.callback,ue!==null&&(r.flags|=64,oe&&(r.flags|=8192),oe=m.callbacks,oe===null?m.callbacks=[ue]:oe.push(ue))}else oe={lane:ue,tag:x.tag,payload:x.payload,callback:x.callback,next:null},de===null?(ae=de=oe,H=me):de=de.next=oe,D|=ue;if(x=x.next,x===null){if(x=m.shared.pending,x===null)break;oe=x,x=oe.next,oe.next=null,m.lastBaseUpdate=oe,m.shared.pending=null}}while(!0);de===null&&(H=me),m.baseState=H,m.firstBaseUpdate=ae,m.lastBaseUpdate=de,E===null&&(m.shared.lanes=0),na|=D,r.lanes=D,r.memoizedState=me}}function J1(r,a){if(typeof r!="function")throw Error(i(191,r));r.call(a)}function eE(r,a){var s=r.callbacks;if(s!==null)for(r.callbacks=null,r=0;r<s.length;r++)J1(s[r],a)}var Nu=ne(null),cc=ne(0);function tE(r,a){r=Mi,w(cc,r),w(Nu,a),Mi=r|a.baseLanes}function lh(){w(cc,Mi),w(Nu,Nu.current)}function ch(){Mi=cc.current,ge(Nu),ge(cc)}var Wi=0,it=null,Ct=null,fn=null,fc=!1,ku=!1,ja=!1,dc=0,$s=0,Lu=null,I3=0;function rn(){throw Error(i(321))}function fh(r,a){if(a===null)return!1;for(var s=0;s<a.length&&s<r.length;s++)if(!or(r[s],a[s]))return!1;return!0}function dh(r,a,s,c,m,E){return Wi=E,it=a,a.memoizedState=null,a.updateQueue=null,a.lanes=0,B.H=r===null||r.memoizedState===null?BE:UE,ja=!1,E=s(c,m),ja=!1,ku&&(E=rE(a,s,c,m)),nE(r),E}function nE(r){B.H=yc;var a=Ct!==null&&Ct.next!==null;if(Wi=0,fn=Ct=it=null,fc=!1,$s=0,Lu=null,a)throw Error(i(300));r===null||Tn||(r=r.dependencies,r!==null&&ac(r)&&(Tn=!0))}function rE(r,a,s,c){it=r;var m=0;do{if(ku&&(Lu=null),$s=0,ku=!1,25<=m)throw Error(i(301));if(m+=1,fn=Ct=null,r.updateQueue!=null){var E=r.updateQueue;E.lastEffect=null,E.events=null,E.stores=null,E.memoCache!=null&&(E.memoCache.index=0)}B.H=V3,E=a(s,c)}while(ku);return E}function P3(){var r=B.H,a=r.useState()[0];return a=typeof a.then=="function"?Zs(a):a,r=r.useState()[0],(Ct!==null?Ct.memoizedState:null)!==r&&(it.flags|=1024),a}function hh(){var r=dc!==0;return dc=0,r}function mh(r,a,s){a.updateQueue=r.updateQueue,a.flags&=-2053,r.lanes&=~s}function ph(r){if(fc){for(r=r.memoizedState;r!==null;){var a=r.queue;a!==null&&(a.pending=null),r=r.next}fc=!1}Wi=0,fn=Ct=it=null,ku=!1,$s=dc=0,Lu=null}function $n(){var r={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return fn===null?it.memoizedState=fn=r:fn=fn.next=r,fn}function dn(){if(Ct===null){var r=it.alternate;r=r!==null?r.memoizedState:null}else r=Ct.next;var a=fn===null?it.memoizedState:fn.next;if(a!==null)fn=a,Ct=r;else{if(r===null)throw it.alternate===null?Error(i(467)):Error(i(310));Ct=r,r={memoizedState:Ct.memoizedState,baseState:Ct.baseState,baseQueue:Ct.baseQueue,queue:Ct.queue,next:null},fn===null?it.memoizedState=fn=r:fn=fn.next=r}return fn}function gh(){return{lastEffect:null,events:null,stores:null,memoCache:null}}function Zs(r){var a=$s;return $s+=1,Lu===null&&(Lu=[]),r=Q1(Lu,r,a),a=it,(fn===null?a.memoizedState:fn.next)===null&&(a=a.alternate,B.H=a===null||a.memoizedState===null?BE:UE),r}function hc(r){if(r!==null&&typeof r=="object"){if(typeof r.then=="function")return Zs(r);if(r.$$typeof===R)return Nn(r)}throw Error(i(438,String(r)))}function Eh(r){var a=null,s=it.updateQueue;if(s!==null&&(a=s.memoCache),a==null){var c=it.alternate;c!==null&&(c=c.updateQueue,c!==null&&(c=c.memoCache,c!=null&&(a={data:c.data.map(function(m){return m.slice()}),index:0})))}if(a==null&&(a={data:[],index:0}),s===null&&(s=gh(),it.updateQueue=s),s.memoCache=a,s=a.data[a.index],s===void 0)for(s=a.data[a.index]=Array(r),c=0;c<r;c++)s[c]=z;return a.index++,s}function Ri(r,a){return typeof a=="function"?a(r):a}function mc(r){var a=dn();return yh(a,Ct,r)}function yh(r,a,s){var c=r.queue;if(c===null)throw Error(i(311));c.lastRenderedReducer=s;var m=r.baseQueue,E=c.pending;if(E!==null){if(m!==null){var D=m.next;m.next=E.next,E.next=D}a.baseQueue=m=E,c.pending=null}if(E=r.baseState,m===null)r.memoizedState=E;else{a=m.next;var x=D=null,H=null,ae=a,de=!1;do{var me=ae.lane&-536870913;if(me!==ae.lane?(gt&me)===me:(Wi&me)===me){var ue=ae.revertLane;if(ue===0)H!==null&&(H=H.next={lane:0,revertLane:0,action:ae.action,hasEagerState:ae.hasEagerState,eagerState:ae.eagerState,next:null}),me===wu&&(de=!0);else if((Wi&ue)===ue){ae=ae.next,ue===wu&&(de=!0);continue}else me={lane:0,revertLane:ae.revertLane,action:ae.action,hasEagerState:ae.hasEagerState,eagerState:ae.eagerState,next:null},H===null?(x=H=me,D=E):H=H.next=me,it.lanes|=ue,na|=ue;me=ae.action,ja&&s(E,me),E=ae.hasEagerState?ae.eagerState:s(E,me)}else ue={lane:me,revertLane:ae.revertLane,action:ae.action,hasEagerState:ae.hasEagerState,eagerState:ae.eagerState,next:null},H===null?(x=H=ue,D=E):H=H.next=ue,it.lanes|=me,na|=me;ae=ae.next}while(ae!==null&&ae!==a);if(H===null?D=E:H.next=x,!or(E,r.memoizedState)&&(Tn=!0,de&&(s=Ou,s!==null)))throw s;r.memoizedState=E,r.baseState=D,r.baseQueue=H,c.lastRenderedState=E}return m===null&&(c.lanes=0),[r.memoizedState,c.dispatch]}function bh(r){var a=dn(),s=a.queue;if(s===null)throw Error(i(311));s.lastRenderedReducer=r;var c=s.dispatch,m=s.pending,E=a.memoizedState;if(m!==null){s.pending=null;var D=m=m.next;do E=r(E,D.action),D=D.next;while(D!==m);or(E,a.memoizedState)||(Tn=!0),a.memoizedState=E,a.baseQueue===null&&(a.baseState=E),s.lastRenderedState=E}return[E,c]}function iE(r,a,s){var c=it,m=dn(),E=Tt;if(E){if(s===void 0)throw Error(i(407));s=s()}else s=a();var D=!or((Ct||m).memoizedState,s);D&&(m.memoizedState=s,Tn=!0),m=m.queue;var x=sE.bind(null,c,m,r);if(Js(2048,8,x,[r]),m.getSnapshot!==a||D||fn!==null&&fn.memoizedState.tag&1){if(c.flags|=2048,Mu(9,pc(),uE.bind(null,c,m,s,a),null),Mt===null)throw Error(i(349));E||(Wi&124)!==0||aE(c,a,s)}return s}function aE(r,a,s){r.flags|=16384,r={getSnapshot:a,value:s},a=it.updateQueue,a===null?(a=gh(),it.updateQueue=a,a.stores=[r]):(s=a.stores,s===null?a.stores=[r]:s.push(r))}function uE(r,a,s,c){a.value=s,a.getSnapshot=c,oE(a)&&lE(r)}function sE(r,a,s){return s(function(){oE(a)&&lE(r)})}function oE(r){var a=r.getSnapshot;r=r.value;try{var s=a();return!or(r,s)}catch{return!0}}function lE(r){var a=Cu(r,2);a!==null&&mr(a,r,2)}function Th(r){var a=$n();if(typeof r=="function"){var s=r;if(r=s(),ja){Pe(!0);try{s()}finally{Pe(!1)}}}return a.memoizedState=a.baseState=r,a.queue={pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ri,lastRenderedState:r},a}function cE(r,a,s,c){return r.baseState=s,yh(r,Ct,typeof c=="function"?c:Ri)}function F3(r,a,s,c,m){if(Ec(r))throw Error(i(485));if(r=a.action,r!==null){var E={payload:m,action:r,next:null,isTransition:!0,status:"pending",value:null,reason:null,listeners:[],then:function(D){E.listeners.push(D)}};B.T!==null?s(!0):E.isTransition=!1,c(E),s=a.pending,s===null?(E.next=a.pending=E,fE(a,E)):(E.next=s.next,a.pending=s.next=E)}}function fE(r,a){var s=a.action,c=a.payload,m=r.state;if(a.isTransition){var E=B.T,D={};B.T=D;try{var x=s(m,c),H=B.S;H!==null&&H(D,x),dE(r,a,x)}catch(ae){Ah(r,a,ae)}finally{B.T=E}}else try{E=s(m,c),dE(r,a,E)}catch(ae){Ah(r,a,ae)}}function dE(r,a,s){s!==null&&typeof s=="object"&&typeof s.then=="function"?s.then(function(c){hE(r,a,c)},function(c){return Ah(r,a,c)}):hE(r,a,s)}function hE(r,a,s){a.status="fulfilled",a.value=s,mE(a),r.state=s,a=r.pending,a!==null&&(s=a.next,s===a?r.pending=null:(s=s.next,a.next=s,fE(r,s)))}function Ah(r,a,s){var c=r.pending;if(r.pending=null,c!==null){c=c.next;do a.status="rejected",a.reason=s,mE(a),a=a.next;while(a!==c)}r.action=null}function mE(r){r=r.listeners;for(var a=0;a<r.length;a++)(0,r[a])()}function pE(r,a){return a}function gE(r,a){if(Tt){var s=Mt.formState;if(s!==null){e:{var c=it;if(Tt){if(Zt){t:{for(var m=Zt,E=ui;m.nodeType!==8;){if(!E){m=null;break t}if(m=Xr(m.nextSibling),m===null){m=null;break t}}E=m.data,m=E==="F!"||E==="F"?m:null}if(m){Zt=Xr(m.nextSibling),c=m.data==="F!";break e}}Ua(c)}c=!1}c&&(a=s[0])}}return s=$n(),s.memoizedState=s.baseState=a,c={pending:null,lanes:0,dispatch:null,lastRenderedReducer:pE,lastRenderedState:a},s.queue=c,s=IE.bind(null,it,c),c.dispatch=s,c=Th(!1),E=_h.bind(null,it,!1,c.queue),c=$n(),m={state:a,dispatch:null,action:r,pending:null},c.queue=m,s=F3.bind(null,it,m,E,s),m.dispatch=s,c.memoizedState=r,[a,s,!1]}function EE(r){var a=dn();return yE(a,Ct,r)}function yE(r,a,s){if(a=yh(r,a,pE)[0],r=mc(Ri)[0],typeof a=="object"&&a!==null&&typeof a.then=="function")try{var c=Zs(a)}catch(D){throw D===Gs?oc:D}else c=a;a=dn();var m=a.queue,E=m.dispatch;return s!==a.memoizedState&&(it.flags|=2048,Mu(9,pc(),B3.bind(null,m,s),null)),[c,E,r]}function B3(r,a){r.action=a}function bE(r){var a=dn(),s=Ct;if(s!==null)return yE(a,s,r);dn(),a=a.memoizedState,s=dn();var c=s.queue.dispatch;return s.memoizedState=r,[a,c,!1]}function Mu(r,a,s,c){return r={tag:r,create:s,deps:c,inst:a,next:null},a=it.updateQueue,a===null&&(a=gh(),it.updateQueue=a),s=a.lastEffect,s===null?a.lastEffect=r.next=r:(c=s.next,s.next=r,r.next=c,a.lastEffect=r),r}function pc(){return{destroy:void 0,resource:void 0}}function TE(){return dn().memoizedState}function gc(r,a,s,c){var m=$n();c=c===void 0?null:c,it.flags|=r,m.memoizedState=Mu(1|a,pc(),s,c)}function Js(r,a,s,c){var m=dn();c=c===void 0?null:c;var E=m.memoizedState.inst;Ct!==null&&c!==null&&fh(c,Ct.memoizedState.deps)?m.memoizedState=Mu(a,E,s,c):(it.flags|=r,m.memoizedState=Mu(1|a,E,s,c))}function AE(r,a){gc(8390656,8,r,a)}function SE(r,a){Js(2048,8,r,a)}function DE(r,a){return Js(4,2,r,a)}function vE(r,a){return Js(4,4,r,a)}function CE(r,a){if(typeof a=="function"){r=r();var s=a(r);return function(){typeof s=="function"?s():a(null)}}if(a!=null)return r=r(),a.current=r,function(){a.current=null}}function _E(r,a,s){s=s!=null?s.concat([r]):null,Js(4,4,CE.bind(null,a,r),s)}function Sh(){}function xE(r,a){var s=dn();a=a===void 0?null:a;var c=s.memoizedState;return a!==null&&fh(a,c[1])?c[0]:(s.memoizedState=[r,a],r)}function RE(r,a){var s=dn();a=a===void 0?null:a;var c=s.memoizedState;if(a!==null&&fh(a,c[1]))return c[0];if(c=r(),ja){Pe(!0);try{r()}finally{Pe(!1)}}return s.memoizedState=[c,a],c}function Dh(r,a,s){return s===void 0||(Wi&1073741824)!==0?r.memoizedState=a:(r.memoizedState=s,r=Ny(),it.lanes|=r,na|=r,s)}function wE(r,a,s,c){return or(s,a)?s:Nu.current!==null?(r=Dh(r,s,c),or(r,a)||(Tn=!0),r):(Wi&42)===0?(Tn=!0,r.memoizedState=s):(r=Ny(),it.lanes|=r,na|=r,a)}function OE(r,a,s,c,m){var E=K.p;K.p=E!==0&&8>E?E:8;var D=B.T,x={};B.T=x,_h(r,!1,a,s);try{var H=m(),ae=B.S;if(ae!==null&&ae(x,H),H!==null&&typeof H=="object"&&typeof H.then=="function"){var de=M3(H,c);eo(r,a,de,hr(r))}else eo(r,a,c,hr(r))}catch(me){eo(r,a,{then:function(){},status:"rejected",reason:me},hr())}finally{K.p=E,B.T=D}}function U3(){}function vh(r,a,s,c){if(r.tag!==5)throw Error(i(476));var m=NE(r).queue;OE(r,m,a,Q,s===null?U3:function(){return kE(r),s(c)})}function NE(r){var a=r.memoizedState;if(a!==null)return a;a={memoizedState:Q,baseState:Q,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ri,lastRenderedState:Q},next:null};var s={};return a.next={memoizedState:s,baseState:s,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ri,lastRenderedState:s},next:null},r.memoizedState=a,r=r.alternate,r!==null&&(r.memoizedState=a),a}function kE(r){var a=NE(r).next.queue;eo(r,a,{},hr())}function Ch(){return Nn(bo)}function LE(){return dn().memoizedState}function ME(){return dn().memoizedState}function H3(r){for(var a=r.return;a!==null;){switch(a.tag){case 24:case 3:var s=hr();r=Xi(s);var c=Ki(a,r,s);c!==null&&(mr(c,a,s),Ks(c,a,s)),a={cache:th()},r.payload=a;return}a=a.return}}function z3(r,a,s){var c=hr();s={lane:c,revertLane:0,action:s,hasEagerState:!1,eagerState:null,next:null},Ec(r)?PE(a,s):(s=Yd(r,a,s,c),s!==null&&(mr(s,r,c),FE(s,a,c)))}function IE(r,a,s){var c=hr();eo(r,a,s,c)}function eo(r,a,s,c){var m={lane:c,revertLane:0,action:s,hasEagerState:!1,eagerState:null,next:null};if(Ec(r))PE(a,m);else{var E=r.alternate;if(r.lanes===0&&(E===null||E.lanes===0)&&(E=a.lastRenderedReducer,E!==null))try{var D=a.lastRenderedState,x=E(D,s);if(m.hasEagerState=!0,m.eagerState=x,or(x,D))return ec(r,a,m,0),Mt===null&&Jl(),!1}catch{}finally{}if(s=Yd(r,a,m,c),s!==null)return mr(s,r,c),FE(s,a,c),!0}return!1}function _h(r,a,s,c){if(c={lane:2,revertLane:im(),action:c,hasEagerState:!1,eagerState:null,next:null},Ec(r)){if(a)throw Error(i(479))}else a=Yd(r,s,c,2),a!==null&&mr(a,r,2)}function Ec(r){var a=r.alternate;return r===it||a!==null&&a===it}function PE(r,a){ku=fc=!0;var s=r.pending;s===null?a.next=a:(a.next=s.next,s.next=a),r.pending=a}function FE(r,a,s){if((s&4194048)!==0){var c=a.lanes;c&=r.pendingLanes,s|=c,a.lanes=s,kt(r,s)}}var yc={readContext:Nn,use:hc,useCallback:rn,useContext:rn,useEffect:rn,useImperativeHandle:rn,useLayoutEffect:rn,useInsertionEffect:rn,useMemo:rn,useReducer:rn,useRef:rn,useState:rn,useDebugValue:rn,useDeferredValue:rn,useTransition:rn,useSyncExternalStore:rn,useId:rn,useHostTransitionStatus:rn,useFormState:rn,useActionState:rn,useOptimistic:rn,useMemoCache:rn,useCacheRefresh:rn},BE={readContext:Nn,use:hc,useCallback:function(r,a){return $n().memoizedState=[r,a===void 0?null:a],r},useContext:Nn,useEffect:AE,useImperativeHandle:function(r,a,s){s=s!=null?s.concat([r]):null,gc(4194308,4,CE.bind(null,a,r),s)},useLayoutEffect:function(r,a){return gc(4194308,4,r,a)},useInsertionEffect:function(r,a){gc(4,2,r,a)},useMemo:function(r,a){var s=$n();a=a===void 0?null:a;var c=r();if(ja){Pe(!0);try{r()}finally{Pe(!1)}}return s.memoizedState=[c,a],c},useReducer:function(r,a,s){var c=$n();if(s!==void 0){var m=s(a);if(ja){Pe(!0);try{s(a)}finally{Pe(!1)}}}else m=a;return c.memoizedState=c.baseState=m,r={pending:null,lanes:0,dispatch:null,lastRenderedReducer:r,lastRenderedState:m},c.queue=r,r=r.dispatch=z3.bind(null,it,r),[c.memoizedState,r]},useRef:function(r){var a=$n();return r={current:r},a.memoizedState=r},useState:function(r){r=Th(r);var a=r.queue,s=IE.bind(null,it,a);return a.dispatch=s,[r.memoizedState,s]},useDebugValue:Sh,useDeferredValue:function(r,a){var s=$n();return Dh(s,r,a)},useTransition:function(){var r=Th(!1);return r=OE.bind(null,it,r.queue,!0,!1),$n().memoizedState=r,[!1,r]},useSyncExternalStore:function(r,a,s){var c=it,m=$n();if(Tt){if(s===void 0)throw Error(i(407));s=s()}else{if(s=a(),Mt===null)throw Error(i(349));(gt&124)!==0||aE(c,a,s)}m.memoizedState=s;var E={value:s,getSnapshot:a};return m.queue=E,AE(sE.bind(null,c,E,r),[r]),c.flags|=2048,Mu(9,pc(),uE.bind(null,c,E,s,a),null),s},useId:function(){var r=$n(),a=Mt.identifierPrefix;if(Tt){var s=Ci,c=vi;s=(c&~(1<<32-ze(c)-1)).toString(32)+s,a="«"+a+"R"+s,s=dc++,0<s&&(a+="H"+s.toString(32)),a+="»"}else s=I3++,a="«"+a+"r"+s.toString(32)+"»";return r.memoizedState=a},useHostTransitionStatus:Ch,useFormState:gE,useActionState:gE,useOptimistic:function(r){var a=$n();a.memoizedState=a.baseState=r;var s={pending:null,lanes:0,dispatch:null,lastRenderedReducer:null,lastRenderedState:null};return a.queue=s,a=_h.bind(null,it,!0,s),s.dispatch=a,[r,a]},useMemoCache:Eh,useCacheRefresh:function(){return $n().memoizedState=H3.bind(null,it)}},UE={readContext:Nn,use:hc,useCallback:xE,useContext:Nn,useEffect:SE,useImperativeHandle:_E,useInsertionEffect:DE,useLayoutEffect:vE,useMemo:RE,useReducer:mc,useRef:TE,useState:function(){return mc(Ri)},useDebugValue:Sh,useDeferredValue:function(r,a){var s=dn();return wE(s,Ct.memoizedState,r,a)},useTransition:function(){var r=mc(Ri)[0],a=dn().memoizedState;return[typeof r=="boolean"?r:Zs(r),a]},useSyncExternalStore:iE,useId:LE,useHostTransitionStatus:Ch,useFormState:EE,useActionState:EE,useOptimistic:function(r,a){var s=dn();return cE(s,Ct,r,a)},useMemoCache:Eh,useCacheRefresh:ME},V3={readContext:Nn,use:hc,useCallback:xE,useContext:Nn,useEffect:SE,useImperativeHandle:_E,useInsertionEffect:DE,useLayoutEffect:vE,useMemo:RE,useReducer:bh,useRef:TE,useState:function(){return bh(Ri)},useDebugValue:Sh,useDeferredValue:function(r,a){var s=dn();return Ct===null?Dh(s,r,a):wE(s,Ct.memoizedState,r,a)},useTransition:function(){var r=bh(Ri)[0],a=dn().memoizedState;return[typeof r=="boolean"?r:Zs(r),a]},useSyncExternalStore:iE,useId:LE,useHostTransitionStatus:Ch,useFormState:bE,useActionState:bE,useOptimistic:function(r,a){var s=dn();return Ct!==null?cE(s,Ct,r,a):(s.baseState=r,[r,s.queue.dispatch])},useMemoCache:Eh,useCacheRefresh:ME},Iu=null,to=0;function bc(r){var a=to;return to+=1,Iu===null&&(Iu=[]),Q1(Iu,r,a)}function no(r,a){a=a.props.ref,r.ref=a!==void 0?a:null}function Tc(r,a){throw a.$$typeof===g?Error(i(525)):(r=Object.prototype.toString.call(a),Error(i(31,r==="[object Object]"?"object with keys {"+Object.keys(a).join(", ")+"}":r)))}function HE(r){var a=r._init;return a(r._payload)}function zE(r){function a(ee,X){if(r){var re=ee.deletions;re===null?(ee.deletions=[X],ee.flags|=16):re.push(X)}}function s(ee,X){if(!r)return null;for(;X!==null;)a(ee,X),X=X.sibling;return null}function c(ee){for(var X=new Map;ee!==null;)ee.key!==null?X.set(ee.key,ee):X.set(ee.index,ee),ee=ee.sibling;return X}function m(ee,X){return ee=Di(ee,X),ee.index=0,ee.sibling=null,ee}function E(ee,X,re){return ee.index=re,r?(re=ee.alternate,re!==null?(re=re.index,re<X?(ee.flags|=67108866,X):re):(ee.flags|=67108866,X)):(ee.flags|=1048576,X)}function D(ee){return r&&ee.alternate===null&&(ee.flags|=67108866),ee}function x(ee,X,re,he){return X===null||X.tag!==6?(X=Xd(re,ee.mode,he),X.return=ee,X):(X=m(X,re),X.return=ee,X)}function H(ee,X,re,he){var Le=re.type;return Le===A?de(ee,X,re.props.children,he,re.key):X!==null&&(X.elementType===Le||typeof Le=="object"&&Le!==null&&Le.$$typeof===P&&HE(Le)===X.type)?(X=m(X,re.props),no(X,re),X.return=ee,X):(X=nc(re.type,re.key,re.props,null,ee.mode,he),no(X,re),X.return=ee,X)}function ae(ee,X,re,he){return X===null||X.tag!==4||X.stateNode.containerInfo!==re.containerInfo||X.stateNode.implementation!==re.implementation?(X=Kd(re,ee.mode,he),X.return=ee,X):(X=m(X,re.children||[]),X.return=ee,X)}function de(ee,X,re,he,Le){return X===null||X.tag!==7?(X=Ia(re,ee.mode,he,Le),X.return=ee,X):(X=m(X,re),X.return=ee,X)}function me(ee,X,re){if(typeof X=="string"&&X!==""||typeof X=="number"||typeof X=="bigint")return X=Xd(""+X,ee.mode,re),X.return=ee,X;if(typeof X=="object"&&X!==null){switch(X.$$typeof){case b:return re=nc(X.type,X.key,X.props,null,ee.mode,re),no(re,X),re.return=ee,re;case T:return X=Kd(X,ee.mode,re),X.return=ee,X;case P:var he=X._init;return X=he(X._payload),me(ee,X,re)}if(L(X)||F(X))return X=Ia(X,ee.mode,re,null),X.return=ee,X;if(typeof X.then=="function")return me(ee,bc(X),re);if(X.$$typeof===R)return me(ee,uc(ee,X),re);Tc(ee,X)}return null}function ue(ee,X,re,he){var Le=X!==null?X.key:null;if(typeof re=="string"&&re!==""||typeof re=="number"||typeof re=="bigint")return Le!==null?null:x(ee,X,""+re,he);if(typeof re=="object"&&re!==null){switch(re.$$typeof){case b:return re.key===Le?H(ee,X,re,he):null;case T:return re.key===Le?ae(ee,X,re,he):null;case P:return Le=re._init,re=Le(re._payload),ue(ee,X,re,he)}if(L(re)||F(re))return Le!==null?null:de(ee,X,re,he,null);if(typeof re.then=="function")return ue(ee,X,bc(re),he);if(re.$$typeof===R)return ue(ee,X,uc(ee,re),he);Tc(ee,re)}return null}function oe(ee,X,re,he,Le){if(typeof he=="string"&&he!==""||typeof he=="number"||typeof he=="bigint")return ee=ee.get(re)||null,x(X,ee,""+he,Le);if(typeof he=="object"&&he!==null){switch(he.$$typeof){case b:return ee=ee.get(he.key===null?re:he.key)||null,H(X,ee,he,Le);case T:return ee=ee.get(he.key===null?re:he.key)||null,ae(X,ee,he,Le);case P:var ut=he._init;return he=ut(he._payload),oe(ee,X,re,he,Le)}if(L(he)||F(he))return ee=ee.get(re)||null,de(X,ee,he,Le,null);if(typeof he.then=="function")return oe(ee,X,re,bc(he),Le);if(he.$$typeof===R)return oe(ee,X,re,uc(X,he),Le);Tc(X,he)}return null}function Xe(ee,X,re,he){for(var Le=null,ut=null,He=X,Ye=X=0,Sn=null;He!==null&&Ye<re.length;Ye++){He.index>Ye?(Sn=He,He=null):Sn=He.sibling;var bt=ue(ee,He,re[Ye],he);if(bt===null){He===null&&(He=Sn);break}r&&He&&bt.alternate===null&&a(ee,He),X=E(bt,X,Ye),ut===null?Le=bt:ut.sibling=bt,ut=bt,He=Sn}if(Ye===re.length)return s(ee,He),Tt&&Fa(ee,Ye),Le;if(He===null){for(;Ye<re.length;Ye++)He=me(ee,re[Ye],he),He!==null&&(X=E(He,X,Ye),ut===null?Le=He:ut.sibling=He,ut=He);return Tt&&Fa(ee,Ye),Le}for(He=c(He);Ye<re.length;Ye++)Sn=oe(He,ee,Ye,re[Ye],he),Sn!==null&&(r&&Sn.alternate!==null&&He.delete(Sn.key===null?Ye:Sn.key),X=E(Sn,X,Ye),ut===null?Le=Sn:ut.sibling=Sn,ut=Sn);return r&&He.forEach(function(fa){return a(ee,fa)}),Tt&&Fa(ee,Ye),Le}function qe(ee,X,re,he){if(re==null)throw Error(i(151));for(var Le=null,ut=null,He=X,Ye=X=0,Sn=null,bt=re.next();He!==null&&!bt.done;Ye++,bt=re.next()){He.index>Ye?(Sn=He,He=null):Sn=He.sibling;var fa=ue(ee,He,bt.value,he);if(fa===null){He===null&&(He=Sn);break}r&&He&&fa.alternate===null&&a(ee,He),X=E(fa,X,Ye),ut===null?Le=fa:ut.sibling=fa,ut=fa,He=Sn}if(bt.done)return s(ee,He),Tt&&Fa(ee,Ye),Le;if(He===null){for(;!bt.done;Ye++,bt=re.next())bt=me(ee,bt.value,he),bt!==null&&(X=E(bt,X,Ye),ut===null?Le=bt:ut.sibling=bt,ut=bt);return Tt&&Fa(ee,Ye),Le}for(He=c(He);!bt.done;Ye++,bt=re.next())bt=oe(He,ee,Ye,bt.value,he),bt!==null&&(r&&bt.alternate!==null&&He.delete(bt.key===null?Ye:bt.key),X=E(bt,X,Ye),ut===null?Le=bt:ut.sibling=bt,ut=bt);return r&&He.forEach(function(jR){return a(ee,jR)}),Tt&&Fa(ee,Ye),Le}function xt(ee,X,re,he){if(typeof re=="object"&&re!==null&&re.type===A&&re.key===null&&(re=re.props.children),typeof re=="object"&&re!==null){switch(re.$$typeof){case b:e:{for(var Le=re.key;X!==null;){if(X.key===Le){if(Le=re.type,Le===A){if(X.tag===7){s(ee,X.sibling),he=m(X,re.props.children),he.return=ee,ee=he;break e}}else if(X.elementType===Le||typeof Le=="object"&&Le!==null&&Le.$$typeof===P&&HE(Le)===X.type){s(ee,X.sibling),he=m(X,re.props),no(he,re),he.return=ee,ee=he;break e}s(ee,X);break}else a(ee,X);X=X.sibling}re.type===A?(he=Ia(re.props.children,ee.mode,he,re.key),he.return=ee,ee=he):(he=nc(re.type,re.key,re.props,null,ee.mode,he),no(he,re),he.return=ee,ee=he)}return D(ee);case T:e:{for(Le=re.key;X!==null;){if(X.key===Le)if(X.tag===4&&X.stateNode.containerInfo===re.containerInfo&&X.stateNode.implementation===re.implementation){s(ee,X.sibling),he=m(X,re.children||[]),he.return=ee,ee=he;break e}else{s(ee,X);break}else a(ee,X);X=X.sibling}he=Kd(re,ee.mode,he),he.return=ee,ee=he}return D(ee);case P:return Le=re._init,re=Le(re._payload),xt(ee,X,re,he)}if(L(re))return Xe(ee,X,re,he);if(F(re)){if(Le=F(re),typeof Le!="function")throw Error(i(150));return re=Le.call(re),qe(ee,X,re,he)}if(typeof re.then=="function")return xt(ee,X,bc(re),he);if(re.$$typeof===R)return xt(ee,X,uc(ee,re),he);Tc(ee,re)}return typeof re=="string"&&re!==""||typeof re=="number"||typeof re=="bigint"?(re=""+re,X!==null&&X.tag===6?(s(ee,X.sibling),he=m(X,re),he.return=ee,ee=he):(s(ee,X),he=Xd(re,ee.mode,he),he.return=ee,ee=he),D(ee)):s(ee,X)}return function(ee,X,re,he){try{to=0;var Le=xt(ee,X,re,he);return Iu=null,Le}catch(He){if(He===Gs||He===oc)throw He;var ut=lr(29,He,null,ee.mode);return ut.lanes=he,ut.return=ee,ut}finally{}}}var Pu=zE(!0),VE=zE(!1),Or=ne(null),si=null;function Qi(r){var a=r.alternate;w(yn,yn.current&1),w(Or,r),si===null&&(a===null||Nu.current!==null||a.memoizedState!==null)&&(si=r)}function jE(r){if(r.tag===22){if(w(yn,yn.current),w(Or,r),si===null){var a=r.alternate;a!==null&&a.memoizedState!==null&&(si=r)}}else $i()}function $i(){w(yn,yn.current),w(Or,Or.current)}function wi(r){ge(Or),si===r&&(si=null),ge(yn)}var yn=ne(0);function Ac(r){for(var a=r;a!==null;){if(a.tag===13){var s=a.memoizedState;if(s!==null&&(s=s.dehydrated,s===null||s.data==="$?"||gm(s)))return a}else if(a.tag===19&&a.memoizedProps.revealOrder!==void 0){if((a.flags&128)!==0)return a}else if(a.child!==null){a.child.return=a,a=a.child;continue}if(a===r)break;for(;a.sibling===null;){if(a.return===null||a.return===r)return null;a=a.return}a.sibling.return=a.return,a=a.sibling}return null}function xh(r,a,s,c){a=r.memoizedState,s=s(c,a),s=s==null?a:p({},a,s),r.memoizedState=s,r.lanes===0&&(r.updateQueue.baseState=s)}var Rh={enqueueSetState:function(r,a,s){r=r._reactInternals;var c=hr(),m=Xi(c);m.payload=a,s!=null&&(m.callback=s),a=Ki(r,m,c),a!==null&&(mr(a,r,c),Ks(a,r,c))},enqueueReplaceState:function(r,a,s){r=r._reactInternals;var c=hr(),m=Xi(c);m.tag=1,m.payload=a,s!=null&&(m.callback=s),a=Ki(r,m,c),a!==null&&(mr(a,r,c),Ks(a,r,c))},enqueueForceUpdate:function(r,a){r=r._reactInternals;var s=hr(),c=Xi(s);c.tag=2,a!=null&&(c.callback=a),a=Ki(r,c,s),a!==null&&(mr(a,r,s),Ks(a,r,s))}};function qE(r,a,s,c,m,E,D){return r=r.stateNode,typeof r.shouldComponentUpdate=="function"?r.shouldComponentUpdate(c,E,D):a.prototype&&a.prototype.isPureReactComponent?!Bs(s,c)||!Bs(m,E):!0}function YE(r,a,s,c){r=a.state,typeof a.componentWillReceiveProps=="function"&&a.componentWillReceiveProps(s,c),typeof a.UNSAFE_componentWillReceiveProps=="function"&&a.UNSAFE_componentWillReceiveProps(s,c),a.state!==r&&Rh.enqueueReplaceState(a,a.state,null)}function qa(r,a){var s=a;if("ref"in a){s={};for(var c in a)c!=="ref"&&(s[c]=a[c])}if(r=r.defaultProps){s===a&&(s=p({},s));for(var m in r)s[m]===void 0&&(s[m]=r[m])}return s}var Sc=typeof reportError=="function"?reportError:function(r){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var a=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof r=="object"&&r!==null&&typeof r.message=="string"?String(r.message):String(r),error:r});if(!window.dispatchEvent(a))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",r);return}console.error(r)};function GE(r){Sc(r)}function XE(r){console.error(r)}function KE(r){Sc(r)}function Dc(r,a){try{var s=r.onUncaughtError;s(a.value,{componentStack:a.stack})}catch(c){setTimeout(function(){throw c})}}function WE(r,a,s){try{var c=r.onCaughtError;c(s.value,{componentStack:s.stack,errorBoundary:a.tag===1?a.stateNode:null})}catch(m){setTimeout(function(){throw m})}}function wh(r,a,s){return s=Xi(s),s.tag=3,s.payload={element:null},s.callback=function(){Dc(r,a)},s}function QE(r){return r=Xi(r),r.tag=3,r}function $E(r,a,s,c){var m=s.type.getDerivedStateFromError;if(typeof m=="function"){var E=c.value;r.payload=function(){return m(E)},r.callback=function(){WE(a,s,c)}}var D=s.stateNode;D!==null&&typeof D.componentDidCatch=="function"&&(r.callback=function(){WE(a,s,c),typeof m!="function"&&(ra===null?ra=new Set([this]):ra.add(this));var x=c.stack;this.componentDidCatch(c.value,{componentStack:x!==null?x:""})})}function j3(r,a,s,c,m){if(s.flags|=32768,c!==null&&typeof c=="object"&&typeof c.then=="function"){if(a=s.alternate,a!==null&&js(a,s,m,!0),s=Or.current,s!==null){switch(s.tag){case 13:return si===null?Jh():s.alternate===null&&Jt===0&&(Jt=3),s.flags&=-257,s.flags|=65536,s.lanes=m,c===ih?s.flags|=16384:(a=s.updateQueue,a===null?s.updateQueue=new Set([c]):a.add(c),tm(r,c,m)),!1;case 22:return s.flags|=65536,c===ih?s.flags|=16384:(a=s.updateQueue,a===null?(a={transitions:null,markerInstances:null,retryQueue:new Set([c])},s.updateQueue=a):(s=a.retryQueue,s===null?a.retryQueue=new Set([c]):s.add(c)),tm(r,c,m)),!1}throw Error(i(435,s.tag))}return tm(r,c,m),Jh(),!1}if(Tt)return a=Or.current,a!==null?((a.flags&65536)===0&&(a.flags|=256),a.flags|=65536,a.lanes=m,c!==$d&&(r=Error(i(422),{cause:c}),Vs(_r(r,s)))):(c!==$d&&(a=Error(i(423),{cause:c}),Vs(_r(a,s))),r=r.current.alternate,r.flags|=65536,m&=-m,r.lanes|=m,c=_r(c,s),m=wh(r.stateNode,c,m),sh(r,m),Jt!==4&&(Jt=2)),!1;var E=Error(i(520),{cause:c});if(E=_r(E,s),lo===null?lo=[E]:lo.push(E),Jt!==4&&(Jt=2),a===null)return!0;c=_r(c,s),s=a;do{switch(s.tag){case 3:return s.flags|=65536,r=m&-m,s.lanes|=r,r=wh(s.stateNode,c,r),sh(s,r),!1;case 1:if(a=s.type,E=s.stateNode,(s.flags&128)===0&&(typeof a.getDerivedStateFromError=="function"||E!==null&&typeof E.componentDidCatch=="function"&&(ra===null||!ra.has(E))))return s.flags|=65536,m&=-m,s.lanes|=m,m=QE(m),$E(m,r,s,c),sh(s,m),!1}s=s.return}while(s!==null);return!1}var ZE=Error(i(461)),Tn=!1;function _n(r,a,s,c){a.child=r===null?VE(a,null,s,c):Pu(a,r.child,s,c)}function JE(r,a,s,c,m){s=s.render;var E=a.ref;if("ref"in c){var D={};for(var x in c)x!=="ref"&&(D[x]=c[x])}else D=c;return za(a),c=dh(r,a,s,D,E,m),x=hh(),r!==null&&!Tn?(mh(r,a,m),Oi(r,a,m)):(Tt&&x&&Wd(a),a.flags|=1,_n(r,a,c,m),a.child)}function ey(r,a,s,c,m){if(r===null){var E=s.type;return typeof E=="function"&&!Gd(E)&&E.defaultProps===void 0&&s.compare===null?(a.tag=15,a.type=E,ty(r,a,E,c,m)):(r=nc(s.type,null,c,a,a.mode,m),r.ref=a.ref,r.return=a,a.child=r)}if(E=r.child,!Fh(r,m)){var D=E.memoizedProps;if(s=s.compare,s=s!==null?s:Bs,s(D,c)&&r.ref===a.ref)return Oi(r,a,m)}return a.flags|=1,r=Di(E,c),r.ref=a.ref,r.return=a,a.child=r}function ty(r,a,s,c,m){if(r!==null){var E=r.memoizedProps;if(Bs(E,c)&&r.ref===a.ref)if(Tn=!1,a.pendingProps=c=E,Fh(r,m))(r.flags&131072)!==0&&(Tn=!0);else return a.lanes=r.lanes,Oi(r,a,m)}return Oh(r,a,s,c,m)}function ny(r,a,s){var c=a.pendingProps,m=c.children,E=r!==null?r.memoizedState:null;if(c.mode==="hidden"){if((a.flags&128)!==0){if(c=E!==null?E.baseLanes|s:s,r!==null){for(m=a.child=r.child,E=0;m!==null;)E=E|m.lanes|m.childLanes,m=m.sibling;a.childLanes=E&~c}else a.childLanes=0,a.child=null;return ry(r,a,c,s)}if((s&536870912)!==0)a.memoizedState={baseLanes:0,cachePool:null},r!==null&&sc(a,E!==null?E.cachePool:null),E!==null?tE(a,E):lh(),jE(a);else return a.lanes=a.childLanes=536870912,ry(r,a,E!==null?E.baseLanes|s:s,s)}else E!==null?(sc(a,E.cachePool),tE(a,E),$i(),a.memoizedState=null):(r!==null&&sc(a,null),lh(),$i());return _n(r,a,m,s),a.child}function ry(r,a,s,c){var m=rh();return m=m===null?null:{parent:En._currentValue,pool:m},a.memoizedState={baseLanes:s,cachePool:m},r!==null&&sc(a,null),lh(),jE(a),r!==null&&js(r,a,c,!0),null}function vc(r,a){var s=a.ref;if(s===null)r!==null&&r.ref!==null&&(a.flags|=4194816);else{if(typeof s!="function"&&typeof s!="object")throw Error(i(284));(r===null||r.ref!==s)&&(a.flags|=4194816)}}function Oh(r,a,s,c,m){return za(a),s=dh(r,a,s,c,void 0,m),c=hh(),r!==null&&!Tn?(mh(r,a,m),Oi(r,a,m)):(Tt&&c&&Wd(a),a.flags|=1,_n(r,a,s,m),a.child)}function iy(r,a,s,c,m,E){return za(a),a.updateQueue=null,s=rE(a,c,s,m),nE(r),c=hh(),r!==null&&!Tn?(mh(r,a,E),Oi(r,a,E)):(Tt&&c&&Wd(a),a.flags|=1,_n(r,a,s,E),a.child)}function ay(r,a,s,c,m){if(za(a),a.stateNode===null){var E=_u,D=s.contextType;typeof D=="object"&&D!==null&&(E=Nn(D)),E=new s(c,E),a.memoizedState=E.state!==null&&E.state!==void 0?E.state:null,E.updater=Rh,a.stateNode=E,E._reactInternals=a,E=a.stateNode,E.props=c,E.state=a.memoizedState,E.refs={},ah(a),D=s.contextType,E.context=typeof D=="object"&&D!==null?Nn(D):_u,E.state=a.memoizedState,D=s.getDerivedStateFromProps,typeof D=="function"&&(xh(a,s,D,c),E.state=a.memoizedState),typeof s.getDerivedStateFromProps=="function"||typeof E.getSnapshotBeforeUpdate=="function"||typeof E.UNSAFE_componentWillMount!="function"&&typeof E.componentWillMount!="function"||(D=E.state,typeof E.componentWillMount=="function"&&E.componentWillMount(),typeof E.UNSAFE_componentWillMount=="function"&&E.UNSAFE_componentWillMount(),D!==E.state&&Rh.enqueueReplaceState(E,E.state,null),Qs(a,c,E,m),Ws(),E.state=a.memoizedState),typeof E.componentDidMount=="function"&&(a.flags|=4194308),c=!0}else if(r===null){E=a.stateNode;var x=a.memoizedProps,H=qa(s,x);E.props=H;var ae=E.context,de=s.contextType;D=_u,typeof de=="object"&&de!==null&&(D=Nn(de));var me=s.getDerivedStateFromProps;de=typeof me=="function"||typeof E.getSnapshotBeforeUpdate=="function",x=a.pendingProps!==x,de||typeof E.UNSAFE_componentWillReceiveProps!="function"&&typeof E.componentWillReceiveProps!="function"||(x||ae!==D)&&YE(a,E,c,D),Gi=!1;var ue=a.memoizedState;E.state=ue,Qs(a,c,E,m),Ws(),ae=a.memoizedState,x||ue!==ae||Gi?(typeof me=="function"&&(xh(a,s,me,c),ae=a.memoizedState),(H=Gi||qE(a,s,H,c,ue,ae,D))?(de||typeof E.UNSAFE_componentWillMount!="function"&&typeof E.componentWillMount!="function"||(typeof E.componentWillMount=="function"&&E.componentWillMount(),typeof E.UNSAFE_componentWillMount=="function"&&E.UNSAFE_componentWillMount()),typeof E.componentDidMount=="function"&&(a.flags|=4194308)):(typeof E.componentDidMount=="function"&&(a.flags|=4194308),a.memoizedProps=c,a.memoizedState=ae),E.props=c,E.state=ae,E.context=D,c=H):(typeof E.componentDidMount=="function"&&(a.flags|=4194308),c=!1)}else{E=a.stateNode,uh(r,a),D=a.memoizedProps,de=qa(s,D),E.props=de,me=a.pendingProps,ue=E.context,ae=s.contextType,H=_u,typeof ae=="object"&&ae!==null&&(H=Nn(ae)),x=s.getDerivedStateFromProps,(ae=typeof x=="function"||typeof E.getSnapshotBeforeUpdate=="function")||typeof E.UNSAFE_componentWillReceiveProps!="function"&&typeof E.componentWillReceiveProps!="function"||(D!==me||ue!==H)&&YE(a,E,c,H),Gi=!1,ue=a.memoizedState,E.state=ue,Qs(a,c,E,m),Ws();var oe=a.memoizedState;D!==me||ue!==oe||Gi||r!==null&&r.dependencies!==null&&ac(r.dependencies)?(typeof x=="function"&&(xh(a,s,x,c),oe=a.memoizedState),(de=Gi||qE(a,s,de,c,ue,oe,H)||r!==null&&r.dependencies!==null&&ac(r.dependencies))?(ae||typeof E.UNSAFE_componentWillUpdate!="function"&&typeof E.componentWillUpdate!="function"||(typeof E.componentWillUpdate=="function"&&E.componentWillUpdate(c,oe,H),typeof E.UNSAFE_componentWillUpdate=="function"&&E.UNSAFE_componentWillUpdate(c,oe,H)),typeof E.componentDidUpdate=="function"&&(a.flags|=4),typeof E.getSnapshotBeforeUpdate=="function"&&(a.flags|=1024)):(typeof E.componentDidUpdate!="function"||D===r.memoizedProps&&ue===r.memoizedState||(a.flags|=4),typeof E.getSnapshotBeforeUpdate!="function"||D===r.memoizedProps&&ue===r.memoizedState||(a.flags|=1024),a.memoizedProps=c,a.memoizedState=oe),E.props=c,E.state=oe,E.context=H,c=de):(typeof E.componentDidUpdate!="function"||D===r.memoizedProps&&ue===r.memoizedState||(a.flags|=4),typeof E.getSnapshotBeforeUpdate!="function"||D===r.memoizedProps&&ue===r.memoizedState||(a.flags|=1024),c=!1)}return E=c,vc(r,a),c=(a.flags&128)!==0,E||c?(E=a.stateNode,s=c&&typeof s.getDerivedStateFromError!="function"?null:E.render(),a.flags|=1,r!==null&&c?(a.child=Pu(a,r.child,null,m),a.child=Pu(a,null,s,m)):_n(r,a,s,m),a.memoizedState=E.state,r=a.child):r=Oi(r,a,m),r}function uy(r,a,s,c){return zs(),a.flags|=256,_n(r,a,s,c),a.child}var Nh={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function kh(r){return{baseLanes:r,cachePool:X1()}}function Lh(r,a,s){return r=r!==null?r.childLanes&~s:0,a&&(r|=Nr),r}function sy(r,a,s){var c=a.pendingProps,m=!1,E=(a.flags&128)!==0,D;if((D=E)||(D=r!==null&&r.memoizedState===null?!1:(yn.current&2)!==0),D&&(m=!0,a.flags&=-129),D=(a.flags&32)!==0,a.flags&=-33,r===null){if(Tt){if(m?Qi(a):$i(),Tt){var x=Zt,H;if(H=x){e:{for(H=x,x=ui;H.nodeType!==8;){if(!x){x=null;break e}if(H=Xr(H.nextSibling),H===null){x=null;break e}}x=H}x!==null?(a.memoizedState={dehydrated:x,treeContext:Pa!==null?{id:vi,overflow:Ci}:null,retryLane:536870912,hydrationErrors:null},H=lr(18,null,null,0),H.stateNode=x,H.return=a,a.child=H,Un=a,Zt=null,H=!0):H=!1}H||Ua(a)}if(x=a.memoizedState,x!==null&&(x=x.dehydrated,x!==null))return gm(x)?a.lanes=32:a.lanes=536870912,null;wi(a)}return x=c.children,c=c.fallback,m?($i(),m=a.mode,x=Cc({mode:"hidden",children:x},m),c=Ia(c,m,s,null),x.return=a,c.return=a,x.sibling=c,a.child=x,m=a.child,m.memoizedState=kh(s),m.childLanes=Lh(r,D,s),a.memoizedState=Nh,c):(Qi(a),Mh(a,x))}if(H=r.memoizedState,H!==null&&(x=H.dehydrated,x!==null)){if(E)a.flags&256?(Qi(a),a.flags&=-257,a=Ih(r,a,s)):a.memoizedState!==null?($i(),a.child=r.child,a.flags|=128,a=null):($i(),m=c.fallback,x=a.mode,c=Cc({mode:"visible",children:c.children},x),m=Ia(m,x,s,null),m.flags|=2,c.return=a,m.return=a,c.sibling=m,a.child=c,Pu(a,r.child,null,s),c=a.child,c.memoizedState=kh(s),c.childLanes=Lh(r,D,s),a.memoizedState=Nh,a=m);else if(Qi(a),gm(x)){if(D=x.nextSibling&&x.nextSibling.dataset,D)var ae=D.dgst;D=ae,c=Error(i(419)),c.stack="",c.digest=D,Vs({value:c,source:null,stack:null}),a=Ih(r,a,s)}else if(Tn||js(r,a,s,!1),D=(s&r.childLanes)!==0,Tn||D){if(D=Mt,D!==null&&(c=s&-s,c=(c&42)!==0?1:vr(c),c=(c&(D.suspendedLanes|s))!==0?0:c,c!==0&&c!==H.retryLane))throw H.retryLane=c,Cu(r,c),mr(D,r,c),ZE;x.data==="$?"||Jh(),a=Ih(r,a,s)}else x.data==="$?"?(a.flags|=192,a.child=r.child,a=null):(r=H.treeContext,Zt=Xr(x.nextSibling),Un=a,Tt=!0,Ba=null,ui=!1,r!==null&&(Rr[wr++]=vi,Rr[wr++]=Ci,Rr[wr++]=Pa,vi=r.id,Ci=r.overflow,Pa=a),a=Mh(a,c.children),a.flags|=4096);return a}return m?($i(),m=c.fallback,x=a.mode,H=r.child,ae=H.sibling,c=Di(H,{mode:"hidden",children:c.children}),c.subtreeFlags=H.subtreeFlags&65011712,ae!==null?m=Di(ae,m):(m=Ia(m,x,s,null),m.flags|=2),m.return=a,c.return=a,c.sibling=m,a.child=c,c=m,m=a.child,x=r.child.memoizedState,x===null?x=kh(s):(H=x.cachePool,H!==null?(ae=En._currentValue,H=H.parent!==ae?{parent:ae,pool:ae}:H):H=X1(),x={baseLanes:x.baseLanes|s,cachePool:H}),m.memoizedState=x,m.childLanes=Lh(r,D,s),a.memoizedState=Nh,c):(Qi(a),s=r.child,r=s.sibling,s=Di(s,{mode:"visible",children:c.children}),s.return=a,s.sibling=null,r!==null&&(D=a.deletions,D===null?(a.deletions=[r],a.flags|=16):D.push(r)),a.child=s,a.memoizedState=null,s)}function Mh(r,a){return a=Cc({mode:"visible",children:a},r.mode),a.return=r,r.child=a}function Cc(r,a){return r=lr(22,r,null,a),r.lanes=0,r.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null},r}function Ih(r,a,s){return Pu(a,r.child,null,s),r=Mh(a,a.pendingProps.children),r.flags|=2,a.memoizedState=null,r}function oy(r,a,s){r.lanes|=a;var c=r.alternate;c!==null&&(c.lanes|=a),Jd(r.return,a,s)}function Ph(r,a,s,c,m){var E=r.memoizedState;E===null?r.memoizedState={isBackwards:a,rendering:null,renderingStartTime:0,last:c,tail:s,tailMode:m}:(E.isBackwards=a,E.rendering=null,E.renderingStartTime=0,E.last=c,E.tail=s,E.tailMode=m)}function ly(r,a,s){var c=a.pendingProps,m=c.revealOrder,E=c.tail;if(_n(r,a,c.children,s),c=yn.current,(c&2)!==0)c=c&1|2,a.flags|=128;else{if(r!==null&&(r.flags&128)!==0)e:for(r=a.child;r!==null;){if(r.tag===13)r.memoizedState!==null&&oy(r,s,a);else if(r.tag===19)oy(r,s,a);else if(r.child!==null){r.child.return=r,r=r.child;continue}if(r===a)break e;for(;r.sibling===null;){if(r.return===null||r.return===a)break e;r=r.return}r.sibling.return=r.return,r=r.sibling}c&=1}switch(w(yn,c),m){case"forwards":for(s=a.child,m=null;s!==null;)r=s.alternate,r!==null&&Ac(r)===null&&(m=s),s=s.sibling;s=m,s===null?(m=a.child,a.child=null):(m=s.sibling,s.sibling=null),Ph(a,!1,m,s,E);break;case"backwards":for(s=null,m=a.child,a.child=null;m!==null;){if(r=m.alternate,r!==null&&Ac(r)===null){a.child=m;break}r=m.sibling,m.sibling=s,s=m,m=r}Ph(a,!0,s,null,E);break;case"together":Ph(a,!1,null,null,void 0);break;default:a.memoizedState=null}return a.child}function Oi(r,a,s){if(r!==null&&(a.dependencies=r.dependencies),na|=a.lanes,(s&a.childLanes)===0)if(r!==null){if(js(r,a,s,!1),(s&a.childLanes)===0)return null}else return null;if(r!==null&&a.child!==r.child)throw Error(i(153));if(a.child!==null){for(r=a.child,s=Di(r,r.pendingProps),a.child=s,s.return=a;r.sibling!==null;)r=r.sibling,s=s.sibling=Di(r,r.pendingProps),s.return=a;s.sibling=null}return a.child}function Fh(r,a){return(r.lanes&a)!==0?!0:(r=r.dependencies,!!(r!==null&&ac(r)))}function q3(r,a,s){switch(a.tag){case 3:Qe(a,a.stateNode.containerInfo),Yi(a,En,r.memoizedState.cache),zs();break;case 27:case 5:mt(a);break;case 4:Qe(a,a.stateNode.containerInfo);break;case 10:Yi(a,a.type,a.memoizedProps.value);break;case 13:var c=a.memoizedState;if(c!==null)return c.dehydrated!==null?(Qi(a),a.flags|=128,null):(s&a.child.childLanes)!==0?sy(r,a,s):(Qi(a),r=Oi(r,a,s),r!==null?r.sibling:null);Qi(a);break;case 19:var m=(r.flags&128)!==0;if(c=(s&a.childLanes)!==0,c||(js(r,a,s,!1),c=(s&a.childLanes)!==0),m){if(c)return ly(r,a,s);a.flags|=128}if(m=a.memoizedState,m!==null&&(m.rendering=null,m.tail=null,m.lastEffect=null),w(yn,yn.current),c)break;return null;case 22:case 23:return a.lanes=0,ny(r,a,s);case 24:Yi(a,En,r.memoizedState.cache)}return Oi(r,a,s)}function cy(r,a,s){if(r!==null)if(r.memoizedProps!==a.pendingProps)Tn=!0;else{if(!Fh(r,s)&&(a.flags&128)===0)return Tn=!1,q3(r,a,s);Tn=(r.flags&131072)!==0}else Tn=!1,Tt&&(a.flags&1048576)!==0&&H1(a,ic,a.index);switch(a.lanes=0,a.tag){case 16:e:{r=a.pendingProps;var c=a.elementType,m=c._init;if(c=m(c._payload),a.type=c,typeof c=="function")Gd(c)?(r=qa(c,r),a.tag=1,a=ay(null,a,c,r,s)):(a.tag=0,a=Oh(null,a,c,r,s));else{if(c!=null){if(m=c.$$typeof,m===Y){a.tag=11,a=JE(null,a,c,r,s);break e}else if(m===J){a.tag=14,a=ey(null,a,c,r,s);break e}}throw a=Z(c)||c,Error(i(306,a,""))}}return a;case 0:return Oh(r,a,a.type,a.pendingProps,s);case 1:return c=a.type,m=qa(c,a.pendingProps),ay(r,a,c,m,s);case 3:e:{if(Qe(a,a.stateNode.containerInfo),r===null)throw Error(i(387));c=a.pendingProps;var E=a.memoizedState;m=E.element,uh(r,a),Qs(a,c,null,s);var D=a.memoizedState;if(c=D.cache,Yi(a,En,c),c!==E.cache&&eh(a,[En],s,!0),Ws(),c=D.element,E.isDehydrated)if(E={element:c,isDehydrated:!1,cache:D.cache},a.updateQueue.baseState=E,a.memoizedState=E,a.flags&256){a=uy(r,a,c,s);break e}else if(c!==m){m=_r(Error(i(424)),a),Vs(m),a=uy(r,a,c,s);break e}else{switch(r=a.stateNode.containerInfo,r.nodeType){case 9:r=r.body;break;default:r=r.nodeName==="HTML"?r.ownerDocument.body:r}for(Zt=Xr(r.firstChild),Un=a,Tt=!0,Ba=null,ui=!0,s=VE(a,null,c,s),a.child=s;s;)s.flags=s.flags&-3|4096,s=s.sibling}else{if(zs(),c===m){a=Oi(r,a,s);break e}_n(r,a,c,s)}a=a.child}return a;case 26:return vc(r,a),r===null?(s=mb(a.type,null,a.pendingProps,null))?a.memoizedState=s:Tt||(s=a.type,r=a.pendingProps,c=Uc(xe.current).createElement(s),c[pe]=a,c[Ce]=r,Rn(c,s,r),pt(c),a.stateNode=c):a.memoizedState=mb(a.type,r.memoizedProps,a.pendingProps,r.memoizedState),null;case 27:return mt(a),r===null&&Tt&&(c=a.stateNode=fb(a.type,a.pendingProps,xe.current),Un=a,ui=!0,m=Zt,ua(a.type)?(Em=m,Zt=Xr(c.firstChild)):Zt=m),_n(r,a,a.pendingProps.children,s),vc(r,a),r===null&&(a.flags|=4194304),a.child;case 5:return r===null&&Tt&&((m=c=Zt)&&(c=yR(c,a.type,a.pendingProps,ui),c!==null?(a.stateNode=c,Un=a,Zt=Xr(c.firstChild),ui=!1,m=!0):m=!1),m||Ua(a)),mt(a),m=a.type,E=a.pendingProps,D=r!==null?r.memoizedProps:null,c=E.children,hm(m,E)?c=null:D!==null&&hm(m,D)&&(a.flags|=32),a.memoizedState!==null&&(m=dh(r,a,P3,null,null,s),bo._currentValue=m),vc(r,a),_n(r,a,c,s),a.child;case 6:return r===null&&Tt&&((r=s=Zt)&&(s=bR(s,a.pendingProps,ui),s!==null?(a.stateNode=s,Un=a,Zt=null,r=!0):r=!1),r||Ua(a)),null;case 13:return sy(r,a,s);case 4:return Qe(a,a.stateNode.containerInfo),c=a.pendingProps,r===null?a.child=Pu(a,null,c,s):_n(r,a,c,s),a.child;case 11:return JE(r,a,a.type,a.pendingProps,s);case 7:return _n(r,a,a.pendingProps,s),a.child;case 8:return _n(r,a,a.pendingProps.children,s),a.child;case 12:return _n(r,a,a.pendingProps.children,s),a.child;case 10:return c=a.pendingProps,Yi(a,a.type,c.value),_n(r,a,c.children,s),a.child;case 9:return m=a.type._context,c=a.pendingProps.children,za(a),m=Nn(m),c=c(m),a.flags|=1,_n(r,a,c,s),a.child;case 14:return ey(r,a,a.type,a.pendingProps,s);case 15:return ty(r,a,a.type,a.pendingProps,s);case 19:return ly(r,a,s);case 31:return c=a.pendingProps,s=a.mode,c={mode:c.mode,children:c.children},r===null?(s=Cc(c,s),s.ref=a.ref,a.child=s,s.return=a,a=s):(s=Di(r.child,c),s.ref=a.ref,a.child=s,s.return=a,a=s),a;case 22:return ny(r,a,s);case 24:return za(a),c=Nn(En),r===null?(m=rh(),m===null&&(m=Mt,E=th(),m.pooledCache=E,E.refCount++,E!==null&&(m.pooledCacheLanes|=s),m=E),a.memoizedState={parent:c,cache:m},ah(a),Yi(a,En,m)):((r.lanes&s)!==0&&(uh(r,a),Qs(a,null,null,s),Ws()),m=r.memoizedState,E=a.memoizedState,m.parent!==c?(m={parent:c,cache:c},a.memoizedState=m,a.lanes===0&&(a.memoizedState=a.updateQueue.baseState=m),Yi(a,En,c)):(c=E.cache,Yi(a,En,c),c!==m.cache&&eh(a,[En],s,!0))),_n(r,a,a.pendingProps.children,s),a.child;case 29:throw a.pendingProps}throw Error(i(156,a.tag))}function Ni(r){r.flags|=4}function fy(r,a){if(a.type!=="stylesheet"||(a.state.loading&4)!==0)r.flags&=-16777217;else if(r.flags|=16777216,!bb(a)){if(a=Or.current,a!==null&&((gt&4194048)===gt?si!==null:(gt&62914560)!==gt&&(gt&536870912)===0||a!==si))throw Xs=ih,K1;r.flags|=8192}}function _c(r,a){a!==null&&(r.flags|=4),r.flags&16384&&(a=r.tag!==22?Ti():536870912,r.lanes|=a,Hu|=a)}function ro(r,a){if(!Tt)switch(r.tailMode){case"hidden":a=r.tail;for(var s=null;a!==null;)a.alternate!==null&&(s=a),a=a.sibling;s===null?r.tail=null:s.sibling=null;break;case"collapsed":s=r.tail;for(var c=null;s!==null;)s.alternate!==null&&(c=s),s=s.sibling;c===null?a||r.tail===null?r.tail=null:r.tail.sibling=null:c.sibling=null}}function Xt(r){var a=r.alternate!==null&&r.alternate.child===r.child,s=0,c=0;if(a)for(var m=r.child;m!==null;)s|=m.lanes|m.childLanes,c|=m.subtreeFlags&65011712,c|=m.flags&65011712,m.return=r,m=m.sibling;else for(m=r.child;m!==null;)s|=m.lanes|m.childLanes,c|=m.subtreeFlags,c|=m.flags,m.return=r,m=m.sibling;return r.subtreeFlags|=c,r.childLanes=s,a}function Y3(r,a,s){var c=a.pendingProps;switch(Qd(a),a.tag){case 31:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Xt(a),null;case 1:return Xt(a),null;case 3:return s=a.stateNode,c=null,r!==null&&(c=r.memoizedState.cache),a.memoizedState.cache!==c&&(a.flags|=2048),xi(En),Nt(),s.pendingContext&&(s.context=s.pendingContext,s.pendingContext=null),(r===null||r.child===null)&&(Hs(a)?Ni(a):r===null||r.memoizedState.isDehydrated&&(a.flags&256)===0||(a.flags|=1024,j1())),Xt(a),null;case 26:return s=a.memoizedState,r===null?(Ni(a),s!==null?(Xt(a),fy(a,s)):(Xt(a),a.flags&=-16777217)):s?s!==r.memoizedState?(Ni(a),Xt(a),fy(a,s)):(Xt(a),a.flags&=-16777217):(r.memoizedProps!==c&&Ni(a),Xt(a),a.flags&=-16777217),null;case 27:qt(a),s=xe.current;var m=a.type;if(r!==null&&a.stateNode!=null)r.memoizedProps!==c&&Ni(a);else{if(!c){if(a.stateNode===null)throw Error(i(166));return Xt(a),null}r=Te.current,Hs(a)?z1(a):(r=fb(m,c,s),a.stateNode=r,Ni(a))}return Xt(a),null;case 5:if(qt(a),s=a.type,r!==null&&a.stateNode!=null)r.memoizedProps!==c&&Ni(a);else{if(!c){if(a.stateNode===null)throw Error(i(166));return Xt(a),null}if(r=Te.current,Hs(a))z1(a);else{switch(m=Uc(xe.current),r){case 1:r=m.createElementNS("http://www.w3.org/2000/svg",s);break;case 2:r=m.createElementNS("http://www.w3.org/1998/Math/MathML",s);break;default:switch(s){case"svg":r=m.createElementNS("http://www.w3.org/2000/svg",s);break;case"math":r=m.createElementNS("http://www.w3.org/1998/Math/MathML",s);break;case"script":r=m.createElement("div"),r.innerHTML="<script><\/script>",r=r.removeChild(r.firstChild);break;case"select":r=typeof c.is=="string"?m.createElement("select",{is:c.is}):m.createElement("select"),c.multiple?r.multiple=!0:c.size&&(r.size=c.size);break;default:r=typeof c.is=="string"?m.createElement(s,{is:c.is}):m.createElement(s)}}r[pe]=a,r[Ce]=c;e:for(m=a.child;m!==null;){if(m.tag===5||m.tag===6)r.appendChild(m.stateNode);else if(m.tag!==4&&m.tag!==27&&m.child!==null){m.child.return=m,m=m.child;continue}if(m===a)break e;for(;m.sibling===null;){if(m.return===null||m.return===a)break e;m=m.return}m.sibling.return=m.return,m=m.sibling}a.stateNode=r;e:switch(Rn(r,s,c),s){case"button":case"input":case"select":case"textarea":r=!!c.autoFocus;break e;case"img":r=!0;break e;default:r=!1}r&&Ni(a)}}return Xt(a),a.flags&=-16777217,null;case 6:if(r&&a.stateNode!=null)r.memoizedProps!==c&&Ni(a);else{if(typeof c!="string"&&a.stateNode===null)throw Error(i(166));if(r=xe.current,Hs(a)){if(r=a.stateNode,s=a.memoizedProps,c=null,m=Un,m!==null)switch(m.tag){case 27:case 5:c=m.memoizedProps}r[pe]=a,r=!!(r.nodeValue===s||c!==null&&c.suppressHydrationWarning===!0||ib(r.nodeValue,s)),r||Ua(a)}else r=Uc(r).createTextNode(c),r[pe]=a,a.stateNode=r}return Xt(a),null;case 13:if(c=a.memoizedState,r===null||r.memoizedState!==null&&r.memoizedState.dehydrated!==null){if(m=Hs(a),c!==null&&c.dehydrated!==null){if(r===null){if(!m)throw Error(i(318));if(m=a.memoizedState,m=m!==null?m.dehydrated:null,!m)throw Error(i(317));m[pe]=a}else zs(),(a.flags&128)===0&&(a.memoizedState=null),a.flags|=4;Xt(a),m=!1}else m=j1(),r!==null&&r.memoizedState!==null&&(r.memoizedState.hydrationErrors=m),m=!0;if(!m)return a.flags&256?(wi(a),a):(wi(a),null)}if(wi(a),(a.flags&128)!==0)return a.lanes=s,a;if(s=c!==null,r=r!==null&&r.memoizedState!==null,s){c=a.child,m=null,c.alternate!==null&&c.alternate.memoizedState!==null&&c.alternate.memoizedState.cachePool!==null&&(m=c.alternate.memoizedState.cachePool.pool);var E=null;c.memoizedState!==null&&c.memoizedState.cachePool!==null&&(E=c.memoizedState.cachePool.pool),E!==m&&(c.flags|=2048)}return s!==r&&s&&(a.child.flags|=8192),_c(a,a.updateQueue),Xt(a),null;case 4:return Nt(),r===null&&om(a.stateNode.containerInfo),Xt(a),null;case 10:return xi(a.type),Xt(a),null;case 19:if(ge(yn),m=a.memoizedState,m===null)return Xt(a),null;if(c=(a.flags&128)!==0,E=m.rendering,E===null)if(c)ro(m,!1);else{if(Jt!==0||r!==null&&(r.flags&128)!==0)for(r=a.child;r!==null;){if(E=Ac(r),E!==null){for(a.flags|=128,ro(m,!1),r=E.updateQueue,a.updateQueue=r,_c(a,r),a.subtreeFlags=0,r=s,s=a.child;s!==null;)U1(s,r),s=s.sibling;return w(yn,yn.current&1|2),a.child}r=r.sibling}m.tail!==null&&Yt()>wc&&(a.flags|=128,c=!0,ro(m,!1),a.lanes=4194304)}else{if(!c)if(r=Ac(E),r!==null){if(a.flags|=128,c=!0,r=r.updateQueue,a.updateQueue=r,_c(a,r),ro(m,!0),m.tail===null&&m.tailMode==="hidden"&&!E.alternate&&!Tt)return Xt(a),null}else 2*Yt()-m.renderingStartTime>wc&&s!==536870912&&(a.flags|=128,c=!0,ro(m,!1),a.lanes=4194304);m.isBackwards?(E.sibling=a.child,a.child=E):(r=m.last,r!==null?r.sibling=E:a.child=E,m.last=E)}return m.tail!==null?(a=m.tail,m.rendering=a,m.tail=a.sibling,m.renderingStartTime=Yt(),a.sibling=null,r=yn.current,w(yn,c?r&1|2:r&1),a):(Xt(a),null);case 22:case 23:return wi(a),ch(),c=a.memoizedState!==null,r!==null?r.memoizedState!==null!==c&&(a.flags|=8192):c&&(a.flags|=8192),c?(s&536870912)!==0&&(a.flags&128)===0&&(Xt(a),a.subtreeFlags&6&&(a.flags|=8192)):Xt(a),s=a.updateQueue,s!==null&&_c(a,s.retryQueue),s=null,r!==null&&r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(s=r.memoizedState.cachePool.pool),c=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(c=a.memoizedState.cachePool.pool),c!==s&&(a.flags|=2048),r!==null&&ge(Va),null;case 24:return s=null,r!==null&&(s=r.memoizedState.cache),a.memoizedState.cache!==s&&(a.flags|=2048),xi(En),Xt(a),null;case 25:return null;case 30:return null}throw Error(i(156,a.tag))}function G3(r,a){switch(Qd(a),a.tag){case 1:return r=a.flags,r&65536?(a.flags=r&-65537|128,a):null;case 3:return xi(En),Nt(),r=a.flags,(r&65536)!==0&&(r&128)===0?(a.flags=r&-65537|128,a):null;case 26:case 27:case 5:return qt(a),null;case 13:if(wi(a),r=a.memoizedState,r!==null&&r.dehydrated!==null){if(a.alternate===null)throw Error(i(340));zs()}return r=a.flags,r&65536?(a.flags=r&-65537|128,a):null;case 19:return ge(yn),null;case 4:return Nt(),null;case 10:return xi(a.type),null;case 22:case 23:return wi(a),ch(),r!==null&&ge(Va),r=a.flags,r&65536?(a.flags=r&-65537|128,a):null;case 24:return xi(En),null;case 25:return null;default:return null}}function dy(r,a){switch(Qd(a),a.tag){case 3:xi(En),Nt();break;case 26:case 27:case 5:qt(a);break;case 4:Nt();break;case 13:wi(a);break;case 19:ge(yn);break;case 10:xi(a.type);break;case 22:case 23:wi(a),ch(),r!==null&&ge(Va);break;case 24:xi(En)}}function io(r,a){try{var s=a.updateQueue,c=s!==null?s.lastEffect:null;if(c!==null){var m=c.next;s=m;do{if((s.tag&r)===r){c=void 0;var E=s.create,D=s.inst;c=E(),D.destroy=c}s=s.next}while(s!==m)}}catch(x){Rt(a,a.return,x)}}function Zi(r,a,s){try{var c=a.updateQueue,m=c!==null?c.lastEffect:null;if(m!==null){var E=m.next;c=E;do{if((c.tag&r)===r){var D=c.inst,x=D.destroy;if(x!==void 0){D.destroy=void 0,m=a;var H=s,ae=x;try{ae()}catch(de){Rt(m,H,de)}}}c=c.next}while(c!==E)}}catch(de){Rt(a,a.return,de)}}function hy(r){var a=r.updateQueue;if(a!==null){var s=r.stateNode;try{eE(a,s)}catch(c){Rt(r,r.return,c)}}}function my(r,a,s){s.props=qa(r.type,r.memoizedProps),s.state=r.memoizedState;try{s.componentWillUnmount()}catch(c){Rt(r,a,c)}}function ao(r,a){try{var s=r.ref;if(s!==null){switch(r.tag){case 26:case 27:case 5:var c=r.stateNode;break;case 30:c=r.stateNode;break;default:c=r.stateNode}typeof s=="function"?r.refCleanup=s(c):s.current=c}}catch(m){Rt(r,a,m)}}function oi(r,a){var s=r.ref,c=r.refCleanup;if(s!==null)if(typeof c=="function")try{c()}catch(m){Rt(r,a,m)}finally{r.refCleanup=null,r=r.alternate,r!=null&&(r.refCleanup=null)}else if(typeof s=="function")try{s(null)}catch(m){Rt(r,a,m)}else s.current=null}function py(r){var a=r.type,s=r.memoizedProps,c=r.stateNode;try{e:switch(a){case"button":case"input":case"select":case"textarea":s.autoFocus&&c.focus();break e;case"img":s.src?c.src=s.src:s.srcSet&&(c.srcset=s.srcSet)}}catch(m){Rt(r,r.return,m)}}function Bh(r,a,s){try{var c=r.stateNode;hR(c,r.type,s,a),c[Ce]=a}catch(m){Rt(r,r.return,m)}}function gy(r){return r.tag===5||r.tag===3||r.tag===26||r.tag===27&&ua(r.type)||r.tag===4}function Uh(r){e:for(;;){for(;r.sibling===null;){if(r.return===null||gy(r.return))return null;r=r.return}for(r.sibling.return=r.return,r=r.sibling;r.tag!==5&&r.tag!==6&&r.tag!==18;){if(r.tag===27&&ua(r.type)||r.flags&2||r.child===null||r.tag===4)continue e;r.child.return=r,r=r.child}if(!(r.flags&2))return r.stateNode}}function Hh(r,a,s){var c=r.tag;if(c===5||c===6)r=r.stateNode,a?(s.nodeType===9?s.body:s.nodeName==="HTML"?s.ownerDocument.body:s).insertBefore(r,a):(a=s.nodeType===9?s.body:s.nodeName==="HTML"?s.ownerDocument.body:s,a.appendChild(r),s=s._reactRootContainer,s!=null||a.onclick!==null||(a.onclick=Bc));else if(c!==4&&(c===27&&ua(r.type)&&(s=r.stateNode,a=null),r=r.child,r!==null))for(Hh(r,a,s),r=r.sibling;r!==null;)Hh(r,a,s),r=r.sibling}function xc(r,a,s){var c=r.tag;if(c===5||c===6)r=r.stateNode,a?s.insertBefore(r,a):s.appendChild(r);else if(c!==4&&(c===27&&ua(r.type)&&(s=r.stateNode),r=r.child,r!==null))for(xc(r,a,s),r=r.sibling;r!==null;)xc(r,a,s),r=r.sibling}function Ey(r){var a=r.stateNode,s=r.memoizedProps;try{for(var c=r.type,m=a.attributes;m.length;)a.removeAttributeNode(m[0]);Rn(a,c,s),a[pe]=r,a[Ce]=s}catch(E){Rt(r,r.return,E)}}var ki=!1,an=!1,zh=!1,yy=typeof WeakSet=="function"?WeakSet:Set,An=null;function X3(r,a){if(r=r.containerInfo,fm=Yc,r=w1(r),Ud(r)){if("selectionStart"in r)var s={start:r.selectionStart,end:r.selectionEnd};else e:{s=(s=r.ownerDocument)&&s.defaultView||window;var c=s.getSelection&&s.getSelection();if(c&&c.rangeCount!==0){s=c.anchorNode;var m=c.anchorOffset,E=c.focusNode;c=c.focusOffset;try{s.nodeType,E.nodeType}catch{s=null;break e}var D=0,x=-1,H=-1,ae=0,de=0,me=r,ue=null;t:for(;;){for(var oe;me!==s||m!==0&&me.nodeType!==3||(x=D+m),me!==E||c!==0&&me.nodeType!==3||(H=D+c),me.nodeType===3&&(D+=me.nodeValue.length),(oe=me.firstChild)!==null;)ue=me,me=oe;for(;;){if(me===r)break t;if(ue===s&&++ae===m&&(x=D),ue===E&&++de===c&&(H=D),(oe=me.nextSibling)!==null)break;me=ue,ue=me.parentNode}me=oe}s=x===-1||H===-1?null:{start:x,end:H}}else s=null}s=s||{start:0,end:0}}else s=null;for(dm={focusedElem:r,selectionRange:s},Yc=!1,An=a;An!==null;)if(a=An,r=a.child,(a.subtreeFlags&1024)!==0&&r!==null)r.return=a,An=r;else for(;An!==null;){switch(a=An,E=a.alternate,r=a.flags,a.tag){case 0:break;case 11:case 15:break;case 1:if((r&1024)!==0&&E!==null){r=void 0,s=a,m=E.memoizedProps,E=E.memoizedState,c=s.stateNode;try{var Xe=qa(s.type,m,s.elementType===s.type);r=c.getSnapshotBeforeUpdate(Xe,E),c.__reactInternalSnapshotBeforeUpdate=r}catch(qe){Rt(s,s.return,qe)}}break;case 3:if((r&1024)!==0){if(r=a.stateNode.containerInfo,s=r.nodeType,s===9)pm(r);else if(s===1)switch(r.nodeName){case"HEAD":case"HTML":case"BODY":pm(r);break;default:r.textContent=""}}break;case 5:case 26:case 27:case 6:case 4:case 17:break;default:if((r&1024)!==0)throw Error(i(163))}if(r=a.sibling,r!==null){r.return=a.return,An=r;break}An=a.return}}function by(r,a,s){var c=s.flags;switch(s.tag){case 0:case 11:case 15:Ji(r,s),c&4&&io(5,s);break;case 1:if(Ji(r,s),c&4)if(r=s.stateNode,a===null)try{r.componentDidMount()}catch(D){Rt(s,s.return,D)}else{var m=qa(s.type,a.memoizedProps);a=a.memoizedState;try{r.componentDidUpdate(m,a,r.__reactInternalSnapshotBeforeUpdate)}catch(D){Rt(s,s.return,D)}}c&64&&hy(s),c&512&&ao(s,s.return);break;case 3:if(Ji(r,s),c&64&&(r=s.updateQueue,r!==null)){if(a=null,s.child!==null)switch(s.child.tag){case 27:case 5:a=s.child.stateNode;break;case 1:a=s.child.stateNode}try{eE(r,a)}catch(D){Rt(s,s.return,D)}}break;case 27:a===null&&c&4&&Ey(s);case 26:case 5:Ji(r,s),a===null&&c&4&&py(s),c&512&&ao(s,s.return);break;case 12:Ji(r,s);break;case 13:Ji(r,s),c&4&&Sy(r,s),c&64&&(r=s.memoizedState,r!==null&&(r=r.dehydrated,r!==null&&(s=nR.bind(null,s),TR(r,s))));break;case 22:if(c=s.memoizedState!==null||ki,!c){a=a!==null&&a.memoizedState!==null||an,m=ki;var E=an;ki=c,(an=a)&&!E?ea(r,s,(s.subtreeFlags&8772)!==0):Ji(r,s),ki=m,an=E}break;case 30:break;default:Ji(r,s)}}function Ty(r){var a=r.alternate;a!==null&&(r.alternate=null,Ty(a)),r.child=null,r.deletions=null,r.sibling=null,r.tag===5&&(a=r.stateNode,a!==null&&Ue(a)),r.stateNode=null,r.return=null,r.dependencies=null,r.memoizedProps=null,r.memoizedState=null,r.pendingProps=null,r.stateNode=null,r.updateQueue=null}var zt=null,Zn=!1;function Li(r,a,s){for(s=s.child;s!==null;)Ay(r,a,s),s=s.sibling}function Ay(r,a,s){if(Ee&&typeof Ee.onCommitFiberUnmount=="function")try{Ee.onCommitFiberUnmount(le,s)}catch{}switch(s.tag){case 26:an||oi(s,a),Li(r,a,s),s.memoizedState?s.memoizedState.count--:s.stateNode&&(s=s.stateNode,s.parentNode.removeChild(s));break;case 27:an||oi(s,a);var c=zt,m=Zn;ua(s.type)&&(zt=s.stateNode,Zn=!1),Li(r,a,s),po(s.stateNode),zt=c,Zn=m;break;case 5:an||oi(s,a);case 6:if(c=zt,m=Zn,zt=null,Li(r,a,s),zt=c,Zn=m,zt!==null)if(Zn)try{(zt.nodeType===9?zt.body:zt.nodeName==="HTML"?zt.ownerDocument.body:zt).removeChild(s.stateNode)}catch(E){Rt(s,a,E)}else try{zt.removeChild(s.stateNode)}catch(E){Rt(s,a,E)}break;case 18:zt!==null&&(Zn?(r=zt,lb(r.nodeType===9?r.body:r.nodeName==="HTML"?r.ownerDocument.body:r,s.stateNode),Do(r)):lb(zt,s.stateNode));break;case 4:c=zt,m=Zn,zt=s.stateNode.containerInfo,Zn=!0,Li(r,a,s),zt=c,Zn=m;break;case 0:case 11:case 14:case 15:an||Zi(2,s,a),an||Zi(4,s,a),Li(r,a,s);break;case 1:an||(oi(s,a),c=s.stateNode,typeof c.componentWillUnmount=="function"&&my(s,a,c)),Li(r,a,s);break;case 21:Li(r,a,s);break;case 22:an=(c=an)||s.memoizedState!==null,Li(r,a,s),an=c;break;default:Li(r,a,s)}}function Sy(r,a){if(a.memoizedState===null&&(r=a.alternate,r!==null&&(r=r.memoizedState,r!==null&&(r=r.dehydrated,r!==null))))try{Do(r)}catch(s){Rt(a,a.return,s)}}function K3(r){switch(r.tag){case 13:case 19:var a=r.stateNode;return a===null&&(a=r.stateNode=new yy),a;case 22:return r=r.stateNode,a=r._retryCache,a===null&&(a=r._retryCache=new yy),a;default:throw Error(i(435,r.tag))}}function Vh(r,a){var s=K3(r);a.forEach(function(c){var m=rR.bind(null,r,c);s.has(c)||(s.add(c),c.then(m,m))})}function cr(r,a){var s=a.deletions;if(s!==null)for(var c=0;c<s.length;c++){var m=s[c],E=r,D=a,x=D;e:for(;x!==null;){switch(x.tag){case 27:if(ua(x.type)){zt=x.stateNode,Zn=!1;break e}break;case 5:zt=x.stateNode,Zn=!1;break e;case 3:case 4:zt=x.stateNode.containerInfo,Zn=!0;break e}x=x.return}if(zt===null)throw Error(i(160));Ay(E,D,m),zt=null,Zn=!1,E=m.alternate,E!==null&&(E.return=null),m.return=null}if(a.subtreeFlags&13878)for(a=a.child;a!==null;)Dy(a,r),a=a.sibling}var Gr=null;function Dy(r,a){var s=r.alternate,c=r.flags;switch(r.tag){case 0:case 11:case 14:case 15:cr(a,r),fr(r),c&4&&(Zi(3,r,r.return),io(3,r),Zi(5,r,r.return));break;case 1:cr(a,r),fr(r),c&512&&(an||s===null||oi(s,s.return)),c&64&&ki&&(r=r.updateQueue,r!==null&&(c=r.callbacks,c!==null&&(s=r.shared.hiddenCallbacks,r.shared.hiddenCallbacks=s===null?c:s.concat(c))));break;case 26:var m=Gr;if(cr(a,r),fr(r),c&512&&(an||s===null||oi(s,s.return)),c&4){var E=s!==null?s.memoizedState:null;if(c=r.memoizedState,s===null)if(c===null)if(r.stateNode===null){e:{c=r.type,s=r.memoizedProps,m=m.ownerDocument||m;t:switch(c){case"title":E=m.getElementsByTagName("title")[0],(!E||E[je]||E[pe]||E.namespaceURI==="http://www.w3.org/2000/svg"||E.hasAttribute("itemprop"))&&(E=m.createElement(c),m.head.insertBefore(E,m.querySelector("head > title"))),Rn(E,c,s),E[pe]=r,pt(E),c=E;break e;case"link":var D=Eb("link","href",m).get(c+(s.href||""));if(D){for(var x=0;x<D.length;x++)if(E=D[x],E.getAttribute("href")===(s.href==null||s.href===""?null:s.href)&&E.getAttribute("rel")===(s.rel==null?null:s.rel)&&E.getAttribute("title")===(s.title==null?null:s.title)&&E.getAttribute("crossorigin")===(s.crossOrigin==null?null:s.crossOrigin)){D.splice(x,1);break t}}E=m.createElement(c),Rn(E,c,s),m.head.appendChild(E);break;case"meta":if(D=Eb("meta","content",m).get(c+(s.content||""))){for(x=0;x<D.length;x++)if(E=D[x],E.getAttribute("content")===(s.content==null?null:""+s.content)&&E.getAttribute("name")===(s.name==null?null:s.name)&&E.getAttribute("property")===(s.property==null?null:s.property)&&E.getAttribute("http-equiv")===(s.httpEquiv==null?null:s.httpEquiv)&&E.getAttribute("charset")===(s.charSet==null?null:s.charSet)){D.splice(x,1);break t}}E=m.createElement(c),Rn(E,c,s),m.head.appendChild(E);break;default:throw Error(i(468,c))}E[pe]=r,pt(E),c=E}r.stateNode=c}else yb(m,r.type,r.stateNode);else r.stateNode=gb(m,c,r.memoizedProps);else E!==c?(E===null?s.stateNode!==null&&(s=s.stateNode,s.parentNode.removeChild(s)):E.count--,c===null?yb(m,r.type,r.stateNode):gb(m,c,r.memoizedProps)):c===null&&r.stateNode!==null&&Bh(r,r.memoizedProps,s.memoizedProps)}break;case 27:cr(a,r),fr(r),c&512&&(an||s===null||oi(s,s.return)),s!==null&&c&4&&Bh(r,r.memoizedProps,s.memoizedProps);break;case 5:if(cr(a,r),fr(r),c&512&&(an||s===null||oi(s,s.return)),r.flags&32){m=r.stateNode;try{yu(m,"")}catch(oe){Rt(r,r.return,oe)}}c&4&&r.stateNode!=null&&(m=r.memoizedProps,Bh(r,m,s!==null?s.memoizedProps:m)),c&1024&&(zh=!0);break;case 6:if(cr(a,r),fr(r),c&4){if(r.stateNode===null)throw Error(i(162));c=r.memoizedProps,s=r.stateNode;try{s.nodeValue=c}catch(oe){Rt(r,r.return,oe)}}break;case 3:if(Vc=null,m=Gr,Gr=Hc(a.containerInfo),cr(a,r),Gr=m,fr(r),c&4&&s!==null&&s.memoizedState.isDehydrated)try{Do(a.containerInfo)}catch(oe){Rt(r,r.return,oe)}zh&&(zh=!1,vy(r));break;case 4:c=Gr,Gr=Hc(r.stateNode.containerInfo),cr(a,r),fr(r),Gr=c;break;case 12:cr(a,r),fr(r);break;case 13:cr(a,r),fr(r),r.child.flags&8192&&r.memoizedState!==null!=(s!==null&&s.memoizedState!==null)&&(Kh=Yt()),c&4&&(c=r.updateQueue,c!==null&&(r.updateQueue=null,Vh(r,c)));break;case 22:m=r.memoizedState!==null;var H=s!==null&&s.memoizedState!==null,ae=ki,de=an;if(ki=ae||m,an=de||H,cr(a,r),an=de,ki=ae,fr(r),c&8192)e:for(a=r.stateNode,a._visibility=m?a._visibility&-2:a._visibility|1,m&&(s===null||H||ki||an||Ya(r)),s=null,a=r;;){if(a.tag===5||a.tag===26){if(s===null){H=s=a;try{if(E=H.stateNode,m)D=E.style,typeof D.setProperty=="function"?D.setProperty("display","none","important"):D.display="none";else{x=H.stateNode;var me=H.memoizedProps.style,ue=me!=null&&me.hasOwnProperty("display")?me.display:null;x.style.display=ue==null||typeof ue=="boolean"?"":(""+ue).trim()}}catch(oe){Rt(H,H.return,oe)}}}else if(a.tag===6){if(s===null){H=a;try{H.stateNode.nodeValue=m?"":H.memoizedProps}catch(oe){Rt(H,H.return,oe)}}}else if((a.tag!==22&&a.tag!==23||a.memoizedState===null||a===r)&&a.child!==null){a.child.return=a,a=a.child;continue}if(a===r)break e;for(;a.sibling===null;){if(a.return===null||a.return===r)break e;s===a&&(s=null),a=a.return}s===a&&(s=null),a.sibling.return=a.return,a=a.sibling}c&4&&(c=r.updateQueue,c!==null&&(s=c.retryQueue,s!==null&&(c.retryQueue=null,Vh(r,s))));break;case 19:cr(a,r),fr(r),c&4&&(c=r.updateQueue,c!==null&&(r.updateQueue=null,Vh(r,c)));break;case 30:break;case 21:break;default:cr(a,r),fr(r)}}function fr(r){var a=r.flags;if(a&2){try{for(var s,c=r.return;c!==null;){if(gy(c)){s=c;break}c=c.return}if(s==null)throw Error(i(160));switch(s.tag){case 27:var m=s.stateNode,E=Uh(r);xc(r,E,m);break;case 5:var D=s.stateNode;s.flags&32&&(yu(D,""),s.flags&=-33);var x=Uh(r);xc(r,x,D);break;case 3:case 4:var H=s.stateNode.containerInfo,ae=Uh(r);Hh(r,ae,H);break;default:throw Error(i(161))}}catch(de){Rt(r,r.return,de)}r.flags&=-3}a&4096&&(r.flags&=-4097)}function vy(r){if(r.subtreeFlags&1024)for(r=r.child;r!==null;){var a=r;vy(a),a.tag===5&&a.flags&1024&&a.stateNode.reset(),r=r.sibling}}function Ji(r,a){if(a.subtreeFlags&8772)for(a=a.child;a!==null;)by(r,a.alternate,a),a=a.sibling}function Ya(r){for(r=r.child;r!==null;){var a=r;switch(a.tag){case 0:case 11:case 14:case 15:Zi(4,a,a.return),Ya(a);break;case 1:oi(a,a.return);var s=a.stateNode;typeof s.componentWillUnmount=="function"&&my(a,a.return,s),Ya(a);break;case 27:po(a.stateNode);case 26:case 5:oi(a,a.return),Ya(a);break;case 22:a.memoizedState===null&&Ya(a);break;case 30:Ya(a);break;default:Ya(a)}r=r.sibling}}function ea(r,a,s){for(s=s&&(a.subtreeFlags&8772)!==0,a=a.child;a!==null;){var c=a.alternate,m=r,E=a,D=E.flags;switch(E.tag){case 0:case 11:case 15:ea(m,E,s),io(4,E);break;case 1:if(ea(m,E,s),c=E,m=c.stateNode,typeof m.componentDidMount=="function")try{m.componentDidMount()}catch(ae){Rt(c,c.return,ae)}if(c=E,m=c.updateQueue,m!==null){var x=c.stateNode;try{var H=m.shared.hiddenCallbacks;if(H!==null)for(m.shared.hiddenCallbacks=null,m=0;m<H.length;m++)J1(H[m],x)}catch(ae){Rt(c,c.return,ae)}}s&&D&64&&hy(E),ao(E,E.return);break;case 27:Ey(E);case 26:case 5:ea(m,E,s),s&&c===null&&D&4&&py(E),ao(E,E.return);break;case 12:ea(m,E,s);break;case 13:ea(m,E,s),s&&D&4&&Sy(m,E);break;case 22:E.memoizedState===null&&ea(m,E,s),ao(E,E.return);break;case 30:break;default:ea(m,E,s)}a=a.sibling}}function jh(r,a){var s=null;r!==null&&r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(s=r.memoizedState.cachePool.pool),r=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(r=a.memoizedState.cachePool.pool),r!==s&&(r!=null&&r.refCount++,s!=null&&qs(s))}function qh(r,a){r=null,a.alternate!==null&&(r=a.alternate.memoizedState.cache),a=a.memoizedState.cache,a!==r&&(a.refCount++,r!=null&&qs(r))}function li(r,a,s,c){if(a.subtreeFlags&10256)for(a=a.child;a!==null;)Cy(r,a,s,c),a=a.sibling}function Cy(r,a,s,c){var m=a.flags;switch(a.tag){case 0:case 11:case 15:li(r,a,s,c),m&2048&&io(9,a);break;case 1:li(r,a,s,c);break;case 3:li(r,a,s,c),m&2048&&(r=null,a.alternate!==null&&(r=a.alternate.memoizedState.cache),a=a.memoizedState.cache,a!==r&&(a.refCount++,r!=null&&qs(r)));break;case 12:if(m&2048){li(r,a,s,c),r=a.stateNode;try{var E=a.memoizedProps,D=E.id,x=E.onPostCommit;typeof x=="function"&&x(D,a.alternate===null?"mount":"update",r.passiveEffectDuration,-0)}catch(H){Rt(a,a.return,H)}}else li(r,a,s,c);break;case 13:li(r,a,s,c);break;case 23:break;case 22:E=a.stateNode,D=a.alternate,a.memoizedState!==null?E._visibility&2?li(r,a,s,c):uo(r,a):E._visibility&2?li(r,a,s,c):(E._visibility|=2,Fu(r,a,s,c,(a.subtreeFlags&10256)!==0)),m&2048&&jh(D,a);break;case 24:li(r,a,s,c),m&2048&&qh(a.alternate,a);break;default:li(r,a,s,c)}}function Fu(r,a,s,c,m){for(m=m&&(a.subtreeFlags&10256)!==0,a=a.child;a!==null;){var E=r,D=a,x=s,H=c,ae=D.flags;switch(D.tag){case 0:case 11:case 15:Fu(E,D,x,H,m),io(8,D);break;case 23:break;case 22:var de=D.stateNode;D.memoizedState!==null?de._visibility&2?Fu(E,D,x,H,m):uo(E,D):(de._visibility|=2,Fu(E,D,x,H,m)),m&&ae&2048&&jh(D.alternate,D);break;case 24:Fu(E,D,x,H,m),m&&ae&2048&&qh(D.alternate,D);break;default:Fu(E,D,x,H,m)}a=a.sibling}}function uo(r,a){if(a.subtreeFlags&10256)for(a=a.child;a!==null;){var s=r,c=a,m=c.flags;switch(c.tag){case 22:uo(s,c),m&2048&&jh(c.alternate,c);break;case 24:uo(s,c),m&2048&&qh(c.alternate,c);break;default:uo(s,c)}a=a.sibling}}var so=8192;function Bu(r){if(r.subtreeFlags&so)for(r=r.child;r!==null;)_y(r),r=r.sibling}function _y(r){switch(r.tag){case 26:Bu(r),r.flags&so&&r.memoizedState!==null&&LR(Gr,r.memoizedState,r.memoizedProps);break;case 5:Bu(r);break;case 3:case 4:var a=Gr;Gr=Hc(r.stateNode.containerInfo),Bu(r),Gr=a;break;case 22:r.memoizedState===null&&(a=r.alternate,a!==null&&a.memoizedState!==null?(a=so,so=16777216,Bu(r),so=a):Bu(r));break;default:Bu(r)}}function xy(r){var a=r.alternate;if(a!==null&&(r=a.child,r!==null)){a.child=null;do a=r.sibling,r.sibling=null,r=a;while(r!==null)}}function oo(r){var a=r.deletions;if((r.flags&16)!==0){if(a!==null)for(var s=0;s<a.length;s++){var c=a[s];An=c,wy(c,r)}xy(r)}if(r.subtreeFlags&10256)for(r=r.child;r!==null;)Ry(r),r=r.sibling}function Ry(r){switch(r.tag){case 0:case 11:case 15:oo(r),r.flags&2048&&Zi(9,r,r.return);break;case 3:oo(r);break;case 12:oo(r);break;case 22:var a=r.stateNode;r.memoizedState!==null&&a._visibility&2&&(r.return===null||r.return.tag!==13)?(a._visibility&=-3,Rc(r)):oo(r);break;default:oo(r)}}function Rc(r){var a=r.deletions;if((r.flags&16)!==0){if(a!==null)for(var s=0;s<a.length;s++){var c=a[s];An=c,wy(c,r)}xy(r)}for(r=r.child;r!==null;){switch(a=r,a.tag){case 0:case 11:case 15:Zi(8,a,a.return),Rc(a);break;case 22:s=a.stateNode,s._visibility&2&&(s._visibility&=-3,Rc(a));break;default:Rc(a)}r=r.sibling}}function wy(r,a){for(;An!==null;){var s=An;switch(s.tag){case 0:case 11:case 15:Zi(8,s,a);break;case 23:case 22:if(s.memoizedState!==null&&s.memoizedState.cachePool!==null){var c=s.memoizedState.cachePool.pool;c!=null&&c.refCount++}break;case 24:qs(s.memoizedState.cache)}if(c=s.child,c!==null)c.return=s,An=c;else e:for(s=r;An!==null;){c=An;var m=c.sibling,E=c.return;if(Ty(c),c===s){An=null;break e}if(m!==null){m.return=E,An=m;break e}An=E}}}var W3={getCacheForType:function(r){var a=Nn(En),s=a.data.get(r);return s===void 0&&(s=r(),a.data.set(r,s)),s}},Q3=typeof WeakMap=="function"?WeakMap:Map,At=0,Mt=null,lt=null,gt=0,St=0,dr=null,ta=!1,Uu=!1,Yh=!1,Mi=0,Jt=0,na=0,Ga=0,Gh=0,Nr=0,Hu=0,lo=null,Jn=null,Xh=!1,Kh=0,wc=1/0,Oc=null,ra=null,xn=0,ia=null,zu=null,Vu=0,Wh=0,Qh=null,Oy=null,co=0,$h=null;function hr(){if((At&2)!==0&>!==0)return gt&-gt;if(B.T!==null){var r=wu;return r!==0?r:im()}return j()}function Ny(){Nr===0&&(Nr=(gt&536870912)===0||Tt?qr():536870912);var r=Or.current;return r!==null&&(r.flags|=32),Nr}function mr(r,a,s){(r===Mt&&(St===2||St===9)||r.cancelPendingCommit!==null)&&(ju(r,0),aa(r,gt,Nr,!1)),sr(r,s),((At&2)===0||r!==Mt)&&(r===Mt&&((At&2)===0&&(Ga|=s),Jt===4&&aa(r,gt,Nr,!1)),ci(r))}function ky(r,a,s){if((At&6)!==0)throw Error(i(327));var c=!s&&(a&124)===0&&(a&r.expiredLanes)===0||nn(r,a),m=c?J3(r,a):em(r,a,!0),E=c;do{if(m===0){Uu&&!c&&aa(r,a,0,!1);break}else{if(s=r.current.alternate,E&&!$3(s)){m=em(r,a,!1),E=!1;continue}if(m===2){if(E=a,r.errorRecoveryDisabledLanes&E)var D=0;else D=r.pendingLanes&-536870913,D=D!==0?D:D&536870912?536870912:0;if(D!==0){a=D;e:{var x=r;m=lo;var H=x.current.memoizedState.isDehydrated;if(H&&(ju(x,D).flags|=256),D=em(x,D,!1),D!==2){if(Yh&&!H){x.errorRecoveryDisabledLanes|=E,Ga|=E,m=4;break e}E=Jn,Jn=m,E!==null&&(Jn===null?Jn=E:Jn.push.apply(Jn,E))}m=D}if(E=!1,m!==2)continue}}if(m===1){ju(r,0),aa(r,a,0,!0);break}e:{switch(c=r,E=m,E){case 0:case 1:throw Error(i(345));case 4:if((a&4194048)!==a)break;case 6:aa(c,a,Nr,!ta);break e;case 2:Jn=null;break;case 3:case 5:break;default:throw Error(i(329))}if((a&62914560)===a&&(m=Kh+300-Yt(),10<m)){if(aa(c,a,Nr,!ta),Bt(c,0,!0)!==0)break e;c.timeoutHandle=sb(Ly.bind(null,c,s,Jn,Oc,Xh,a,Nr,Ga,Hu,ta,E,2,-0,0),m);break e}Ly(c,s,Jn,Oc,Xh,a,Nr,Ga,Hu,ta,E,0,-0,0)}}break}while(!0);ci(r)}function Ly(r,a,s,c,m,E,D,x,H,ae,de,me,ue,oe){if(r.timeoutHandle=-1,me=a.subtreeFlags,(me&8192||(me&16785408)===16785408)&&(yo={stylesheets:null,count:0,unsuspend:kR},_y(a),me=MR(),me!==null)){r.cancelPendingCommit=me(Hy.bind(null,r,a,E,s,c,m,D,x,H,de,1,ue,oe)),aa(r,E,D,!ae);return}Hy(r,a,E,s,c,m,D,x,H)}function $3(r){for(var a=r;;){var s=a.tag;if((s===0||s===11||s===15)&&a.flags&16384&&(s=a.updateQueue,s!==null&&(s=s.stores,s!==null)))for(var c=0;c<s.length;c++){var m=s[c],E=m.getSnapshot;m=m.value;try{if(!or(E(),m))return!1}catch{return!1}}if(s=a.child,a.subtreeFlags&16384&&s!==null)s.return=a,a=s;else{if(a===r)break;for(;a.sibling===null;){if(a.return===null||a.return===r)return!0;a=a.return}a.sibling.return=a.return,a=a.sibling}}return!0}function aa(r,a,s,c){a&=~Gh,a&=~Ga,r.suspendedLanes|=a,r.pingedLanes&=~a,c&&(r.warmLanes|=a),c=r.expirationTimes;for(var m=a;0<m;){var E=31-ze(m),D=1<<E;c[E]=-1,m&=~D}s!==0&&Ai(r,s,a)}function Nc(){return(At&6)===0?(fo(0),!1):!0}function Zh(){if(lt!==null){if(St===0)var r=lt.return;else r=lt,_i=Ha=null,ph(r),Iu=null,to=0,r=lt;for(;r!==null;)dy(r.alternate,r),r=r.return;lt=null}}function ju(r,a){var s=r.timeoutHandle;s!==-1&&(r.timeoutHandle=-1,pR(s)),s=r.cancelPendingCommit,s!==null&&(r.cancelPendingCommit=null,s()),Zh(),Mt=r,lt=s=Di(r.current,null),gt=a,St=0,dr=null,ta=!1,Uu=nn(r,a),Yh=!1,Hu=Nr=Gh=Ga=na=Jt=0,Jn=lo=null,Xh=!1,(a&8)!==0&&(a|=a&32);var c=r.entangledLanes;if(c!==0)for(r=r.entanglements,c&=a;0<c;){var m=31-ze(c),E=1<<m;a|=r[m],c&=~E}return Mi=a,Jl(),s}function My(r,a){it=null,B.H=yc,a===Gs||a===oc?(a=$1(),St=3):a===K1?(a=$1(),St=4):St=a===ZE?8:a!==null&&typeof a=="object"&&typeof a.then=="function"?6:1,dr=a,lt===null&&(Jt=1,Dc(r,_r(a,r.current)))}function Iy(){var r=B.H;return B.H=yc,r===null?yc:r}function Py(){var r=B.A;return B.A=W3,r}function Jh(){Jt=4,ta||(gt&4194048)!==gt&&Or.current!==null||(Uu=!0),(na&134217727)===0&&(Ga&134217727)===0||Mt===null||aa(Mt,gt,Nr,!1)}function em(r,a,s){var c=At;At|=2;var m=Iy(),E=Py();(Mt!==r||gt!==a)&&(Oc=null,ju(r,a)),a=!1;var D=Jt;e:do try{if(St!==0&<!==null){var x=lt,H=dr;switch(St){case 8:Zh(),D=6;break e;case 3:case 2:case 9:case 6:Or.current===null&&(a=!0);var ae=St;if(St=0,dr=null,qu(r,x,H,ae),s&&Uu){D=0;break e}break;default:ae=St,St=0,dr=null,qu(r,x,H,ae)}}Z3(),D=Jt;break}catch(de){My(r,de)}while(!0);return a&&r.shellSuspendCounter++,_i=Ha=null,At=c,B.H=m,B.A=E,lt===null&&(Mt=null,gt=0,Jl()),D}function Z3(){for(;lt!==null;)Fy(lt)}function J3(r,a){var s=At;At|=2;var c=Iy(),m=Py();Mt!==r||gt!==a?(Oc=null,wc=Yt()+500,ju(r,a)):Uu=nn(r,a);e:do try{if(St!==0&<!==null){a=lt;var E=dr;t:switch(St){case 1:St=0,dr=null,qu(r,a,E,1);break;case 2:case 9:if(W1(E)){St=0,dr=null,By(a);break}a=function(){St!==2&&St!==9||Mt!==r||(St=7),ci(r)},E.then(a,a);break e;case 3:St=7;break e;case 4:St=5;break e;case 7:W1(E)?(St=0,dr=null,By(a)):(St=0,dr=null,qu(r,a,E,7));break;case 5:var D=null;switch(lt.tag){case 26:D=lt.memoizedState;case 5:case 27:var x=lt;if(!D||bb(D)){St=0,dr=null;var H=x.sibling;if(H!==null)lt=H;else{var ae=x.return;ae!==null?(lt=ae,kc(ae)):lt=null}break t}}St=0,dr=null,qu(r,a,E,5);break;case 6:St=0,dr=null,qu(r,a,E,6);break;case 8:Zh(),Jt=6;break e;default:throw Error(i(462))}}eR();break}catch(de){My(r,de)}while(!0);return _i=Ha=null,B.H=c,B.A=m,At=s,lt!==null?0:(Mt=null,gt=0,Jl(),Jt)}function eR(){for(;lt!==null&&!ni();)Fy(lt)}function Fy(r){var a=cy(r.alternate,r,Mi);r.memoizedProps=r.pendingProps,a===null?kc(r):lt=a}function By(r){var a=r,s=a.alternate;switch(a.tag){case 15:case 0:a=iy(s,a,a.pendingProps,a.type,void 0,gt);break;case 11:a=iy(s,a,a.pendingProps,a.type.render,a.ref,gt);break;case 5:ph(a);default:dy(s,a),a=lt=U1(a,Mi),a=cy(s,a,Mi)}r.memoizedProps=r.pendingProps,a===null?kc(r):lt=a}function qu(r,a,s,c){_i=Ha=null,ph(a),Iu=null,to=0;var m=a.return;try{if(j3(r,m,a,s,gt)){Jt=1,Dc(r,_r(s,r.current)),lt=null;return}}catch(E){if(m!==null)throw lt=m,E;Jt=1,Dc(r,_r(s,r.current)),lt=null;return}a.flags&32768?(Tt||c===1?r=!0:Uu||(gt&536870912)!==0?r=!1:(ta=r=!0,(c===2||c===9||c===3||c===6)&&(c=Or.current,c!==null&&c.tag===13&&(c.flags|=16384))),Uy(a,r)):kc(a)}function kc(r){var a=r;do{if((a.flags&32768)!==0){Uy(a,ta);return}r=a.return;var s=Y3(a.alternate,a,Mi);if(s!==null){lt=s;return}if(a=a.sibling,a!==null){lt=a;return}lt=a=r}while(a!==null);Jt===0&&(Jt=5)}function Uy(r,a){do{var s=G3(r.alternate,r);if(s!==null){s.flags&=32767,lt=s;return}if(s=r.return,s!==null&&(s.flags|=32768,s.subtreeFlags=0,s.deletions=null),!a&&(r=r.sibling,r!==null)){lt=r;return}lt=r=s}while(r!==null);Jt=6,lt=null}function Hy(r,a,s,c,m,E,D,x,H){r.cancelPendingCommit=null;do Lc();while(xn!==0);if((At&6)!==0)throw Error(i(327));if(a!==null){if(a===r.current)throw Error(i(177));if(E=a.lanes|a.childLanes,E|=qd,gu(r,s,E,D,x,H),r===Mt&&(lt=Mt=null,gt=0),zu=a,ia=r,Vu=s,Wh=E,Qh=m,Oy=c,(a.subtreeFlags&10256)!==0||(a.flags&10256)!==0?(r.callbackNode=null,r.callbackPriority=0,iR(jr,function(){return Yy(),null})):(r.callbackNode=null,r.callbackPriority=0),c=(a.flags&13878)!==0,(a.subtreeFlags&13878)!==0||c){c=B.T,B.T=null,m=K.p,K.p=2,D=At,At|=4;try{X3(r,a,s)}finally{At=D,K.p=m,B.T=c}}xn=1,zy(),Vy(),jy()}}function zy(){if(xn===1){xn=0;var r=ia,a=zu,s=(a.flags&13878)!==0;if((a.subtreeFlags&13878)!==0||s){s=B.T,B.T=null;var c=K.p;K.p=2;var m=At;At|=4;try{Dy(a,r);var E=dm,D=w1(r.containerInfo),x=E.focusedElem,H=E.selectionRange;if(D!==x&&x&&x.ownerDocument&&R1(x.ownerDocument.documentElement,x)){if(H!==null&&Ud(x)){var ae=H.start,de=H.end;if(de===void 0&&(de=ae),"selectionStart"in x)x.selectionStart=ae,x.selectionEnd=Math.min(de,x.value.length);else{var me=x.ownerDocument||document,ue=me&&me.defaultView||window;if(ue.getSelection){var oe=ue.getSelection(),Xe=x.textContent.length,qe=Math.min(H.start,Xe),xt=H.end===void 0?qe:Math.min(H.end,Xe);!oe.extend&&qe>xt&&(D=xt,xt=qe,qe=D);var ee=x1(x,qe),X=x1(x,xt);if(ee&&X&&(oe.rangeCount!==1||oe.anchorNode!==ee.node||oe.anchorOffset!==ee.offset||oe.focusNode!==X.node||oe.focusOffset!==X.offset)){var re=me.createRange();re.setStart(ee.node,ee.offset),oe.removeAllRanges(),qe>xt?(oe.addRange(re),oe.extend(X.node,X.offset)):(re.setEnd(X.node,X.offset),oe.addRange(re))}}}}for(me=[],oe=x;oe=oe.parentNode;)oe.nodeType===1&&me.push({element:oe,left:oe.scrollLeft,top:oe.scrollTop});for(typeof x.focus=="function"&&x.focus(),x=0;x<me.length;x++){var he=me[x];he.element.scrollLeft=he.left,he.element.scrollTop=he.top}}Yc=!!fm,dm=fm=null}finally{At=m,K.p=c,B.T=s}}r.current=a,xn=2}}function Vy(){if(xn===2){xn=0;var r=ia,a=zu,s=(a.flags&8772)!==0;if((a.subtreeFlags&8772)!==0||s){s=B.T,B.T=null;var c=K.p;K.p=2;var m=At;At|=4;try{by(r,a.alternate,a)}finally{At=m,K.p=c,B.T=s}}xn=3}}function jy(){if(xn===4||xn===3){xn=0,ri();var r=ia,a=zu,s=Vu,c=Oy;(a.subtreeFlags&10256)!==0||(a.flags&10256)!==0?xn=5:(xn=0,zu=ia=null,qy(r,r.pendingLanes));var m=r.pendingLanes;if(m===0&&(ra=null),Oa(s),a=a.stateNode,Ee&&typeof Ee.onCommitFiberRoot=="function")try{Ee.onCommitFiberRoot(le,a,void 0,(a.current.flags&128)===128)}catch{}if(c!==null){a=B.T,m=K.p,K.p=2,B.T=null;try{for(var E=r.onRecoverableError,D=0;D<c.length;D++){var x=c[D];E(x.value,{componentStack:x.stack})}}finally{B.T=a,K.p=m}}(Vu&3)!==0&&Lc(),ci(r),m=r.pendingLanes,(s&4194090)!==0&&(m&42)!==0?r===$h?co++:(co=0,$h=r):co=0,fo(0)}}function qy(r,a){(r.pooledCacheLanes&=a)===0&&(a=r.pooledCache,a!=null&&(r.pooledCache=null,qs(a)))}function Lc(r){return zy(),Vy(),jy(),Yy()}function Yy(){if(xn!==5)return!1;var r=ia,a=Wh;Wh=0;var s=Oa(Vu),c=B.T,m=K.p;try{K.p=32>s?32:s,B.T=null,s=Qh,Qh=null;var E=ia,D=Vu;if(xn=0,zu=ia=null,Vu=0,(At&6)!==0)throw Error(i(331));var x=At;if(At|=4,Ry(E.current),Cy(E,E.current,D,s),At=x,fo(0,!1),Ee&&typeof Ee.onPostCommitFiberRoot=="function")try{Ee.onPostCommitFiberRoot(le,E)}catch{}return!0}finally{K.p=m,B.T=c,qy(r,a)}}function Gy(r,a,s){a=_r(s,a),a=wh(r.stateNode,a,2),r=Ki(r,a,2),r!==null&&(sr(r,2),ci(r))}function Rt(r,a,s){if(r.tag===3)Gy(r,r,s);else for(;a!==null;){if(a.tag===3){Gy(a,r,s);break}else if(a.tag===1){var c=a.stateNode;if(typeof a.type.getDerivedStateFromError=="function"||typeof c.componentDidCatch=="function"&&(ra===null||!ra.has(c))){r=_r(s,r),s=QE(2),c=Ki(a,s,2),c!==null&&($E(s,c,a,r),sr(c,2),ci(c));break}}a=a.return}}function tm(r,a,s){var c=r.pingCache;if(c===null){c=r.pingCache=new Q3;var m=new Set;c.set(a,m)}else m=c.get(a),m===void 0&&(m=new Set,c.set(a,m));m.has(s)||(Yh=!0,m.add(s),r=tR.bind(null,r,a,s),a.then(r,r))}function tR(r,a,s){var c=r.pingCache;c!==null&&c.delete(a),r.pingedLanes|=r.suspendedLanes&s,r.warmLanes&=~s,Mt===r&&(gt&s)===s&&(Jt===4||Jt===3&&(gt&62914560)===gt&&300>Yt()-Kh?(At&2)===0&&ju(r,0):Gh|=s,Hu===gt&&(Hu=0)),ci(r)}function Xy(r,a){a===0&&(a=Ti()),r=Cu(r,a),r!==null&&(sr(r,a),ci(r))}function nR(r){var a=r.memoizedState,s=0;a!==null&&(s=a.retryLane),Xy(r,s)}function rR(r,a){var s=0;switch(r.tag){case 13:var c=r.stateNode,m=r.memoizedState;m!==null&&(s=m.retryLane);break;case 19:c=r.stateNode;break;case 22:c=r.stateNode._retryCache;break;default:throw Error(i(314))}c!==null&&c.delete(a),Xy(r,s)}function iR(r,a){return Ar(r,a)}var Mc=null,Yu=null,nm=!1,Ic=!1,rm=!1,Xa=0;function ci(r){r!==Yu&&r.next===null&&(Yu===null?Mc=Yu=r:Yu=Yu.next=r),Ic=!0,nm||(nm=!0,uR())}function fo(r,a){if(!rm&&Ic){rm=!0;do for(var s=!1,c=Mc;c!==null;){if(r!==0){var m=c.pendingLanes;if(m===0)var E=0;else{var D=c.suspendedLanes,x=c.pingedLanes;E=(1<<31-ze(42|r)+1)-1,E&=m&~(D&~x),E=E&201326741?E&201326741|1:E?E|2:0}E!==0&&(s=!0,$y(c,E))}else E=gt,E=Bt(c,c===Mt?E:0,c.cancelPendingCommit!==null||c.timeoutHandle!==-1),(E&3)===0||nn(c,E)||(s=!0,$y(c,E));c=c.next}while(s);rm=!1}}function aR(){Ky()}function Ky(){Ic=nm=!1;var r=0;Xa!==0&&(mR()&&(r=Xa),Xa=0);for(var a=Yt(),s=null,c=Mc;c!==null;){var m=c.next,E=Wy(c,a);E===0?(c.next=null,s===null?Mc=m:s.next=m,m===null&&(Yu=s)):(s=c,(r!==0||(E&3)!==0)&&(Ic=!0)),c=m}fo(r)}function Wy(r,a){for(var s=r.suspendedLanes,c=r.pingedLanes,m=r.expirationTimes,E=r.pendingLanes&-62914561;0<E;){var D=31-ze(E),x=1<<D,H=m[D];H===-1?((x&s)===0||(x&c)!==0)&&(m[D]=On(x,a)):H<=a&&(r.expiredLanes|=x),E&=~x}if(a=Mt,s=gt,s=Bt(r,r===a?s:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),c=r.callbackNode,s===0||r===a&&(St===2||St===9)||r.cancelPendingCommit!==null)return c!==null&&c!==null&&tn(c),r.callbackNode=null,r.callbackPriority=0;if((s&3)===0||nn(r,s)){if(a=s&-s,a===r.callbackPriority)return a;switch(c!==null&&tn(c),Oa(s)){case 2:case 8:s=ai;break;case 32:s=jr;break;case 268435456:s=Yn;break;default:s=jr}return c=Qy.bind(null,r),s=Ar(s,c),r.callbackPriority=a,r.callbackNode=s,a}return c!==null&&c!==null&&tn(c),r.callbackPriority=2,r.callbackNode=null,2}function Qy(r,a){if(xn!==0&&xn!==5)return r.callbackNode=null,r.callbackPriority=0,null;var s=r.callbackNode;if(Lc()&&r.callbackNode!==s)return null;var c=gt;return c=Bt(r,r===Mt?c:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),c===0?null:(ky(r,c,a),Wy(r,Yt()),r.callbackNode!=null&&r.callbackNode===s?Qy.bind(null,r):null)}function $y(r,a){if(Lc())return null;ky(r,a,!0)}function uR(){gR(function(){(At&6)!==0?Ar(Sr,aR):Ky()})}function im(){return Xa===0&&(Xa=qr()),Xa}function Zy(r){return r==null||typeof r=="symbol"||typeof r=="boolean"?null:typeof r=="function"?r:Gl(""+r)}function Jy(r,a){var s=a.ownerDocument.createElement("input");return s.name=a.name,s.value=a.value,r.id&&s.setAttribute("form",r.id),a.parentNode.insertBefore(s,a),r=new FormData(r),s.parentNode.removeChild(s),r}function sR(r,a,s,c,m){if(a==="submit"&&s&&s.stateNode===m){var E=Zy((m[Ce]||null).action),D=c.submitter;D&&(a=(a=D[Ce]||null)?Zy(a.formAction):D.getAttribute("formAction"),a!==null&&(E=a,D=null));var x=new Ql("action","action",null,c,m);r.push({event:x,listeners:[{instance:null,listener:function(){if(c.defaultPrevented){if(Xa!==0){var H=D?Jy(m,D):new FormData(m);vh(s,{pending:!0,data:H,method:m.method,action:E},null,H)}}else typeof E=="function"&&(x.preventDefault(),H=D?Jy(m,D):new FormData(m),vh(s,{pending:!0,data:H,method:m.method,action:E},E,H))},currentTarget:m}]})}}for(var am=0;am<jd.length;am++){var um=jd[am],oR=um.toLowerCase(),lR=um[0].toUpperCase()+um.slice(1);Yr(oR,"on"+lR)}Yr(k1,"onAnimationEnd"),Yr(L1,"onAnimationIteration"),Yr(M1,"onAnimationStart"),Yr("dblclick","onDoubleClick"),Yr("focusin","onFocus"),Yr("focusout","onBlur"),Yr(_3,"onTransitionRun"),Yr(x3,"onTransitionStart"),Yr(R3,"onTransitionCancel"),Yr(I1,"onTransitionEnd"),Oe("onMouseEnter",["mouseout","mouseover"]),Oe("onMouseLeave",["mouseout","mouseover"]),Oe("onPointerEnter",["pointerout","pointerover"]),Oe("onPointerLeave",["pointerout","pointerover"]),ye("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),ye("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),ye("onBeforeInput",["compositionend","keypress","textInput","paste"]),ye("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),ye("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),ye("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var ho="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),cR=new Set("beforetoggle cancel close invalid load scroll scrollend toggle".split(" ").concat(ho));function eb(r,a){a=(a&4)!==0;for(var s=0;s<r.length;s++){var c=r[s],m=c.event;c=c.listeners;e:{var E=void 0;if(a)for(var D=c.length-1;0<=D;D--){var x=c[D],H=x.instance,ae=x.currentTarget;if(x=x.listener,H!==E&&m.isPropagationStopped())break e;E=x,m.currentTarget=ae;try{E(m)}catch(de){Sc(de)}m.currentTarget=null,E=H}else for(D=0;D<c.length;D++){if(x=c[D],H=x.instance,ae=x.currentTarget,x=x.listener,H!==E&&m.isPropagationStopped())break e;E=x,m.currentTarget=ae;try{E(m)}catch(de){Sc(de)}m.currentTarget=null,E=H}}}}function ct(r,a){var s=a[Fe];s===void 0&&(s=a[Fe]=new Set);var c=r+"__bubble";s.has(c)||(tb(a,r,2,!1),s.add(c))}function sm(r,a,s){var c=0;a&&(c|=4),tb(s,r,c,a)}var Pc="_reactListening"+Math.random().toString(36).slice(2);function om(r){if(!r[Pc]){r[Pc]=!0,Se.forEach(function(s){s!=="selectionchange"&&(cR.has(s)||sm(s,!1,r),sm(s,!0,r))});var a=r.nodeType===9?r:r.ownerDocument;a===null||a[Pc]||(a[Pc]=!0,sm("selectionchange",!1,a))}}function tb(r,a,s,c){switch(Cb(a)){case 2:var m=FR;break;case 8:m=BR;break;default:m=Sm}s=m.bind(null,a,s,r),m=void 0,!Od||a!=="touchstart"&&a!=="touchmove"&&a!=="wheel"||(m=!0),c?m!==void 0?r.addEventListener(a,s,{capture:!0,passive:m}):r.addEventListener(a,s,!0):m!==void 0?r.addEventListener(a,s,{passive:m}):r.addEventListener(a,s,!1)}function lm(r,a,s,c,m){var E=c;if((a&1)===0&&(a&2)===0&&c!==null)e:for(;;){if(c===null)return;var D=c.tag;if(D===3||D===4){var x=c.stateNode.containerInfo;if(x===m)break;if(D===4)for(D=c.return;D!==null;){var H=D.tag;if((H===3||H===4)&&D.stateNode.containerInfo===m)return;D=D.return}for(;x!==null;){if(D=Ge(x),D===null)return;if(H=D.tag,H===5||H===6||H===26||H===27){c=E=D;continue e}x=x.parentNode}}c=c.return}o1(function(){var ae=E,de=Rd(s),me=[];e:{var ue=P1.get(r);if(ue!==void 0){var oe=Ql,Xe=r;switch(r){case"keypress":if(Kl(s)===0)break e;case"keydown":case"keyup":oe=i3;break;case"focusin":Xe="focus",oe=Md;break;case"focusout":Xe="blur",oe=Md;break;case"beforeblur":case"afterblur":oe=Md;break;case"click":if(s.button===2)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":oe=f1;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":oe=Gx;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":oe=s3;break;case k1:case L1:case M1:oe=Wx;break;case I1:oe=l3;break;case"scroll":case"scrollend":oe=qx;break;case"wheel":oe=f3;break;case"copy":case"cut":case"paste":oe=$x;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":oe=h1;break;case"toggle":case"beforetoggle":oe=h3}var qe=(a&4)!==0,xt=!qe&&(r==="scroll"||r==="scrollend"),ee=qe?ue!==null?ue+"Capture":null:ue;qe=[];for(var X=ae,re;X!==null;){var he=X;if(re=he.stateNode,he=he.tag,he!==5&&he!==26&&he!==27||re===null||ee===null||(he=Ns(X,ee),he!=null&&qe.push(mo(X,he,re))),xt)break;X=X.return}0<qe.length&&(ue=new oe(ue,Xe,null,s,de),me.push({event:ue,listeners:qe}))}}if((a&7)===0){e:{if(ue=r==="mouseover"||r==="pointerover",oe=r==="mouseout"||r==="pointerout",ue&&s!==xd&&(Xe=s.relatedTarget||s.fromElement)&&(Ge(Xe)||Xe[we]))break e;if((oe||ue)&&(ue=de.window===de?de:(ue=de.ownerDocument)?ue.defaultView||ue.parentWindow:window,oe?(Xe=s.relatedTarget||s.toElement,oe=ae,Xe=Xe?Ge(Xe):null,Xe!==null&&(xt=o(Xe),qe=Xe.tag,Xe!==xt||qe!==5&&qe!==27&&qe!==6)&&(Xe=null)):(oe=null,Xe=ae),oe!==Xe)){if(qe=f1,he="onMouseLeave",ee="onMouseEnter",X="mouse",(r==="pointerout"||r==="pointerover")&&(qe=h1,he="onPointerLeave",ee="onPointerEnter",X="pointer"),xt=oe==null?ue:Dt(oe),re=Xe==null?ue:Dt(Xe),ue=new qe(he,X+"leave",oe,s,de),ue.target=xt,ue.relatedTarget=re,he=null,Ge(de)===ae&&(qe=new qe(ee,X+"enter",Xe,s,de),qe.target=re,qe.relatedTarget=xt,he=qe),xt=he,oe&&Xe)t:{for(qe=oe,ee=Xe,X=0,re=qe;re;re=Gu(re))X++;for(re=0,he=ee;he;he=Gu(he))re++;for(;0<X-re;)qe=Gu(qe),X--;for(;0<re-X;)ee=Gu(ee),re--;for(;X--;){if(qe===ee||ee!==null&&qe===ee.alternate)break t;qe=Gu(qe),ee=Gu(ee)}qe=null}else qe=null;oe!==null&&nb(me,ue,oe,qe,!1),Xe!==null&&xt!==null&&nb(me,xt,Xe,qe,!0)}}e:{if(ue=ae?Dt(ae):window,oe=ue.nodeName&&ue.nodeName.toLowerCase(),oe==="select"||oe==="input"&&ue.type==="file")var Le=A1;else if(b1(ue))if(S1)Le=D3;else{Le=A3;var ut=T3}else oe=ue.nodeName,!oe||oe.toLowerCase()!=="input"||ue.type!=="checkbox"&&ue.type!=="radio"?ae&&_d(ae.elementType)&&(Le=A1):Le=S3;if(Le&&(Le=Le(r,ae))){T1(me,Le,s,de);break e}ut&&ut(r,ue,ae),r==="focusout"&&ae&&ue.type==="number"&&ae.memoizedProps.value!=null&&Cd(ue,"number",ue.value)}switch(ut=ae?Dt(ae):window,r){case"focusin":(b1(ut)||ut.contentEditable==="true")&&(Su=ut,Hd=ae,Us=null);break;case"focusout":Us=Hd=Su=null;break;case"mousedown":zd=!0;break;case"contextmenu":case"mouseup":case"dragend":zd=!1,O1(me,s,de);break;case"selectionchange":if(C3)break;case"keydown":case"keyup":O1(me,s,de)}var He;if(Pd)e:{switch(r){case"compositionstart":var Ye="onCompositionStart";break e;case"compositionend":Ye="onCompositionEnd";break e;case"compositionupdate":Ye="onCompositionUpdate";break e}Ye=void 0}else Au?E1(r,s)&&(Ye="onCompositionEnd"):r==="keydown"&&s.keyCode===229&&(Ye="onCompositionStart");Ye&&(m1&&s.locale!=="ko"&&(Au||Ye!=="onCompositionStart"?Ye==="onCompositionEnd"&&Au&&(He=l1()):(qi=de,Nd="value"in qi?qi.value:qi.textContent,Au=!0)),ut=Fc(ae,Ye),0<ut.length&&(Ye=new d1(Ye,r,null,s,de),me.push({event:Ye,listeners:ut}),He?Ye.data=He:(He=y1(s),He!==null&&(Ye.data=He)))),(He=p3?g3(r,s):E3(r,s))&&(Ye=Fc(ae,"onBeforeInput"),0<Ye.length&&(ut=new d1("onBeforeInput","beforeinput",null,s,de),me.push({event:ut,listeners:Ye}),ut.data=He)),sR(me,r,ae,s,de)}eb(me,a)})}function mo(r,a,s){return{instance:r,listener:a,currentTarget:s}}function Fc(r,a){for(var s=a+"Capture",c=[];r!==null;){var m=r,E=m.stateNode;if(m=m.tag,m!==5&&m!==26&&m!==27||E===null||(m=Ns(r,s),m!=null&&c.unshift(mo(r,m,E)),m=Ns(r,a),m!=null&&c.push(mo(r,m,E))),r.tag===3)return c;r=r.return}return[]}function Gu(r){if(r===null)return null;do r=r.return;while(r&&r.tag!==5&&r.tag!==27);return r||null}function nb(r,a,s,c,m){for(var E=a._reactName,D=[];s!==null&&s!==c;){var x=s,H=x.alternate,ae=x.stateNode;if(x=x.tag,H!==null&&H===c)break;x!==5&&x!==26&&x!==27||ae===null||(H=ae,m?(ae=Ns(s,E),ae!=null&&D.unshift(mo(s,ae,H))):m||(ae=Ns(s,E),ae!=null&&D.push(mo(s,ae,H)))),s=s.return}D.length!==0&&r.push({event:a,listeners:D})}var fR=/\r\n?/g,dR=/\u0000|\uFFFD/g;function rb(r){return(typeof r=="string"?r:""+r).replace(fR,` +`).replace(dR,"")}function ib(r,a){return a=rb(a),rb(r)===a}function Bc(){}function _t(r,a,s,c,m,E){switch(s){case"children":typeof c=="string"?a==="body"||a==="textarea"&&c===""||yu(r,c):(typeof c=="number"||typeof c=="bigint")&&a!=="body"&&yu(r,""+c);break;case"className":Bn(r,"class",c);break;case"tabIndex":Bn(r,"tabindex",c);break;case"dir":case"role":case"viewBox":case"width":case"height":Bn(r,s,c);break;case"style":u1(r,c,E);break;case"data":if(a!=="object"){Bn(r,"data",c);break}case"src":case"href":if(c===""&&(a!=="a"||s!=="href")){r.removeAttribute(s);break}if(c==null||typeof c=="function"||typeof c=="symbol"||typeof c=="boolean"){r.removeAttribute(s);break}c=Gl(""+c),r.setAttribute(s,c);break;case"action":case"formAction":if(typeof c=="function"){r.setAttribute(s,"javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')");break}else typeof E=="function"&&(s==="formAction"?(a!=="input"&&_t(r,a,"name",m.name,m,null),_t(r,a,"formEncType",m.formEncType,m,null),_t(r,a,"formMethod",m.formMethod,m,null),_t(r,a,"formTarget",m.formTarget,m,null)):(_t(r,a,"encType",m.encType,m,null),_t(r,a,"method",m.method,m,null),_t(r,a,"target",m.target,m,null)));if(c==null||typeof c=="symbol"||typeof c=="boolean"){r.removeAttribute(s);break}c=Gl(""+c),r.setAttribute(s,c);break;case"onClick":c!=null&&(r.onclick=Bc);break;case"onScroll":c!=null&&ct("scroll",r);break;case"onScrollEnd":c!=null&&ct("scrollend",r);break;case"dangerouslySetInnerHTML":if(c!=null){if(typeof c!="object"||!("__html"in c))throw Error(i(61));if(s=c.__html,s!=null){if(m.children!=null)throw Error(i(60));r.innerHTML=s}}break;case"multiple":r.multiple=c&&typeof c!="function"&&typeof c!="symbol";break;case"muted":r.muted=c&&typeof c!="function"&&typeof c!="symbol";break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"defaultValue":case"defaultChecked":case"innerHTML":case"ref":break;case"autoFocus":break;case"xlinkHref":if(c==null||typeof c=="function"||typeof c=="boolean"||typeof c=="symbol"){r.removeAttribute("xlink:href");break}s=Gl(""+c),r.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",s);break;case"contentEditable":case"spellCheck":case"draggable":case"value":case"autoReverse":case"externalResourcesRequired":case"focusable":case"preserveAlpha":c!=null&&typeof c!="function"&&typeof c!="symbol"?r.setAttribute(s,""+c):r.removeAttribute(s);break;case"inert":case"allowFullScreen":case"async":case"autoPlay":case"controls":case"default":case"defer":case"disabled":case"disablePictureInPicture":case"disableRemotePlayback":case"formNoValidate":case"hidden":case"loop":case"noModule":case"noValidate":case"open":case"playsInline":case"readOnly":case"required":case"reversed":case"scoped":case"seamless":case"itemScope":c&&typeof c!="function"&&typeof c!="symbol"?r.setAttribute(s,""):r.removeAttribute(s);break;case"capture":case"download":c===!0?r.setAttribute(s,""):c!==!1&&c!=null&&typeof c!="function"&&typeof c!="symbol"?r.setAttribute(s,c):r.removeAttribute(s);break;case"cols":case"rows":case"size":case"span":c!=null&&typeof c!="function"&&typeof c!="symbol"&&!isNaN(c)&&1<=c?r.setAttribute(s,c):r.removeAttribute(s);break;case"rowSpan":case"start":c==null||typeof c=="function"||typeof c=="symbol"||isNaN(c)?r.removeAttribute(s):r.setAttribute(s,c);break;case"popover":ct("beforetoggle",r),ct("toggle",r),$t(r,"popover",c);break;case"xlinkActuate":$e(r,"http://www.w3.org/1999/xlink","xlink:actuate",c);break;case"xlinkArcrole":$e(r,"http://www.w3.org/1999/xlink","xlink:arcrole",c);break;case"xlinkRole":$e(r,"http://www.w3.org/1999/xlink","xlink:role",c);break;case"xlinkShow":$e(r,"http://www.w3.org/1999/xlink","xlink:show",c);break;case"xlinkTitle":$e(r,"http://www.w3.org/1999/xlink","xlink:title",c);break;case"xlinkType":$e(r,"http://www.w3.org/1999/xlink","xlink:type",c);break;case"xmlBase":$e(r,"http://www.w3.org/XML/1998/namespace","xml:base",c);break;case"xmlLang":$e(r,"http://www.w3.org/XML/1998/namespace","xml:lang",c);break;case"xmlSpace":$e(r,"http://www.w3.org/XML/1998/namespace","xml:space",c);break;case"is":$t(r,"is",c);break;case"innerText":case"textContent":break;default:(!(2<s.length)||s[0]!=="o"&&s[0]!=="O"||s[1]!=="n"&&s[1]!=="N")&&(s=Vx.get(s)||s,$t(r,s,c))}}function cm(r,a,s,c,m,E){switch(s){case"style":u1(r,c,E);break;case"dangerouslySetInnerHTML":if(c!=null){if(typeof c!="object"||!("__html"in c))throw Error(i(61));if(s=c.__html,s!=null){if(m.children!=null)throw Error(i(60));r.innerHTML=s}}break;case"children":typeof c=="string"?yu(r,c):(typeof c=="number"||typeof c=="bigint")&&yu(r,""+c);break;case"onScroll":c!=null&&ct("scroll",r);break;case"onScrollEnd":c!=null&&ct("scrollend",r);break;case"onClick":c!=null&&(r.onclick=Bc);break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"innerHTML":case"ref":break;case"innerText":case"textContent":break;default:if(!G.hasOwnProperty(s))e:{if(s[0]==="o"&&s[1]==="n"&&(m=s.endsWith("Capture"),a=s.slice(2,m?s.length-7:void 0),E=r[Ce]||null,E=E!=null?E[s]:null,typeof E=="function"&&r.removeEventListener(a,E,m),typeof c=="function")){typeof E!="function"&&E!==null&&(s in r?r[s]=null:r.hasAttribute(s)&&r.removeAttribute(s)),r.addEventListener(a,c,m);break e}s in r?r[s]=c:c===!0?r.setAttribute(s,""):$t(r,s,c)}}}function Rn(r,a,s){switch(a){case"div":case"span":case"svg":case"path":case"a":case"g":case"p":case"li":break;case"img":ct("error",r),ct("load",r);var c=!1,m=!1,E;for(E in s)if(s.hasOwnProperty(E)){var D=s[E];if(D!=null)switch(E){case"src":c=!0;break;case"srcSet":m=!0;break;case"children":case"dangerouslySetInnerHTML":throw Error(i(137,a));default:_t(r,a,E,D,s,null)}}m&&_t(r,a,"srcSet",s.srcSet,s,null),c&&_t(r,a,"src",s.src,s,null);return;case"input":ct("invalid",r);var x=E=D=m=null,H=null,ae=null;for(c in s)if(s.hasOwnProperty(c)){var de=s[c];if(de!=null)switch(c){case"name":m=de;break;case"type":D=de;break;case"checked":H=de;break;case"defaultChecked":ae=de;break;case"value":E=de;break;case"defaultValue":x=de;break;case"children":case"dangerouslySetInnerHTML":if(de!=null)throw Error(i(137,a));break;default:_t(r,a,c,de,s,null)}}n1(r,E,x,H,ae,D,m,!1),ql(r);return;case"select":ct("invalid",r),c=D=E=null;for(m in s)if(s.hasOwnProperty(m)&&(x=s[m],x!=null))switch(m){case"value":E=x;break;case"defaultValue":D=x;break;case"multiple":c=x;default:_t(r,a,m,x,s,null)}a=E,s=D,r.multiple=!!c,a!=null?Eu(r,!!c,a,!1):s!=null&&Eu(r,!!c,s,!0);return;case"textarea":ct("invalid",r),E=m=c=null;for(D in s)if(s.hasOwnProperty(D)&&(x=s[D],x!=null))switch(D){case"value":c=x;break;case"defaultValue":m=x;break;case"children":E=x;break;case"dangerouslySetInnerHTML":if(x!=null)throw Error(i(91));break;default:_t(r,a,D,x,s,null)}i1(r,c,m,E),ql(r);return;case"option":for(H in s)if(s.hasOwnProperty(H)&&(c=s[H],c!=null))switch(H){case"selected":r.selected=c&&typeof c!="function"&&typeof c!="symbol";break;default:_t(r,a,H,c,s,null)}return;case"dialog":ct("beforetoggle",r),ct("toggle",r),ct("cancel",r),ct("close",r);break;case"iframe":case"object":ct("load",r);break;case"video":case"audio":for(c=0;c<ho.length;c++)ct(ho[c],r);break;case"image":ct("error",r),ct("load",r);break;case"details":ct("toggle",r);break;case"embed":case"source":case"link":ct("error",r),ct("load",r);case"area":case"base":case"br":case"col":case"hr":case"keygen":case"meta":case"param":case"track":case"wbr":case"menuitem":for(ae in s)if(s.hasOwnProperty(ae)&&(c=s[ae],c!=null))switch(ae){case"children":case"dangerouslySetInnerHTML":throw Error(i(137,a));default:_t(r,a,ae,c,s,null)}return;default:if(_d(a)){for(de in s)s.hasOwnProperty(de)&&(c=s[de],c!==void 0&&cm(r,a,de,c,s,void 0));return}}for(x in s)s.hasOwnProperty(x)&&(c=s[x],c!=null&&_t(r,a,x,c,s,null))}function hR(r,a,s,c){switch(a){case"div":case"span":case"svg":case"path":case"a":case"g":case"p":case"li":break;case"input":var m=null,E=null,D=null,x=null,H=null,ae=null,de=null;for(oe in s){var me=s[oe];if(s.hasOwnProperty(oe)&&me!=null)switch(oe){case"checked":break;case"value":break;case"defaultValue":H=me;default:c.hasOwnProperty(oe)||_t(r,a,oe,null,c,me)}}for(var ue in c){var oe=c[ue];if(me=s[ue],c.hasOwnProperty(ue)&&(oe!=null||me!=null))switch(ue){case"type":E=oe;break;case"name":m=oe;break;case"checked":ae=oe;break;case"defaultChecked":de=oe;break;case"value":D=oe;break;case"defaultValue":x=oe;break;case"children":case"dangerouslySetInnerHTML":if(oe!=null)throw Error(i(137,a));break;default:oe!==me&&_t(r,a,ue,oe,c,me)}}vd(r,D,x,H,ae,de,E,m);return;case"select":oe=D=x=ue=null;for(E in s)if(H=s[E],s.hasOwnProperty(E)&&H!=null)switch(E){case"value":break;case"multiple":oe=H;default:c.hasOwnProperty(E)||_t(r,a,E,null,c,H)}for(m in c)if(E=c[m],H=s[m],c.hasOwnProperty(m)&&(E!=null||H!=null))switch(m){case"value":ue=E;break;case"defaultValue":x=E;break;case"multiple":D=E;default:E!==H&&_t(r,a,m,E,c,H)}a=x,s=D,c=oe,ue!=null?Eu(r,!!s,ue,!1):!!c!=!!s&&(a!=null?Eu(r,!!s,a,!0):Eu(r,!!s,s?[]:"",!1));return;case"textarea":oe=ue=null;for(x in s)if(m=s[x],s.hasOwnProperty(x)&&m!=null&&!c.hasOwnProperty(x))switch(x){case"value":break;case"children":break;default:_t(r,a,x,null,c,m)}for(D in c)if(m=c[D],E=s[D],c.hasOwnProperty(D)&&(m!=null||E!=null))switch(D){case"value":ue=m;break;case"defaultValue":oe=m;break;case"children":break;case"dangerouslySetInnerHTML":if(m!=null)throw Error(i(91));break;default:m!==E&&_t(r,a,D,m,c,E)}r1(r,ue,oe);return;case"option":for(var Xe in s)if(ue=s[Xe],s.hasOwnProperty(Xe)&&ue!=null&&!c.hasOwnProperty(Xe))switch(Xe){case"selected":r.selected=!1;break;default:_t(r,a,Xe,null,c,ue)}for(H in c)if(ue=c[H],oe=s[H],c.hasOwnProperty(H)&&ue!==oe&&(ue!=null||oe!=null))switch(H){case"selected":r.selected=ue&&typeof ue!="function"&&typeof ue!="symbol";break;default:_t(r,a,H,ue,c,oe)}return;case"img":case"link":case"area":case"base":case"br":case"col":case"embed":case"hr":case"keygen":case"meta":case"param":case"source":case"track":case"wbr":case"menuitem":for(var qe in s)ue=s[qe],s.hasOwnProperty(qe)&&ue!=null&&!c.hasOwnProperty(qe)&&_t(r,a,qe,null,c,ue);for(ae in c)if(ue=c[ae],oe=s[ae],c.hasOwnProperty(ae)&&ue!==oe&&(ue!=null||oe!=null))switch(ae){case"children":case"dangerouslySetInnerHTML":if(ue!=null)throw Error(i(137,a));break;default:_t(r,a,ae,ue,c,oe)}return;default:if(_d(a)){for(var xt in s)ue=s[xt],s.hasOwnProperty(xt)&&ue!==void 0&&!c.hasOwnProperty(xt)&&cm(r,a,xt,void 0,c,ue);for(de in c)ue=c[de],oe=s[de],!c.hasOwnProperty(de)||ue===oe||ue===void 0&&oe===void 0||cm(r,a,de,ue,c,oe);return}}for(var ee in s)ue=s[ee],s.hasOwnProperty(ee)&&ue!=null&&!c.hasOwnProperty(ee)&&_t(r,a,ee,null,c,ue);for(me in c)ue=c[me],oe=s[me],!c.hasOwnProperty(me)||ue===oe||ue==null&&oe==null||_t(r,a,me,ue,c,oe)}var fm=null,dm=null;function Uc(r){return r.nodeType===9?r:r.ownerDocument}function ab(r){switch(r){case"http://www.w3.org/2000/svg":return 1;case"http://www.w3.org/1998/Math/MathML":return 2;default:return 0}}function ub(r,a){if(r===0)switch(a){case"svg":return 1;case"math":return 2;default:return 0}return r===1&&a==="foreignObject"?0:r}function hm(r,a){return r==="textarea"||r==="noscript"||typeof a.children=="string"||typeof a.children=="number"||typeof a.children=="bigint"||typeof a.dangerouslySetInnerHTML=="object"&&a.dangerouslySetInnerHTML!==null&&a.dangerouslySetInnerHTML.__html!=null}var mm=null;function mR(){var r=window.event;return r&&r.type==="popstate"?r===mm?!1:(mm=r,!0):(mm=null,!1)}var sb=typeof setTimeout=="function"?setTimeout:void 0,pR=typeof clearTimeout=="function"?clearTimeout:void 0,ob=typeof Promise=="function"?Promise:void 0,gR=typeof queueMicrotask=="function"?queueMicrotask:typeof ob<"u"?function(r){return ob.resolve(null).then(r).catch(ER)}:sb;function ER(r){setTimeout(function(){throw r})}function ua(r){return r==="head"}function lb(r,a){var s=a,c=0,m=0;do{var E=s.nextSibling;if(r.removeChild(s),E&&E.nodeType===8)if(s=E.data,s==="/$"){if(0<c&&8>c){s=c;var D=r.ownerDocument;if(s&1&&po(D.documentElement),s&2&&po(D.body),s&4)for(s=D.head,po(s),D=s.firstChild;D;){var x=D.nextSibling,H=D.nodeName;D[je]||H==="SCRIPT"||H==="STYLE"||H==="LINK"&&D.rel.toLowerCase()==="stylesheet"||s.removeChild(D),D=x}}if(m===0){r.removeChild(E),Do(a);return}m--}else s==="$"||s==="$?"||s==="$!"?m++:c=s.charCodeAt(0)-48;else c=0;s=E}while(s);Do(a)}function pm(r){var a=r.firstChild;for(a&&a.nodeType===10&&(a=a.nextSibling);a;){var s=a;switch(a=a.nextSibling,s.nodeName){case"HTML":case"HEAD":case"BODY":pm(s),Ue(s);continue;case"SCRIPT":case"STYLE":continue;case"LINK":if(s.rel.toLowerCase()==="stylesheet")continue}r.removeChild(s)}}function yR(r,a,s,c){for(;r.nodeType===1;){var m=s;if(r.nodeName.toLowerCase()!==a.toLowerCase()){if(!c&&(r.nodeName!=="INPUT"||r.type!=="hidden"))break}else if(c){if(!r[je])switch(a){case"meta":if(!r.hasAttribute("itemprop"))break;return r;case"link":if(E=r.getAttribute("rel"),E==="stylesheet"&&r.hasAttribute("data-precedence"))break;if(E!==m.rel||r.getAttribute("href")!==(m.href==null||m.href===""?null:m.href)||r.getAttribute("crossorigin")!==(m.crossOrigin==null?null:m.crossOrigin)||r.getAttribute("title")!==(m.title==null?null:m.title))break;return r;case"style":if(r.hasAttribute("data-precedence"))break;return r;case"script":if(E=r.getAttribute("src"),(E!==(m.src==null?null:m.src)||r.getAttribute("type")!==(m.type==null?null:m.type)||r.getAttribute("crossorigin")!==(m.crossOrigin==null?null:m.crossOrigin))&&E&&r.hasAttribute("async")&&!r.hasAttribute("itemprop"))break;return r;default:return r}}else if(a==="input"&&r.type==="hidden"){var E=m.name==null?null:""+m.name;if(m.type==="hidden"&&r.getAttribute("name")===E)return r}else return r;if(r=Xr(r.nextSibling),r===null)break}return null}function bR(r,a,s){if(a==="")return null;for(;r.nodeType!==3;)if((r.nodeType!==1||r.nodeName!=="INPUT"||r.type!=="hidden")&&!s||(r=Xr(r.nextSibling),r===null))return null;return r}function gm(r){return r.data==="$!"||r.data==="$?"&&r.ownerDocument.readyState==="complete"}function TR(r,a){var s=r.ownerDocument;if(r.data!=="$?"||s.readyState==="complete")a();else{var c=function(){a(),s.removeEventListener("DOMContentLoaded",c)};s.addEventListener("DOMContentLoaded",c),r._reactRetry=c}}function Xr(r){for(;r!=null;r=r.nextSibling){var a=r.nodeType;if(a===1||a===3)break;if(a===8){if(a=r.data,a==="$"||a==="$!"||a==="$?"||a==="F!"||a==="F")break;if(a==="/$")return null}}return r}var Em=null;function cb(r){r=r.previousSibling;for(var a=0;r;){if(r.nodeType===8){var s=r.data;if(s==="$"||s==="$!"||s==="$?"){if(a===0)return r;a--}else s==="/$"&&a++}r=r.previousSibling}return null}function fb(r,a,s){switch(a=Uc(s),r){case"html":if(r=a.documentElement,!r)throw Error(i(452));return r;case"head":if(r=a.head,!r)throw Error(i(453));return r;case"body":if(r=a.body,!r)throw Error(i(454));return r;default:throw Error(i(451))}}function po(r){for(var a=r.attributes;a.length;)r.removeAttributeNode(a[0]);Ue(r)}var kr=new Map,db=new Set;function Hc(r){return typeof r.getRootNode=="function"?r.getRootNode():r.nodeType===9?r:r.ownerDocument}var Ii=K.d;K.d={f:AR,r:SR,D:DR,C:vR,L:CR,m:_R,X:RR,S:xR,M:wR};function AR(){var r=Ii.f(),a=Nc();return r||a}function SR(r){var a=dt(r);a!==null&&a.tag===5&&a.type==="form"?kE(a):Ii.r(r)}var Xu=typeof document>"u"?null:document;function hb(r,a,s){var c=Xu;if(c&&typeof a=="string"&&a){var m=Cr(a);m='link[rel="'+r+'"][href="'+m+'"]',typeof s=="string"&&(m+='[crossorigin="'+s+'"]'),db.has(m)||(db.add(m),r={rel:r,crossOrigin:s,href:a},c.querySelector(m)===null&&(a=c.createElement("link"),Rn(a,"link",r),pt(a),c.head.appendChild(a)))}}function DR(r){Ii.D(r),hb("dns-prefetch",r,null)}function vR(r,a){Ii.C(r,a),hb("preconnect",r,a)}function CR(r,a,s){Ii.L(r,a,s);var c=Xu;if(c&&r&&a){var m='link[rel="preload"][as="'+Cr(a)+'"]';a==="image"&&s&&s.imageSrcSet?(m+='[imagesrcset="'+Cr(s.imageSrcSet)+'"]',typeof s.imageSizes=="string"&&(m+='[imagesizes="'+Cr(s.imageSizes)+'"]')):m+='[href="'+Cr(r)+'"]';var E=m;switch(a){case"style":E=Ku(r);break;case"script":E=Wu(r)}kr.has(E)||(r=p({rel:"preload",href:a==="image"&&s&&s.imageSrcSet?void 0:r,as:a},s),kr.set(E,r),c.querySelector(m)!==null||a==="style"&&c.querySelector(go(E))||a==="script"&&c.querySelector(Eo(E))||(a=c.createElement("link"),Rn(a,"link",r),pt(a),c.head.appendChild(a)))}}function _R(r,a){Ii.m(r,a);var s=Xu;if(s&&r){var c=a&&typeof a.as=="string"?a.as:"script",m='link[rel="modulepreload"][as="'+Cr(c)+'"][href="'+Cr(r)+'"]',E=m;switch(c){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":E=Wu(r)}if(!kr.has(E)&&(r=p({rel:"modulepreload",href:r},a),kr.set(E,r),s.querySelector(m)===null)){switch(c){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(s.querySelector(Eo(E)))return}c=s.createElement("link"),Rn(c,"link",r),pt(c),s.head.appendChild(c)}}}function xR(r,a,s){Ii.S(r,a,s);var c=Xu;if(c&&r){var m=Lt(c).hoistableStyles,E=Ku(r);a=a||"default";var D=m.get(E);if(!D){var x={loading:0,preload:null};if(D=c.querySelector(go(E)))x.loading=5;else{r=p({rel:"stylesheet",href:r,"data-precedence":a},s),(s=kr.get(E))&&ym(r,s);var H=D=c.createElement("link");pt(H),Rn(H,"link",r),H._p=new Promise(function(ae,de){H.onload=ae,H.onerror=de}),H.addEventListener("load",function(){x.loading|=1}),H.addEventListener("error",function(){x.loading|=2}),x.loading|=4,zc(D,a,c)}D={type:"stylesheet",instance:D,count:1,state:x},m.set(E,D)}}}function RR(r,a){Ii.X(r,a);var s=Xu;if(s&&r){var c=Lt(s).hoistableScripts,m=Wu(r),E=c.get(m);E||(E=s.querySelector(Eo(m)),E||(r=p({src:r,async:!0},a),(a=kr.get(m))&&bm(r,a),E=s.createElement("script"),pt(E),Rn(E,"link",r),s.head.appendChild(E)),E={type:"script",instance:E,count:1,state:null},c.set(m,E))}}function wR(r,a){Ii.M(r,a);var s=Xu;if(s&&r){var c=Lt(s).hoistableScripts,m=Wu(r),E=c.get(m);E||(E=s.querySelector(Eo(m)),E||(r=p({src:r,async:!0,type:"module"},a),(a=kr.get(m))&&bm(r,a),E=s.createElement("script"),pt(E),Rn(E,"link",r),s.head.appendChild(E)),E={type:"script",instance:E,count:1,state:null},c.set(m,E))}}function mb(r,a,s,c){var m=(m=xe.current)?Hc(m):null;if(!m)throw Error(i(446));switch(r){case"meta":case"title":return null;case"style":return typeof s.precedence=="string"&&typeof s.href=="string"?(a=Ku(s.href),s=Lt(m).hoistableStyles,c=s.get(a),c||(c={type:"style",instance:null,count:0,state:null},s.set(a,c)),c):{type:"void",instance:null,count:0,state:null};case"link":if(s.rel==="stylesheet"&&typeof s.href=="string"&&typeof s.precedence=="string"){r=Ku(s.href);var E=Lt(m).hoistableStyles,D=E.get(r);if(D||(m=m.ownerDocument||m,D={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},E.set(r,D),(E=m.querySelector(go(r)))&&!E._p&&(D.instance=E,D.state.loading=5),kr.has(r)||(s={rel:"preload",as:"style",href:s.href,crossOrigin:s.crossOrigin,integrity:s.integrity,media:s.media,hrefLang:s.hrefLang,referrerPolicy:s.referrerPolicy},kr.set(r,s),E||OR(m,r,s,D.state))),a&&c===null)throw Error(i(528,""));return D}if(a&&c!==null)throw Error(i(529,""));return null;case"script":return a=s.async,s=s.src,typeof s=="string"&&a&&typeof a!="function"&&typeof a!="symbol"?(a=Wu(s),s=Lt(m).hoistableScripts,c=s.get(a),c||(c={type:"script",instance:null,count:0,state:null},s.set(a,c)),c):{type:"void",instance:null,count:0,state:null};default:throw Error(i(444,r))}}function Ku(r){return'href="'+Cr(r)+'"'}function go(r){return'link[rel="stylesheet"]['+r+"]"}function pb(r){return p({},r,{"data-precedence":r.precedence,precedence:null})}function OR(r,a,s,c){r.querySelector('link[rel="preload"][as="style"]['+a+"]")?c.loading=1:(a=r.createElement("link"),c.preload=a,a.addEventListener("load",function(){return c.loading|=1}),a.addEventListener("error",function(){return c.loading|=2}),Rn(a,"link",s),pt(a),r.head.appendChild(a))}function Wu(r){return'[src="'+Cr(r)+'"]'}function Eo(r){return"script[async]"+r}function gb(r,a,s){if(a.count++,a.instance===null)switch(a.type){case"style":var c=r.querySelector('style[data-href~="'+Cr(s.href)+'"]');if(c)return a.instance=c,pt(c),c;var m=p({},s,{"data-href":s.href,"data-precedence":s.precedence,href:null,precedence:null});return c=(r.ownerDocument||r).createElement("style"),pt(c),Rn(c,"style",m),zc(c,s.precedence,r),a.instance=c;case"stylesheet":m=Ku(s.href);var E=r.querySelector(go(m));if(E)return a.state.loading|=4,a.instance=E,pt(E),E;c=pb(s),(m=kr.get(m))&&ym(c,m),E=(r.ownerDocument||r).createElement("link"),pt(E);var D=E;return D._p=new Promise(function(x,H){D.onload=x,D.onerror=H}),Rn(E,"link",c),a.state.loading|=4,zc(E,s.precedence,r),a.instance=E;case"script":return E=Wu(s.src),(m=r.querySelector(Eo(E)))?(a.instance=m,pt(m),m):(c=s,(m=kr.get(E))&&(c=p({},s),bm(c,m)),r=r.ownerDocument||r,m=r.createElement("script"),pt(m),Rn(m,"link",c),r.head.appendChild(m),a.instance=m);case"void":return null;default:throw Error(i(443,a.type))}else a.type==="stylesheet"&&(a.state.loading&4)===0&&(c=a.instance,a.state.loading|=4,zc(c,s.precedence,r));return a.instance}function zc(r,a,s){for(var c=s.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),m=c.length?c[c.length-1]:null,E=m,D=0;D<c.length;D++){var x=c[D];if(x.dataset.precedence===a)E=x;else if(E!==m)break}E?E.parentNode.insertBefore(r,E.nextSibling):(a=s.nodeType===9?s.head:s,a.insertBefore(r,a.firstChild))}function ym(r,a){r.crossOrigin==null&&(r.crossOrigin=a.crossOrigin),r.referrerPolicy==null&&(r.referrerPolicy=a.referrerPolicy),r.title==null&&(r.title=a.title)}function bm(r,a){r.crossOrigin==null&&(r.crossOrigin=a.crossOrigin),r.referrerPolicy==null&&(r.referrerPolicy=a.referrerPolicy),r.integrity==null&&(r.integrity=a.integrity)}var Vc=null;function Eb(r,a,s){if(Vc===null){var c=new Map,m=Vc=new Map;m.set(s,c)}else m=Vc,c=m.get(s),c||(c=new Map,m.set(s,c));if(c.has(r))return c;for(c.set(r,null),s=s.getElementsByTagName(r),m=0;m<s.length;m++){var E=s[m];if(!(E[je]||E[pe]||r==="link"&&E.getAttribute("rel")==="stylesheet")&&E.namespaceURI!=="http://www.w3.org/2000/svg"){var D=E.getAttribute(a)||"";D=r+D;var x=c.get(D);x?x.push(E):c.set(D,[E])}}return c}function yb(r,a,s){r=r.ownerDocument||r,r.head.insertBefore(s,a==="title"?r.querySelector("head > title"):null)}function NR(r,a,s){if(s===1||a.itemProp!=null)return!1;switch(r){case"meta":case"title":return!0;case"style":if(typeof a.precedence!="string"||typeof a.href!="string"||a.href==="")break;return!0;case"link":if(typeof a.rel!="string"||typeof a.href!="string"||a.href===""||a.onLoad||a.onError)break;switch(a.rel){case"stylesheet":return r=a.disabled,typeof a.precedence=="string"&&r==null;default:return!0}case"script":if(a.async&&typeof a.async!="function"&&typeof a.async!="symbol"&&!a.onLoad&&!a.onError&&a.src&&typeof a.src=="string")return!0}return!1}function bb(r){return!(r.type==="stylesheet"&&(r.state.loading&3)===0)}var yo=null;function kR(){}function LR(r,a,s){if(yo===null)throw Error(i(475));var c=yo;if(a.type==="stylesheet"&&(typeof s.media!="string"||matchMedia(s.media).matches!==!1)&&(a.state.loading&4)===0){if(a.instance===null){var m=Ku(s.href),E=r.querySelector(go(m));if(E){r=E._p,r!==null&&typeof r=="object"&&typeof r.then=="function"&&(c.count++,c=jc.bind(c),r.then(c,c)),a.state.loading|=4,a.instance=E,pt(E);return}E=r.ownerDocument||r,s=pb(s),(m=kr.get(m))&&ym(s,m),E=E.createElement("link"),pt(E);var D=E;D._p=new Promise(function(x,H){D.onload=x,D.onerror=H}),Rn(E,"link",s),a.instance=E}c.stylesheets===null&&(c.stylesheets=new Map),c.stylesheets.set(a,r),(r=a.state.preload)&&(a.state.loading&3)===0&&(c.count++,a=jc.bind(c),r.addEventListener("load",a),r.addEventListener("error",a))}}function MR(){if(yo===null)throw Error(i(475));var r=yo;return r.stylesheets&&r.count===0&&Tm(r,r.stylesheets),0<r.count?function(a){var s=setTimeout(function(){if(r.stylesheets&&Tm(r,r.stylesheets),r.unsuspend){var c=r.unsuspend;r.unsuspend=null,c()}},6e4);return r.unsuspend=a,function(){r.unsuspend=null,clearTimeout(s)}}:null}function jc(){if(this.count--,this.count===0){if(this.stylesheets)Tm(this,this.stylesheets);else if(this.unsuspend){var r=this.unsuspend;this.unsuspend=null,r()}}}var qc=null;function Tm(r,a){r.stylesheets=null,r.unsuspend!==null&&(r.count++,qc=new Map,a.forEach(IR,r),qc=null,jc.call(r))}function IR(r,a){if(!(a.state.loading&4)){var s=qc.get(r);if(s)var c=s.get(null);else{s=new Map,qc.set(r,s);for(var m=r.querySelectorAll("link[data-precedence],style[data-precedence]"),E=0;E<m.length;E++){var D=m[E];(D.nodeName==="LINK"||D.getAttribute("media")!=="not all")&&(s.set(D.dataset.precedence,D),c=D)}c&&s.set(null,c)}m=a.instance,D=m.getAttribute("data-precedence"),E=s.get(D)||c,E===c&&s.set(null,m),s.set(D,m),this.count++,c=jc.bind(this),m.addEventListener("load",c),m.addEventListener("error",c),E?E.parentNode.insertBefore(m,E.nextSibling):(r=r.nodeType===9?r.head:r,r.insertBefore(m,r.firstChild)),a.state.loading|=4}}var bo={$$typeof:R,Provider:null,Consumer:null,_currentValue:Q,_currentValue2:Q,_threadCount:0};function PR(r,a,s,c,m,E,D,x){this.tag=1,this.containerInfo=r,this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.next=this.pendingContext=this.context=this.cancelPendingCommit=null,this.callbackPriority=0,this.expirationTimes=Vi(-1),this.entangledLanes=this.shellSuspendCounter=this.errorRecoveryDisabledLanes=this.expiredLanes=this.warmLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Vi(0),this.hiddenUpdates=Vi(null),this.identifierPrefix=c,this.onUncaughtError=m,this.onCaughtError=E,this.onRecoverableError=D,this.pooledCache=null,this.pooledCacheLanes=0,this.formState=x,this.incompleteTransitions=new Map}function Tb(r,a,s,c,m,E,D,x,H,ae,de,me){return r=new PR(r,a,s,D,x,H,ae,me),a=1,E===!0&&(a|=24),E=lr(3,null,null,a),r.current=E,E.stateNode=r,a=th(),a.refCount++,r.pooledCache=a,a.refCount++,E.memoizedState={element:c,isDehydrated:s,cache:a},ah(E),r}function Ab(r){return r?(r=_u,r):_u}function Sb(r,a,s,c,m,E){m=Ab(m),c.context===null?c.context=m:c.pendingContext=m,c=Xi(a),c.payload={element:s},E=E===void 0?null:E,E!==null&&(c.callback=E),s=Ki(r,c,a),s!==null&&(mr(s,r,a),Ks(s,r,a))}function Db(r,a){if(r=r.memoizedState,r!==null&&r.dehydrated!==null){var s=r.retryLane;r.retryLane=s!==0&&s<a?s:a}}function Am(r,a){Db(r,a),(r=r.alternate)&&Db(r,a)}function vb(r){if(r.tag===13){var a=Cu(r,67108864);a!==null&&mr(a,r,67108864),Am(r,67108864)}}var Yc=!0;function FR(r,a,s,c){var m=B.T;B.T=null;var E=K.p;try{K.p=2,Sm(r,a,s,c)}finally{K.p=E,B.T=m}}function BR(r,a,s,c){var m=B.T;B.T=null;var E=K.p;try{K.p=8,Sm(r,a,s,c)}finally{K.p=E,B.T=m}}function Sm(r,a,s,c){if(Yc){var m=Dm(c);if(m===null)lm(r,a,c,Gc,s),_b(r,c);else if(HR(m,r,a,s,c))c.stopPropagation();else if(_b(r,c),a&4&&-1<UR.indexOf(r)){for(;m!==null;){var E=dt(m);if(E!==null)switch(E.tag){case 3:if(E=E.stateNode,E.current.memoizedState.isDehydrated){var D=Qt(E.pendingLanes);if(D!==0){var x=E;for(x.pendingLanes|=2,x.entangledLanes|=2;D;){var H=1<<31-ze(D);x.entanglements[1]|=H,D&=~H}ci(E),(At&6)===0&&(wc=Yt()+500,fo(0))}}break;case 13:x=Cu(E,2),x!==null&&mr(x,E,2),Nc(),Am(E,2)}if(E=Dm(c),E===null&&lm(r,a,c,Gc,s),E===m)break;m=E}m!==null&&c.stopPropagation()}else lm(r,a,c,null,s)}}function Dm(r){return r=Rd(r),vm(r)}var Gc=null;function vm(r){if(Gc=null,r=Ge(r),r!==null){var a=o(r);if(a===null)r=null;else{var s=a.tag;if(s===13){if(r=l(a),r!==null)return r;r=null}else if(s===3){if(a.stateNode.current.memoizedState.isDehydrated)return a.tag===3?a.stateNode.containerInfo:null;r=null}else a!==r&&(r=null)}}return Gc=r,null}function Cb(r){switch(r){case"beforetoggle":case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"toggle":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 2;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 8;case"message":switch(ii()){case Sr:return 2;case ai:return 8;case jr:case ur:return 32;case Yn:return 268435456;default:return 32}default:return 32}}var Cm=!1,sa=null,oa=null,la=null,To=new Map,Ao=new Map,ca=[],UR="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset".split(" ");function _b(r,a){switch(r){case"focusin":case"focusout":sa=null;break;case"dragenter":case"dragleave":oa=null;break;case"mouseover":case"mouseout":la=null;break;case"pointerover":case"pointerout":To.delete(a.pointerId);break;case"gotpointercapture":case"lostpointercapture":Ao.delete(a.pointerId)}}function So(r,a,s,c,m,E){return r===null||r.nativeEvent!==E?(r={blockedOn:a,domEventName:s,eventSystemFlags:c,nativeEvent:E,targetContainers:[m]},a!==null&&(a=dt(a),a!==null&&vb(a)),r):(r.eventSystemFlags|=c,a=r.targetContainers,m!==null&&a.indexOf(m)===-1&&a.push(m),r)}function HR(r,a,s,c,m){switch(a){case"focusin":return sa=So(sa,r,a,s,c,m),!0;case"dragenter":return oa=So(oa,r,a,s,c,m),!0;case"mouseover":return la=So(la,r,a,s,c,m),!0;case"pointerover":var E=m.pointerId;return To.set(E,So(To.get(E)||null,r,a,s,c,m)),!0;case"gotpointercapture":return E=m.pointerId,Ao.set(E,So(Ao.get(E)||null,r,a,s,c,m)),!0}return!1}function xb(r){var a=Ge(r.target);if(a!==null){var s=o(a);if(s!==null){if(a=s.tag,a===13){if(a=l(s),a!==null){r.blockedOn=a,te(r.priority,function(){if(s.tag===13){var c=hr();c=vr(c);var m=Cu(s,c);m!==null&&mr(m,s,c),Am(s,c)}});return}}else if(a===3&&s.stateNode.current.memoizedState.isDehydrated){r.blockedOn=s.tag===3?s.stateNode.containerInfo:null;return}}}r.blockedOn=null}function Xc(r){if(r.blockedOn!==null)return!1;for(var a=r.targetContainers;0<a.length;){var s=Dm(r.nativeEvent);if(s===null){s=r.nativeEvent;var c=new s.constructor(s.type,s);xd=c,s.target.dispatchEvent(c),xd=null}else return a=dt(s),a!==null&&vb(a),r.blockedOn=s,!1;a.shift()}return!0}function Rb(r,a,s){Xc(r)&&s.delete(a)}function zR(){Cm=!1,sa!==null&&Xc(sa)&&(sa=null),oa!==null&&Xc(oa)&&(oa=null),la!==null&&Xc(la)&&(la=null),To.forEach(Rb),Ao.forEach(Rb)}function Kc(r,a){r.blockedOn===a&&(r.blockedOn=null,Cm||(Cm=!0,e.unstable_scheduleCallback(e.unstable_NormalPriority,zR)))}var Wc=null;function wb(r){Wc!==r&&(Wc=r,e.unstable_scheduleCallback(e.unstable_NormalPriority,function(){Wc===r&&(Wc=null);for(var a=0;a<r.length;a+=3){var s=r[a],c=r[a+1],m=r[a+2];if(typeof c!="function"){if(vm(c||s)===null)continue;break}var E=dt(s);E!==null&&(r.splice(a,3),a-=3,vh(E,{pending:!0,data:m,method:s.method,action:c},c,m))}}))}function Do(r){function a(H){return Kc(H,r)}sa!==null&&Kc(sa,r),oa!==null&&Kc(oa,r),la!==null&&Kc(la,r),To.forEach(a),Ao.forEach(a);for(var s=0;s<ca.length;s++){var c=ca[s];c.blockedOn===r&&(c.blockedOn=null)}for(;0<ca.length&&(s=ca[0],s.blockedOn===null);)xb(s),s.blockedOn===null&&ca.shift();if(s=(r.ownerDocument||r).$$reactFormReplay,s!=null)for(c=0;c<s.length;c+=3){var m=s[c],E=s[c+1],D=m[Ce]||null;if(typeof E=="function")D||wb(s);else if(D){var x=null;if(E&&E.hasAttribute("formAction")){if(m=E,D=E[Ce]||null)x=D.formAction;else if(vm(m)!==null)continue}else x=D.action;typeof x=="function"?s[c+1]=x:(s.splice(c,3),c-=3),wb(s)}}}function _m(r){this._internalRoot=r}Qc.prototype.render=_m.prototype.render=function(r){var a=this._internalRoot;if(a===null)throw Error(i(409));var s=a.current,c=hr();Sb(s,c,r,a,null,null)},Qc.prototype.unmount=_m.prototype.unmount=function(){var r=this._internalRoot;if(r!==null){this._internalRoot=null;var a=r.containerInfo;Sb(r.current,2,null,r,null,null),Nc(),a[we]=null}};function Qc(r){this._internalRoot=r}Qc.prototype.unstable_scheduleHydration=function(r){if(r){var a=j();r={blockedOn:null,target:r,priority:a};for(var s=0;s<ca.length&&a!==0&&a<ca[s].priority;s++);ca.splice(s,0,r),s===0&&xb(r)}};var Ob=t.version;if(Ob!=="19.1.0")throw Error(i(527,Ob,"19.1.0"));K.findDOMNode=function(r){var a=r._reactInternals;if(a===void 0)throw typeof r.render=="function"?Error(i(188)):(r=Object.keys(r).join(","),Error(i(268,r)));return r=d(a),r=r!==null?h(r):null,r=r===null?null:r.stateNode,r};var VR={bundleType:0,version:"19.1.0",rendererPackageName:"react-dom",currentDispatcherRef:B,reconcilerVersion:"19.1.0"};if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"){var $c=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!$c.isDisabled&&$c.supportsFiber)try{le=$c.inject(VR),Ee=$c}catch{}}return Co.createRoot=function(r,a){if(!u(r))throw Error(i(299));var s=!1,c="",m=GE,E=XE,D=KE,x=null;return a!=null&&(a.unstable_strictMode===!0&&(s=!0),a.identifierPrefix!==void 0&&(c=a.identifierPrefix),a.onUncaughtError!==void 0&&(m=a.onUncaughtError),a.onCaughtError!==void 0&&(E=a.onCaughtError),a.onRecoverableError!==void 0&&(D=a.onRecoverableError),a.unstable_transitionCallbacks!==void 0&&(x=a.unstable_transitionCallbacks)),a=Tb(r,1,!1,null,null,s,c,m,E,D,x,null),r[we]=a.current,om(r),new _m(a)},Co.hydrateRoot=function(r,a,s){if(!u(r))throw Error(i(299));var c=!1,m="",E=GE,D=XE,x=KE,H=null,ae=null;return s!=null&&(s.unstable_strictMode===!0&&(c=!0),s.identifierPrefix!==void 0&&(m=s.identifierPrefix),s.onUncaughtError!==void 0&&(E=s.onUncaughtError),s.onCaughtError!==void 0&&(D=s.onCaughtError),s.onRecoverableError!==void 0&&(x=s.onRecoverableError),s.unstable_transitionCallbacks!==void 0&&(H=s.unstable_transitionCallbacks),s.formState!==void 0&&(ae=s.formState)),a=Tb(r,1,!0,a,s??null,c,m,E,D,x,H,ae),a.context=Ab(null),s=a.current,c=hr(),c=vr(c),m=Xi(c),m.callback=null,Ki(s,m,c),s=c,a.current.lanes=s,sr(a,s),ci(a),r[we]=a.current,om(r),new Qc(a)},Co.version="19.1.0",Co}var Hb;function $R(){if(Hb)return wm.exports;Hb=1;function e(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}return e(),wm.exports=QR(),wm.exports}var ZR=$R();const Oj=Rl(ZR);var _o={},zb;function JR(){if(zb)return _o;zb=1,Object.defineProperty(_o,"__esModule",{value:!0}),_o.parse=l,_o.serialize=h;const e=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,t=/^[\u0021-\u003A\u003C-\u007E]*$/,n=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,i=/^[\u0020-\u003A\u003D-\u007E]*$/,u=Object.prototype.toString,o=(()=>{const b=function(){};return b.prototype=Object.create(null),b})();function l(b,T){const A=new o,_=b.length;if(_<2)return A;const O=T?.decode||p;let C=0;do{const N=b.indexOf("=",C);if(N===-1)break;const R=b.indexOf(";",C),Y=R===-1?_:R;if(N>Y){C=b.lastIndexOf(";",N-1)+1;continue}const M=f(b,C,N),v=d(b,N,M),J=b.slice(M,v);if(A[J]===void 0){let P=f(b,N+1,Y),q=d(b,Y,P);const z=O(b.slice(P,q));A[J]=z}C=Y+1}while(C<_);return A}function f(b,T,A){do{const _=b.charCodeAt(T);if(_!==32&&_!==9)return T}while(++T<A);return A}function d(b,T,A){for(;T>A;){const _=b.charCodeAt(--T);if(_!==32&&_!==9)return T+1}return A}function h(b,T,A){const _=A?.encode||encodeURIComponent;if(!e.test(b))throw new TypeError(`argument name is invalid: ${b}`);const O=_(T);if(!t.test(O))throw new TypeError(`argument val is invalid: ${T}`);let C=b+"="+O;if(!A)return C;if(A.maxAge!==void 0){if(!Number.isInteger(A.maxAge))throw new TypeError(`option maxAge is invalid: ${A.maxAge}`);C+="; Max-Age="+A.maxAge}if(A.domain){if(!n.test(A.domain))throw new TypeError(`option domain is invalid: ${A.domain}`);C+="; Domain="+A.domain}if(A.path){if(!i.test(A.path))throw new TypeError(`option path is invalid: ${A.path}`);C+="; Path="+A.path}if(A.expires){if(!g(A.expires)||!Number.isFinite(A.expires.valueOf()))throw new TypeError(`option expires is invalid: ${A.expires}`);C+="; Expires="+A.expires.toUTCString()}if(A.httpOnly&&(C+="; HttpOnly"),A.secure&&(C+="; Secure"),A.partitioned&&(C+="; Partitioned"),A.priority)switch(typeof A.priority=="string"?A.priority.toLowerCase():void 0){case"low":C+="; Priority=Low";break;case"medium":C+="; Priority=Medium";break;case"high":C+="; Priority=High";break;default:throw new TypeError(`option priority is invalid: ${A.priority}`)}if(A.sameSite)switch(typeof A.sameSite=="string"?A.sameSite.toLowerCase():A.sameSite){case!0:case"strict":C+="; SameSite=Strict";break;case"lax":C+="; SameSite=Lax";break;case"none":C+="; SameSite=None";break;default:throw new TypeError(`option sameSite is invalid: ${A.sameSite}`)}return C}function p(b){if(b.indexOf("%")===-1)return b;try{return decodeURIComponent(b)}catch{return b}}function g(b){return u.call(b)==="[object Date]"}return _o}JR();/** + * react-router v7.6.3 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */var U2=e=>{throw TypeError(e)},ew=(e,t,n)=>t.has(e)||U2("Cannot "+n),Lm=(e,t,n)=>(ew(e,t,"read from private field"),n?n.call(e):t.get(e)),tw=(e,t,n)=>t.has(e)?U2("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),Vb="popstate";function nw(e={}){function t(i,u){let{pathname:o,search:l,hash:f}=i.location;return ml("",{pathname:o,search:l,hash:f},u.state&&u.state.usr||null,u.state&&u.state.key||"default")}function n(i,u){return typeof u=="string"?u:Aa(u)}return iw(t,n,null,e)}function ot(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function on(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function rw(){return Math.random().toString(36).substring(2,10)}function jb(e,t){return{usr:e.state,key:e.key,idx:t}}function ml(e,t,n=null,i){return{pathname:typeof e=="string"?e:e.pathname,search:"",hash:"",...typeof t=="string"?_a(t):t,state:n,key:t&&t.key||i||rw()}}function Aa({pathname:e="/",search:t="",hash:n=""}){return t&&t!=="?"&&(e+=t.charAt(0)==="?"?t:"?"+t),n&&n!=="#"&&(e+=n.charAt(0)==="#"?n:"#"+n),e}function _a(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substring(n),e=e.substring(0,n));let i=e.indexOf("?");i>=0&&(t.search=e.substring(i),e=e.substring(0,i)),e&&(t.pathname=e)}return t}function iw(e,t,n,i={}){let{window:u=document.defaultView,v5Compat:o=!1}=i,l=u.history,f="POP",d=null,h=p();h==null&&(h=0,l.replaceState({...l.state,idx:h},""));function p(){return(l.state||{idx:null}).idx}function g(){f="POP";let O=p(),C=O==null?null:O-h;h=O,d&&d({action:f,location:_.location,delta:C})}function b(O,C){f="PUSH";let N=ml(_.location,O,C);h=p()+1;let R=jb(N,h),Y=_.createHref(N);try{l.pushState(R,"",Y)}catch(M){if(M instanceof DOMException&&M.name==="DataCloneError")throw M;u.location.assign(Y)}o&&d&&d({action:f,location:_.location,delta:1})}function T(O,C){f="REPLACE";let N=ml(_.location,O,C);h=p();let R=jb(N,h),Y=_.createHref(N);l.replaceState(R,"",Y),o&&d&&d({action:f,location:_.location,delta:0})}function A(O){return H2(O)}let _={get action(){return f},get location(){return e(u,l)},listen(O){if(d)throw new Error("A history only accepts one active listener");return u.addEventListener(Vb,g),d=O,()=>{u.removeEventListener(Vb,g),d=null}},createHref(O){return t(u,O)},createURL:A,encodeLocation(O){let C=A(O);return{pathname:C.pathname,search:C.search,hash:C.hash}},push:b,replace:T,go(O){return l.go(O)}};return _}function H2(e,t=!1){let n="http://localhost";typeof window<"u"&&(n=window.location.origin!=="null"?window.location.origin:window.location.href),ot(n,"No window.location.(origin|href) available to create URL");let i=typeof e=="string"?e:Aa(e);return i=i.replace(/ $/,"%20"),!t&&i.startsWith("//")&&(i=n+i),new URL(i,n)}var $o,qb=class{constructor(e){if(tw(this,$o,new Map),e)for(let[t,n]of e)this.set(t,n)}get(e){if(Lm(this,$o).has(e))return Lm(this,$o).get(e);if(e.defaultValue!==void 0)return e.defaultValue;throw new Error("No value found for context")}set(e,t){Lm(this,$o).set(e,t)}};$o=new WeakMap;var aw=new Set(["lazy","caseSensitive","path","id","index","children"]);function uw(e){return aw.has(e)}var sw=new Set(["lazy","caseSensitive","path","id","index","unstable_middleware","children"]);function ow(e){return sw.has(e)}function lw(e){return e.index===!0}function Mf(e,t,n=[],i={}){return e.map((u,o)=>{let l=[...n,String(o)],f=typeof u.id=="string"?u.id:l.join("-");if(ot(u.index!==!0||!u.children,"Cannot specify children on an index route"),ot(!i[f],`Found a route id collision on id "${f}". Route id's must be globally unique within Data Router usages`),lw(u)){let d={...u,...t(u),id:f};return i[f]=d,d}else{let d={...u,...t(u),id:f,children:void 0};return i[f]=d,u.children&&(d.children=Mf(u.children,t,l,i)),d}})}function ba(e,t,n="/"){return bf(e,t,n,!1)}function bf(e,t,n,i){let u=typeof t=="string"?_a(t):t,o=Hr(u.pathname||"/",n);if(o==null)return null;let l=z2(e);fw(l);let f=null;for(let d=0;f==null&&d<l.length;++d){let h=Sw(o);f=Tw(l[d],h,i)}return f}function cw(e,t){let{route:n,pathname:i,params:u}=e;return{id:n.id,pathname:i,params:u,data:t[n.id],handle:n.handle}}function z2(e,t=[],n=[],i=""){let u=(o,l,f)=>{let d={relativePath:f===void 0?o.path||"":f,caseSensitive:o.caseSensitive===!0,childrenIndex:l,route:o};d.relativePath.startsWith("/")&&(ot(d.relativePath.startsWith(i),`Absolute route path "${d.relativePath}" nested under path "${i}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),d.relativePath=d.relativePath.slice(i.length));let h=mi([i,d.relativePath]),p=n.concat(d);o.children&&o.children.length>0&&(ot(o.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${h}".`),z2(o.children,t,p,h)),!(o.path==null&&!o.index)&&t.push({path:h,score:yw(h,o.index),routesMeta:p})};return e.forEach((o,l)=>{if(o.path===""||!o.path?.includes("?"))u(o,l);else for(let f of V2(o.path))u(o,l,f)}),t}function V2(e){let t=e.split("/");if(t.length===0)return[];let[n,...i]=t,u=n.endsWith("?"),o=n.replace(/\?$/,"");if(i.length===0)return u?[o,""]:[o];let l=V2(i.join("/")),f=[];return f.push(...l.map(d=>d===""?o:[o,d].join("/"))),u&&f.push(...l),f.map(d=>e.startsWith("/")&&d===""?"/":d)}function fw(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:bw(t.routesMeta.map(i=>i.childrenIndex),n.routesMeta.map(i=>i.childrenIndex)))}var dw=/^:[\w-]+$/,hw=3,mw=2,pw=1,gw=10,Ew=-2,Yb=e=>e==="*";function yw(e,t){let n=e.split("/"),i=n.length;return n.some(Yb)&&(i+=Ew),t&&(i+=mw),n.filter(u=>!Yb(u)).reduce((u,o)=>u+(dw.test(o)?hw:o===""?pw:gw),i)}function bw(e,t){return e.length===t.length&&e.slice(0,-1).every((i,u)=>i===t[u])?e[e.length-1]-t[t.length-1]:0}function Tw(e,t,n=!1){let{routesMeta:i}=e,u={},o="/",l=[];for(let f=0;f<i.length;++f){let d=i[f],h=f===i.length-1,p=o==="/"?t:t.slice(o.length)||"/",g=If({path:d.relativePath,caseSensitive:d.caseSensitive,end:h},p),b=d.route;if(!g&&h&&n&&!i[i.length-1].route.index&&(g=If({path:d.relativePath,caseSensitive:d.caseSensitive,end:!1},p)),!g)return null;Object.assign(u,g.params),l.push({params:u,pathname:mi([o,g.pathname]),pathnameBase:Cw(mi([o,g.pathnameBase])),route:b}),g.pathnameBase!=="/"&&(o=mi([o,g.pathnameBase]))}return l}function If(e,t){typeof e=="string"&&(e={path:e,caseSensitive:!1,end:!0});let[n,i]=Aw(e.path,e.caseSensitive,e.end),u=t.match(n);if(!u)return null;let o=u[0],l=o.replace(/(.)\/+$/,"$1"),f=u.slice(1);return{params:i.reduce((h,{paramName:p,isOptional:g},b)=>{if(p==="*"){let A=f[b]||"";l=o.slice(0,o.length-A.length).replace(/(.)\/+$/,"$1")}const T=f[b];return g&&!T?h[p]=void 0:h[p]=(T||"").replace(/%2F/g,"/"),h},{}),pathname:o,pathnameBase:l,pattern:e}}function Aw(e,t=!1,n=!0){on(e==="*"||!e.endsWith("*")||e.endsWith("/*"),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,"/*")}".`);let i=[],u="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(l,f,d)=>(i.push({paramName:f,isOptional:d!=null}),d?"/?([^\\/]+)?":"/([^\\/]+)"));return e.endsWith("*")?(i.push({paramName:"*"}),u+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?u+="\\/*$":e!==""&&e!=="/"&&(u+="(?:(?=\\/|$))"),[new RegExp(u,t?void 0:"i"),i]}function Sw(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return on(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function Hr(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,i=e.charAt(n);return i&&i!=="/"?null:e.slice(n)||"/"}function Dw(e,t="/"){let{pathname:n,search:i="",hash:u=""}=typeof e=="string"?_a(e):e;return{pathname:n?n.startsWith("/")?n:vw(n,t):t,search:_w(i),hash:xw(u)}}function vw(e,t){let n=t.replace(/\/+$/,"").split("/");return e.split("/").forEach(u=>{u===".."?n.length>1&&n.pop():u!=="."&&n.push(u)}),n.length>1?n.join("/"):"/"}function Mm(e,t,n,i){return`Cannot include a '${e}' character in a manually specified \`to.${t}\` field [${JSON.stringify(i)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`}function j2(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function $f(e){let t=j2(e);return t.map((n,i)=>i===t.length-1?n.pathname:n.pathnameBase)}function Zf(e,t,n,i=!1){let u;typeof e=="string"?u=_a(e):(u={...e},ot(!u.pathname||!u.pathname.includes("?"),Mm("?","pathname","search",u)),ot(!u.pathname||!u.pathname.includes("#"),Mm("#","pathname","hash",u)),ot(!u.search||!u.search.includes("#"),Mm("#","search","hash",u)));let o=e===""||u.pathname==="",l=o?"/":u.pathname,f;if(l==null)f=n;else{let g=t.length-1;if(!i&&l.startsWith("..")){let b=l.split("/");for(;b[0]==="..";)b.shift(),g-=1;u.pathname=b.join("/")}f=g>=0?t[g]:"/"}let d=Dw(u,f),h=l&&l!=="/"&&l.endsWith("/"),p=(o||l===".")&&n.endsWith("/");return!d.pathname.endsWith("/")&&(h||p)&&(d.pathname+="/"),d}var mi=e=>e.join("/").replace(/\/\/+/g,"/"),Cw=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),_w=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,xw=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e,Pf=class{constructor(e,t,n,i=!1){this.status=e,this.statusText=t||"",this.internal=i,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function pl(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}var q2=["POST","PUT","PATCH","DELETE"],Rw=new Set(q2),ww=["GET",...q2],Ow=new Set(ww),Nw=new Set([301,302,303,307,308]),kw=new Set([307,308]),Im={state:"idle",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},Lw={state:"idle",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},xo={state:"unblocked",proceed:void 0,reset:void 0,location:void 0},M0=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Mw=e=>({hasErrorBoundary:!!e.hasErrorBoundary}),Y2="remix-router-transitions",G2=Symbol("ResetLoaderData");function Iw(e){const t=e.window?e.window:typeof window<"u"?window:void 0,n=typeof t<"u"&&typeof t.document<"u"&&typeof t.document.createElement<"u";ot(e.routes.length>0,"You must provide a non-empty routes array to createRouter");let i=e.hydrationRouteProperties||[],u=e.mapRouteProperties||Mw,o={},l=Mf(e.routes,u,void 0,o),f,d=e.basename||"/",h=e.dataStrategy||Hw,p={unstable_middleware:!1,...e.future},g=null,b=new Set,T=null,A=null,_=null,O=e.hydrationData!=null,C=ba(l,e.history.location,d),N=!1,R=null,Y;if(C==null&&!e.patchRoutesOnNavigation){let j=Ir(404,{pathname:e.history.location.pathname}),{matches:te,route:se}=rT(l);Y=!0,C=te,R={[se.id]:j}}else if(C&&!e.hydrationData&&Ai(C,l,e.history.location.pathname).active&&(C=null),C)if(C.some(j=>j.route.lazy))Y=!1;else if(!C.some(j=>j.route.loader))Y=!0;else{let j=e.hydrationData?e.hydrationData.loaderData:null,te=e.hydrationData?e.hydrationData.errors:null;if(te){let se=C.findIndex(pe=>te[pe.route.id]!==void 0);Y=C.slice(0,se+1).every(pe=>!Ip(pe.route,j,te))}else Y=C.every(se=>!Ip(se.route,j,te))}else{Y=!1,C=[];let j=Ai(null,l,e.history.location.pathname);j.active&&j.matches&&(N=!0,C=j.matches)}let M,v={historyAction:e.history.action,location:e.history.location,matches:C,initialized:Y,navigation:Im,restoreScrollPosition:e.hydrationData!=null?!1:null,preventScrollReset:!1,revalidation:"idle",loaderData:e.hydrationData&&e.hydrationData.loaderData||{},actionData:e.hydrationData&&e.hydrationData.actionData||null,errors:e.hydrationData&&e.hydrationData.errors||R,fetchers:new Map,blockers:new Map},J="POP",P=!1,q,z=!1,V=new Map,F=null,$=!1,Z=!1,L=new Set,B=new Map,K=0,Q=-1,_e=new Map,S=new Set,ne=new Map,ge=new Map,w=new Set,Te=new Map,Re,xe=null;function We(){if(g=e.history.listen(({action:j,location:te,delta:se})=>{if(Re){Re(),Re=void 0;return}on(Te.size===0||se!=null,"You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL.");let pe=On({currentLocation:v.location,nextLocation:te,historyAction:j});if(pe&&se!=null){let Ce=new Promise(we=>{Re=we});e.history.go(se*-1),nn(pe,{state:"blocked",location:te,proceed(){nn(pe,{state:"proceeding",proceed:void 0,reset:void 0,location:te}),Ce.then(()=>e.history.go(se))},reset(){let we=new Map(v.blockers);we.set(pe,xo),mt({blockers:we})}});return}return tn(j,te)}),n){$w(t,V);let j=()=>Zw(t,V);t.addEventListener("pagehide",j),F=()=>t.removeEventListener("pagehide",j)}return v.initialized||tn("POP",v.location,{initialHydration:!0}),M}function Qe(){g&&g(),F&&F(),b.clear(),q&&q.abort(),v.fetchers.forEach((j,te)=>ze(te)),v.blockers.forEach((j,te)=>Bt(te))}function Nt(j){return b.add(j),()=>b.delete(j)}function mt(j,te={}){v={...v,...j};let se=[],pe=[];v.fetchers.forEach((Ce,we)=>{Ce.state==="idle"&&(w.has(we)?se.push(we):pe.push(we))}),w.forEach(Ce=>{!v.fetchers.has(Ce)&&!B.has(Ce)&&se.push(Ce)}),[...b].forEach(Ce=>Ce(v,{deletedFetchers:se,viewTransitionOpts:te.viewTransitionOpts,flushSync:te.flushSync===!0})),se.forEach(Ce=>ze(Ce)),pe.forEach(Ce=>v.fetchers.delete(Ce))}function qt(j,te,{flushSync:se}={}){let pe=v.actionData!=null&&v.navigation.formMethod!=null&&br(v.navigation.formMethod)&&v.navigation.state==="loading"&&j.state?._isRedirect!==!0,Ce;te.actionData?Object.keys(te.actionData).length>0?Ce=te.actionData:Ce=null:pe?Ce=v.actionData:Ce=null;let we=te.loaderData?tT(v.loaderData,te.loaderData,te.matches||[],te.errors):v.loaderData,Fe=v.blockers;Fe.size>0&&(Fe=new Map(Fe),Fe.forEach((ke,je)=>Fe.set(je,xo)));let Ne=P===!0||v.navigation.formMethod!=null&&br(v.navigation.formMethod)&&j.state?._isRedirect!==!0;f&&(l=f,f=void 0),$||J==="POP"||(J==="PUSH"?e.history.push(j,j.state):J==="REPLACE"&&e.history.replace(j,j.state));let Be;if(J==="POP"){let ke=V.get(v.location.pathname);ke&&ke.has(j.pathname)?Be={currentLocation:v.location,nextLocation:j}:V.has(j.pathname)&&(Be={currentLocation:j,nextLocation:v.location})}else if(z){let ke=V.get(v.location.pathname);ke?ke.add(j.pathname):(ke=new Set([j.pathname]),V.set(v.location.pathname,ke)),Be={currentLocation:v.location,nextLocation:j}}mt({...te,actionData:Ce,loaderData:we,historyAction:J,location:j,initialized:!0,navigation:Im,revalidation:"idle",restoreScrollPosition:gu(j,te.matches||v.matches),preventScrollReset:Ne,blockers:Fe},{viewTransitionOpts:Be,flushSync:se===!0}),J="POP",P=!1,z=!1,$=!1,Z=!1,xe?.resolve(),xe=null}async function ln(j,te){if(typeof j=="number"){e.history.go(j);return}let se=Mp(v.location,v.matches,d,j,te?.fromRouteId,te?.relative),{path:pe,submission:Ce,error:we}=Gb(!1,se,te),Fe=v.location,Ne=ml(v.location,pe,te&&te.state);Ne={...Ne,...e.history.encodeLocation(Ne)};let Be=te&&te.replace!=null?te.replace:void 0,ke="PUSH";Be===!0?ke="REPLACE":Be===!1||Ce!=null&&br(Ce.formMethod)&&Ce.formAction===v.location.pathname+v.location.search&&(ke="REPLACE");let je=te&&"preventScrollReset"in te?te.preventScrollReset===!0:void 0,Ue=(te&&te.flushSync)===!0,Ge=On({currentLocation:Fe,nextLocation:Ne,historyAction:ke});if(Ge){nn(Ge,{state:"blocked",location:Ne,proceed(){nn(Ge,{state:"proceeding",proceed:void 0,reset:void 0,location:Ne}),ln(j,te)},reset(){let dt=new Map(v.blockers);dt.set(Ge,xo),mt({blockers:dt})}});return}await tn(ke,Ne,{submission:Ce,pendingError:we,preventScrollReset:je,replace:te&&te.replace,enableViewTransition:te&&te.viewTransition,flushSync:Ue})}function Ar(){xe||(xe=Jw()),Gn(),mt({revalidation:"loading"});let j=xe.promise;return v.navigation.state==="submitting"?j:v.navigation.state==="idle"?(tn(v.historyAction,v.location,{startUninterruptedRevalidation:!0}),j):(tn(J||v.historyAction,v.navigation.location,{overrideNavigation:v.navigation,enableViewTransition:z===!0}),j)}async function tn(j,te,se){q&&q.abort(),q=null,J=j,$=(se&&se.startUninterruptedRevalidation)===!0,sr(v.location,v.matches),P=(se&&se.preventScrollReset)===!0,z=(se&&se.enableViewTransition)===!0;let pe=f||l,Ce=se&&se.overrideNavigation,we=se?.initialHydration&&v.matches&&v.matches.length>0&&!N?v.matches:ba(pe,te,d),Fe=(se&&se.flushSync)===!0;if(we&&v.initialized&&!Z&&Gw(v.location,te)&&!(se&&se.submission&&br(se.submission.formMethod))){qt(te,{matches:we},{flushSync:Fe});return}let Ne=Ai(we,pe,te.pathname);if(Ne.active&&Ne.matches&&(we=Ne.matches),!we){let{error:Lt,notFoundMatches:pt,route:Se}=qr(te.pathname);qt(te,{matches:pt,loaderData:{},errors:{[Se.id]:Lt}},{flushSync:Fe});return}q=new AbortController;let Be=Ju(e.history,te,q.signal,se&&se.submission),ke=new qb(e.unstable_getContext?await e.unstable_getContext():void 0),je;if(se&&se.pendingError)je=[eu(we).route.id,{type:"error",error:se.pendingError}];else if(se&&se.submission&&br(se.submission.formMethod)){let Lt=await ni(Be,te,se.submission,we,ke,Ne.active,se&&se.initialHydration===!0,{replace:se.replace,flushSync:Fe});if(Lt.shortCircuited)return;if(Lt.pendingActionResult){let[pt,Se]=Lt.pendingActionResult;if(yr(Se)&&pl(Se.error)&&Se.error.status===404){q=null,qt(te,{matches:Lt.matches,loaderData:{},errors:{[pt]:Se.error}});return}}we=Lt.matches||we,je=Lt.pendingActionResult,Ce=Pm(te,se.submission),Fe=!1,Ne.active=!1,Be=Ju(e.history,Be.url,Be.signal)}let{shortCircuited:Ue,matches:Ge,loaderData:dt,errors:Dt}=await ri(Be,te,we,ke,Ne.active,Ce,se&&se.submission,se&&se.fetcherSubmission,se&&se.replace,se&&se.initialHydration===!0,Fe,je);Ue||(q=null,qt(te,{matches:Ge||we,...nT(je),loaderData:dt,errors:Dt}))}async function ni(j,te,se,pe,Ce,we,Fe,Ne={}){Gn();let Be=Ww(te,se);if(mt({navigation:Be},{flushSync:Ne.flushSync===!0}),we){let Ue=await kt(pe,te.pathname,j.signal);if(Ue.type==="aborted")return{shortCircuited:!0};if(Ue.type==="error"){let Ge=eu(Ue.partialMatches).route.id;return{matches:Ue.partialMatches,pendingActionResult:[Ge,{type:"error",error:Ue.error}]}}else if(Ue.matches)pe=Ue.matches;else{let{notFoundMatches:Ge,error:dt,route:Dt}=qr(te.pathname);return{matches:Ge,pendingActionResult:[Dt.id,{type:"error",error:dt}]}}}let ke,je=Zo(pe,te);if(!je.route.action&&!je.route.lazy)ke={type:"error",error:Ir(405,{method:j.method,pathname:te.pathname,routeId:je.route.id})};else{let Ue=ss(u,o,j,pe,je,Fe?[]:i,Ce),Ge=await Yn(j,Ue,Ce,null);if(ke=Ge[je.route.id],!ke){for(let dt of pe)if(Ge[dt.route.id]){ke=Ge[dt.route.id];break}}if(j.signal.aborted)return{shortCircuited:!0}}if(tu(ke)){let Ue;return Ne&&Ne.replace!=null?Ue=Ne.replace:Ue=Zb(ke.response.headers.get("Location"),new URL(j.url),d)===v.location.pathname+v.location.search,await ur(j,ke,!0,{submission:se,replace:Ue}),{shortCircuited:!0}}if(yr(ke)){let Ue=eu(pe,je.route.id);return(Ne&&Ne.replace)!==!0&&(J="PUSH"),{matches:pe,pendingActionResult:[Ue.route.id,ke,je.route.id]}}return{matches:pe,pendingActionResult:[je.route.id,ke]}}async function ri(j,te,se,pe,Ce,we,Fe,Ne,Be,ke,je,Ue){let Ge=we||Pm(te,Fe),dt=Fe||Ne||aT(Ge),Dt=!$&&!ke;if(Ce){if(Dt){let yt=Yt(Ue);mt({navigation:Ge,...yt!==void 0?{actionData:yt}:{}},{flushSync:je})}let $e=await kt(se,te.pathname,j.signal);if($e.type==="aborted")return{shortCircuited:!0};if($e.type==="error"){let yt=eu($e.partialMatches).route.id;return{matches:$e.partialMatches,loaderData:{},errors:{[yt]:$e.error}}}else if($e.matches)se=$e.matches;else{let{error:yt,notFoundMatches:Xn,route:Kn}=qr(te.pathname);return{matches:Xn,loaderData:{},errors:{[Kn.id]:yt}}}}let Lt=f||l,{dsMatches:pt,revalidatingFetchers:Se}=Xb(j,pe,u,o,e.history,v,se,dt,te,ke?[]:i,ke===!0,Z,L,w,ne,S,Lt,d,e.patchRoutesOnNavigation!=null,Ue);if(Q=++K,!e.dataStrategy&&!pt.some($e=>$e.shouldLoad)&&Se.length===0){let $e=Wt();return qt(te,{matches:se,loaderData:{},errors:Ue&&yr(Ue[1])?{[Ue[0]]:Ue[1].error}:null,...nT(Ue),...$e?{fetchers:new Map(v.fetchers)}:{}},{flushSync:je}),{shortCircuited:!0}}if(Dt){let $e={};if(!Ce){$e.navigation=Ge;let yt=Yt(Ue);yt!==void 0&&($e.actionData=yt)}Se.length>0&&($e.fetchers=ii(Se)),mt($e,{flushSync:je})}Se.forEach($e=>{Ft($e.key),$e.controller&&B.set($e.key,$e.controller)});let G=()=>Se.forEach($e=>Ft($e.key));q&&q.signal.addEventListener("abort",G);let{loaderResults:ye,fetcherResults:Oe}=await Dr(pt,Se,j,pe);if(j.signal.aborted)return{shortCircuited:!0};q&&q.signal.removeEventListener("abort",G),Se.forEach($e=>B.delete($e.key));let rt=Zc(ye);if(rt)return await ur(j,rt.result,!0,{replace:Be}),{shortCircuited:!0};if(rt=Zc(Oe),rt)return S.add(rt.key),await ur(j,rt.result,!0,{replace:Be}),{shortCircuited:!0};let{loaderData:Ut,errors:vt}=eT(v,se,ye,Ue,Se,Oe);ke&&v.errors&&(vt={...v.errors,...vt});let cn=Wt(),$t=Gt(Q),Bn=cn||$t||Se.length>0;return{matches:se,loaderData:Ut,errors:vt,...Bn?{fetchers:new Map(v.fetchers)}:{}}}function Yt(j){if(j&&!yr(j[1]))return{[j[0]]:j[1].data};if(v.actionData)return Object.keys(v.actionData).length===0?null:v.actionData}function ii(j){return j.forEach(te=>{let se=v.fetchers.get(te.key),pe=Ro(void 0,se?se.data:void 0);v.fetchers.set(te.key,pe)}),new Map(v.fetchers)}async function Sr(j,te,se,pe){Ft(j);let Ce=(pe&&pe.flushSync)===!0,we=f||l,Fe=Mp(v.location,v.matches,d,se,te,pe?.relative),Ne=ba(we,Fe,d),Be=Ai(Ne,we,Fe);if(Be.active&&Be.matches&&(Ne=Be.matches),!Ne){Ee(j,te,Ir(404,{pathname:Fe}),{flushSync:Ce});return}let{path:ke,submission:je,error:Ue}=Gb(!0,Fe,pe);if(Ue){Ee(j,te,Ue,{flushSync:Ce});return}let Ge=Zo(Ne,ke),dt=new qb(e.unstable_getContext?await e.unstable_getContext():void 0),Dt=(pe&&pe.preventScrollReset)===!0;if(je&&br(je.formMethod)){await ai(j,te,ke,Ge,Ne,dt,Be.active,Ce,Dt,je);return}ne.set(j,{routeId:te,path:ke}),await jr(j,te,ke,Ge,Ne,dt,Be.active,Ce,Dt,je)}async function ai(j,te,se,pe,Ce,we,Fe,Ne,Be,ke){Gn(),ne.delete(j);function je(Ht){if(!Ht.route.action&&!Ht.route.lazy){let ji=Ir(405,{method:ke.formMethod,pathname:se,routeId:te});return Ee(j,te,ji,{flushSync:Ne}),!0}return!1}if(!Fe&&je(pe))return;let Ue=v.fetchers.get(j);le(j,Qw(ke,Ue),{flushSync:Ne});let Ge=new AbortController,dt=Ju(e.history,se,Ge.signal,ke);if(Fe){let Ht=await kt(Ce,se,dt.signal,j);if(Ht.type==="aborted")return;if(Ht.type==="error"){Ee(j,te,Ht.error,{flushSync:Ne});return}else if(Ht.matches){if(Ce=Ht.matches,pe=Zo(Ce,se),je(pe))return}else{Ee(j,te,Ir(404,{pathname:se}),{flushSync:Ne});return}}B.set(j,Ge);let Dt=K,Lt=ss(u,o,dt,Ce,pe,i,we),Se=(await Yn(dt,Lt,we,j))[pe.route.id];if(dt.signal.aborted){B.get(j)===Ge&&B.delete(j);return}if(w.has(j)){if(tu(Se)||yr(Se)){le(j,ma(void 0));return}}else{if(tu(Se))if(B.delete(j),Q>Dt){le(j,ma(void 0));return}else return S.add(j),le(j,Ro(ke)),ur(dt,Se,!1,{fetcherSubmission:ke,preventScrollReset:Be});if(yr(Se)){Ee(j,te,Se.error);return}}let G=v.navigation.location||v.location,ye=Ju(e.history,G,Ge.signal),Oe=f||l,rt=v.navigation.state!=="idle"?ba(Oe,v.navigation.location,d):v.matches;ot(rt,"Didn't find any matches after fetcher action");let Ut=++K;_e.set(j,Ut);let vt=Ro(ke,Se.data);v.fetchers.set(j,vt);let{dsMatches:cn,revalidatingFetchers:$t}=Xb(ye,we,u,o,e.history,v,rt,ke,G,i,!1,Z,L,w,ne,S,Oe,d,e.patchRoutesOnNavigation!=null,[pe.route.id,Se]);$t.filter(Ht=>Ht.key!==j).forEach(Ht=>{let ji=Ht.key,Os=v.fetchers.get(ji),Wn=Ro(void 0,Os?Os.data:void 0);v.fetchers.set(ji,Wn),Ft(ji),Ht.controller&&B.set(ji,Ht.controller)}),mt({fetchers:new Map(v.fetchers)});let Bn=()=>$t.forEach(Ht=>Ft(Ht.key));Ge.signal.addEventListener("abort",Bn);let{loaderResults:$e,fetcherResults:yt}=await Dr(cn,$t,ye,we);if(Ge.signal.aborted)return;if(Ge.signal.removeEventListener("abort",Bn),_e.delete(j),B.delete(j),$t.forEach(Ht=>B.delete(Ht.key)),v.fetchers.has(j)){let Ht=ma(Se.data);v.fetchers.set(j,Ht)}let Xn=Zc($e);if(Xn)return ur(ye,Xn.result,!1,{preventScrollReset:Be});if(Xn=Zc(yt),Xn)return S.add(Xn.key),ur(ye,Xn.result,!1,{preventScrollReset:Be});let{loaderData:Kn,errors:Na}=eT(v,rt,$e,void 0,$t,yt);Gt(Ut),v.navigation.state==="loading"&&Ut>Q?(ot(J,"Expected pending action"),q&&q.abort(),qt(v.navigation.location,{matches:rt,loaderData:Kn,errors:Na,fetchers:new Map(v.fetchers)})):(mt({errors:Na,loaderData:tT(v.loaderData,Kn,rt,Na),fetchers:new Map(v.fetchers)}),Z=!1)}async function jr(j,te,se,pe,Ce,we,Fe,Ne,Be,ke){let je=v.fetchers.get(j);le(j,Ro(ke,je?je.data:void 0),{flushSync:Ne});let Ue=new AbortController,Ge=Ju(e.history,se,Ue.signal);if(Fe){let Se=await kt(Ce,se,Ge.signal,j);if(Se.type==="aborted")return;if(Se.type==="error"){Ee(j,te,Se.error,{flushSync:Ne});return}else if(Se.matches)Ce=Se.matches,pe=Zo(Ce,se);else{Ee(j,te,Ir(404,{pathname:se}),{flushSync:Ne});return}}B.set(j,Ue);let dt=K,Dt=ss(u,o,Ge,Ce,pe,i,we),pt=(await Yn(Ge,Dt,we,j))[pe.route.id];if(B.get(j)===Ue&&B.delete(j),!Ge.signal.aborted){if(w.has(j)){le(j,ma(void 0));return}if(tu(pt))if(Q>dt){le(j,ma(void 0));return}else{S.add(j),await ur(Ge,pt,!1,{preventScrollReset:Be});return}if(yr(pt)){Ee(j,te,pt.error);return}le(j,ma(pt.data))}}async function ur(j,te,se,{submission:pe,fetcherSubmission:Ce,preventScrollReset:we,replace:Fe}={}){te.response.headers.has("X-Remix-Revalidate")&&(Z=!0);let Ne=te.response.headers.get("Location");ot(Ne,"Expected a Location header on the redirect Response"),Ne=Zb(Ne,new URL(j.url),d);let Be=ml(v.location,Ne,{_isRedirect:!0});if(n){let Dt=!1;if(te.response.headers.has("X-Remix-Reload-Document"))Dt=!0;else if(M0.test(Ne)){const Lt=H2(Ne,!0);Dt=Lt.origin!==t.location.origin||Hr(Lt.pathname,d)==null}if(Dt){Fe?t.location.replace(Ne):t.location.assign(Ne);return}}q=null;let ke=Fe===!0||te.response.headers.has("X-Remix-Replace")?"REPLACE":"PUSH",{formMethod:je,formAction:Ue,formEncType:Ge}=v.navigation;!pe&&!Ce&&je&&Ue&&Ge&&(pe=aT(v.navigation));let dt=pe||Ce;if(kw.has(te.response.status)&&dt&&br(dt.formMethod))await tn(ke,Be,{submission:{...dt,formAction:Ne},preventScrollReset:we||P,enableViewTransition:se?z:void 0});else{let Dt=Pm(Be,pe);await tn(ke,Be,{overrideNavigation:Dt,fetcherSubmission:Ce,preventScrollReset:we||P,enableViewTransition:se?z:void 0})}}async function Yn(j,te,se,pe){let Ce,we={};try{Ce=await zw(h,j,te,pe,se,!1)}catch(Fe){return te.filter(Ne=>Ne.shouldLoad).forEach(Ne=>{we[Ne.route.id]={type:"error",error:Fe}}),we}if(j.signal.aborted)return we;for(let[Fe,Ne]of Object.entries(Ce))if(Xw(Ne)){let Be=Ne.result;we[Fe]={type:"redirect",response:qw(Be,j,Fe,te,d)}}else we[Fe]=await jw(Ne);return we}async function Dr(j,te,se,pe){let Ce=Yn(se,j,pe,null),we=Promise.all(te.map(async Be=>{if(Be.matches&&Be.match&&Be.request&&Be.controller){let je=(await Yn(Be.request,Be.matches,pe,Be.key))[Be.match.route.id];return{[Be.key]:je}}else return Promise.resolve({[Be.key]:{type:"error",error:Ir(404,{pathname:Be.path})}})})),Fe=await Ce,Ne=(await we).reduce((Be,ke)=>Object.assign(Be,ke),{});return{loaderResults:Fe,fetcherResults:Ne}}function Gn(){Z=!0,ne.forEach((j,te)=>{B.has(te)&&L.add(te),Ft(te)})}function le(j,te,se={}){v.fetchers.set(j,te),mt({fetchers:new Map(v.fetchers)},{flushSync:(se&&se.flushSync)===!0})}function Ee(j,te,se,pe={}){let Ce=eu(v.matches,te);ze(j),mt({errors:{[Ce.route.id]:se},fetchers:new Map(v.fetchers)},{flushSync:(pe&&pe.flushSync)===!0})}function Pe(j){return ge.set(j,(ge.get(j)||0)+1),w.has(j)&&w.delete(j),v.fetchers.get(j)||Lw}function ze(j){let te=v.fetchers.get(j);B.has(j)&&!(te&&te.state==="loading"&&_e.has(j))&&Ft(j),ne.delete(j),_e.delete(j),S.delete(j),w.delete(j),L.delete(j),v.fetchers.delete(j)}function ht(j){let te=(ge.get(j)||0)-1;te<=0?(ge.delete(j),w.add(j)):ge.set(j,te),mt({fetchers:new Map(v.fetchers)})}function Ft(j){let te=B.get(j);te&&(te.abort(),B.delete(j))}function Cn(j){for(let te of j){let se=Pe(te),pe=ma(se.data);v.fetchers.set(te,pe)}}function Wt(){let j=[],te=!1;for(let se of S){let pe=v.fetchers.get(se);ot(pe,`Expected fetcher: ${se}`),pe.state==="loading"&&(S.delete(se),j.push(se),te=!0)}return Cn(j),te}function Gt(j){let te=[];for(let[se,pe]of _e)if(pe<j){let Ce=v.fetchers.get(se);ot(Ce,`Expected fetcher: ${se}`),Ce.state==="loading"&&(Ft(se),_e.delete(se),te.push(se))}return Cn(te),te.length>0}function Qt(j,te){let se=v.blockers.get(j)||xo;return Te.get(j)!==te&&Te.set(j,te),se}function Bt(j){v.blockers.delete(j),Te.delete(j)}function nn(j,te){let se=v.blockers.get(j)||xo;ot(se.state==="unblocked"&&te.state==="blocked"||se.state==="blocked"&&te.state==="blocked"||se.state==="blocked"&&te.state==="proceeding"||se.state==="blocked"&&te.state==="unblocked"||se.state==="proceeding"&&te.state==="unblocked",`Invalid blocker state transition: ${se.state} -> ${te.state}`);let pe=new Map(v.blockers);pe.set(j,te),mt({blockers:pe})}function On({currentLocation:j,nextLocation:te,historyAction:se}){if(Te.size===0)return;Te.size>1&&on(!1,"A router only supports one blocker at a time");let pe=Array.from(Te.entries()),[Ce,we]=pe[pe.length-1],Fe=v.blockers.get(Ce);if(!(Fe&&Fe.state==="proceeding")&&we({currentLocation:j,nextLocation:te,historyAction:se}))return Ce}function qr(j){let te=Ir(404,{pathname:j}),se=f||l,{matches:pe,route:Ce}=rT(se);return{notFoundMatches:pe,route:Ce,error:te}}function Ti(j,te,se){if(T=j,_=te,A=se||null,!O&&v.navigation===Im){O=!0;let pe=gu(v.location,v.matches);pe!=null&&mt({restoreScrollPosition:pe})}return()=>{T=null,_=null,A=null}}function Vi(j,te){return A&&A(j,te.map(pe=>cw(pe,v.loaderData)))||j.key}function sr(j,te){if(T&&_){let se=Vi(j,te);T[se]=_()}}function gu(j,te){if(T){let se=Vi(j,te),pe=T[se];if(typeof pe=="number")return pe}return null}function Ai(j,te,se){if(e.patchRoutesOnNavigation)if(j){if(Object.keys(j[0].params).length>0)return{active:!0,matches:bf(te,se,d,!0)}}else return{active:!0,matches:bf(te,se,d,!0)||[]};return{active:!1,matches:null}}async function kt(j,te,se,pe){if(!e.patchRoutesOnNavigation)return{type:"success",matches:j};let Ce=j;for(;;){let we=f==null,Fe=f||l,Ne=o;try{await e.patchRoutesOnNavigation({signal:se,path:te,matches:Ce,fetcherKey:pe,patch:(je,Ue)=>{se.aborted||Kb(je,Ue,Fe,Ne,u)}})}catch(je){return{type:"error",error:je,partialMatches:Ce}}finally{we&&!se.aborted&&(l=[...l])}if(se.aborted)return{type:"aborted"};let Be=ba(Fe,te,d);if(Be)return{type:"success",matches:Be};let ke=bf(Fe,te,d,!0);if(!ke||Ce.length===ke.length&&Ce.every((je,Ue)=>je.route.id===ke[Ue].route.id))return{type:"success",matches:null};Ce=ke}}function vr(j){o={},f=Mf(j,u,void 0,o)}function Oa(j,te){let se=f==null;Kb(j,te,f||l,o,u),se&&(l=[...l],mt({}))}return M={get basename(){return d},get future(){return p},get state(){return v},get routes(){return l},get window(){return t},initialize:We,subscribe:Nt,enableScrollRestoration:Ti,navigate:ln,fetch:Sr,revalidate:Ar,createHref:j=>e.history.createHref(j),encodeLocation:j=>e.history.encodeLocation(j),getFetcher:Pe,deleteFetcher:ht,dispose:Qe,getBlocker:Qt,deleteBlocker:Bt,patchRoutes:Oa,_internalFetchControllers:B,_internalSetRoutes:vr},M}function Pw(e){return e!=null&&("formData"in e&&e.formData!=null||"body"in e&&e.body!==void 0)}function Mp(e,t,n,i,u,o){let l,f;if(u){l=[];for(let h of t)if(l.push(h),h.route.id===u){f=h;break}}else l=t,f=t[t.length-1];let d=Zf(i||".",$f(l),Hr(e.pathname,n)||e.pathname,o==="path");if(i==null&&(d.search=e.search,d.hash=e.hash),(i==null||i===""||i===".")&&f){let h=I0(d.search);if(f.route.index&&!h)d.search=d.search?d.search.replace(/^\?/,"?index&"):"?index";else if(!f.route.index&&h){let p=new URLSearchParams(d.search),g=p.getAll("index");p.delete("index"),g.filter(T=>T).forEach(T=>p.append("index",T));let b=p.toString();d.search=b?`?${b}`:""}}return n!=="/"&&(d.pathname=d.pathname==="/"?n:mi([n,d.pathname])),Aa(d)}function Gb(e,t,n){if(!n||!Pw(n))return{path:t};if(n.formMethod&&!Kw(n.formMethod))return{path:t,error:Ir(405,{method:n.formMethod})};let i=()=>({path:t,error:Ir(400,{type:"invalid-body"})}),o=(n.formMethod||"get").toUpperCase(),l=Z2(t);if(n.body!==void 0){if(n.formEncType==="text/plain"){if(!br(o))return i();let g=typeof n.body=="string"?n.body:n.body instanceof FormData||n.body instanceof URLSearchParams?Array.from(n.body.entries()).reduce((b,[T,A])=>`${b}${T}=${A} +`,""):String(n.body);return{path:t,submission:{formMethod:o,formAction:l,formEncType:n.formEncType,formData:void 0,json:void 0,text:g}}}else if(n.formEncType==="application/json"){if(!br(o))return i();try{let g=typeof n.body=="string"?JSON.parse(n.body):n.body;return{path:t,submission:{formMethod:o,formAction:l,formEncType:n.formEncType,formData:void 0,json:g,text:void 0}}}catch{return i()}}}ot(typeof FormData=="function","FormData is not available in this environment");let f,d;if(n.formData)f=Fp(n.formData),d=n.formData;else if(n.body instanceof FormData)f=Fp(n.body),d=n.body;else if(n.body instanceof URLSearchParams)f=n.body,d=Jb(f);else if(n.body==null)f=new URLSearchParams,d=new FormData;else try{f=new URLSearchParams(n.body),d=Jb(f)}catch{return i()}let h={formMethod:o,formAction:l,formEncType:n&&n.formEncType||"application/x-www-form-urlencoded",formData:d,json:void 0,text:void 0};if(br(h.formMethod))return{path:t,submission:h};let p=_a(t);return e&&p.search&&I0(p.search)&&f.append("index",""),p.search=`?${f}`,{path:Aa(p),submission:h}}function Xb(e,t,n,i,u,o,l,f,d,h,p,g,b,T,A,_,O,C,N,R){let Y=R?yr(R[1])?R[1].error:R[1].data:void 0,M=u.createURL(o.location),v=u.createURL(d),J;if(p&&o.errors){let $=Object.keys(o.errors)[0];J=l.findIndex(Z=>Z.route.id===$)}else if(R&&yr(R[1])){let $=R[0];J=l.findIndex(Z=>Z.route.id===$)-1}let P=R?R[1].statusCode:void 0,q=P&&P>=400,z={currentUrl:M,currentParams:o.matches[0]?.params||{},nextUrl:v,nextParams:l[0].params,...f,actionResult:Y,actionStatus:P},V=l.map(($,Z)=>{let{route:L}=$,B=null;if(J!=null&&Z>J?B=!1:L.lazy?B=!0:L.loader==null?B=!1:p?B=Ip(L,o.loaderData,o.errors):Fw(o.loaderData,o.matches[Z],$)&&(B=!0),B!==null)return Pp(n,i,e,$,h,t,B);let K=q?!1:g||M.pathname+M.search===v.pathname+v.search||M.search!==v.search||Bw(o.matches[Z],$),Q={...z,defaultShouldRevalidate:K},_e=Ff($,Q);return Pp(n,i,e,$,h,t,_e,Q)}),F=[];return A.forEach(($,Z)=>{if(p||!l.some(ge=>ge.route.id===$.routeId)||T.has(Z))return;let L=o.fetchers.get(Z),B=L&&L.state!=="idle"&&L.data===void 0,K=ba(O,$.path,C);if(!K){if(N&&B)return;F.push({key:Z,routeId:$.routeId,path:$.path,matches:null,match:null,request:null,controller:null});return}if(_.has(Z))return;let Q=Zo(K,$.path),_e=new AbortController,S=Ju(u,$.path,_e.signal),ne=null;if(b.has(Z))b.delete(Z),ne=ss(n,i,S,K,Q,h,t);else if(B)g&&(ne=ss(n,i,S,K,Q,h,t));else{let ge={...z,defaultShouldRevalidate:q?!1:g};Ff(Q,ge)&&(ne=ss(n,i,S,K,Q,h,t,ge))}ne&&F.push({key:Z,routeId:$.routeId,path:$.path,matches:ne,match:Q,request:S,controller:_e})}),{dsMatches:V,revalidatingFetchers:F}}function Ip(e,t,n){if(e.lazy)return!0;if(!e.loader)return!1;let i=t!=null&&e.id in t,u=n!=null&&n[e.id]!==void 0;return!i&&u?!1:typeof e.loader=="function"&&e.loader.hydrate===!0?!0:!i&&!u}function Fw(e,t,n){let i=!t||n.route.id!==t.route.id,u=!e.hasOwnProperty(n.route.id);return i||u}function Bw(e,t){let n=e.route.path;return e.pathname!==t.pathname||n!=null&&n.endsWith("*")&&e.params["*"]!==t.params["*"]}function Ff(e,t){if(e.route.shouldRevalidate){let n=e.route.shouldRevalidate(t);if(typeof n=="boolean")return n}return t.defaultShouldRevalidate}function Kb(e,t,n,i,u){let o;if(e){let d=i[e];ot(d,`No route found to patch children into: routeId = ${e}`),d.children||(d.children=[]),o=d.children}else o=n;let l=t.filter(d=>!o.some(h=>X2(d,h))),f=Mf(l,u,[e||"_","patch",String(o?.length||"0")],i);o.push(...f)}function X2(e,t){return"id"in e&&"id"in t&&e.id===t.id?!0:e.index===t.index&&e.path===t.path&&e.caseSensitive===t.caseSensitive?(!e.children||e.children.length===0)&&(!t.children||t.children.length===0)?!0:e.children.every((n,i)=>t.children?.some(u=>X2(n,u))):!1}var Wb=new WeakMap,K2=({key:e,route:t,manifest:n,mapRouteProperties:i})=>{let u=n[t.id];if(ot(u,"No route found in manifest"),!u.lazy||typeof u.lazy!="object")return;let o=u.lazy[e];if(!o)return;let l=Wb.get(u);l||(l={},Wb.set(u,l));let f=l[e];if(f)return f;let d=(async()=>{let h=uw(e),g=u[e]!==void 0&&e!=="hasErrorBoundary";if(h)on(!h,"Route property "+e+" is not a supported lazy route property. This property will be ignored."),l[e]=Promise.resolve();else if(g)on(!1,`Route "${u.id}" has a static property "${e}" defined. The lazy property will be ignored.`);else{let b=await o();b!=null&&(Object.assign(u,{[e]:b}),Object.assign(u,i(u)))}typeof u.lazy=="object"&&(u.lazy[e]=void 0,Object.values(u.lazy).every(b=>b===void 0)&&(u.lazy=void 0))})();return l[e]=d,d},Qb=new WeakMap;function Uw(e,t,n,i,u){let o=n[e.id];if(ot(o,"No route found in manifest"),!e.lazy)return{lazyRoutePromise:void 0,lazyHandlerPromise:void 0};if(typeof e.lazy=="function"){let p=Qb.get(o);if(p)return{lazyRoutePromise:p,lazyHandlerPromise:p};let g=(async()=>{ot(typeof e.lazy=="function","No lazy route function found");let b=await e.lazy(),T={};for(let A in b){let _=b[A];if(_===void 0)continue;let O=ow(A),N=o[A]!==void 0&&A!=="hasErrorBoundary";O?on(!O,"Route property "+A+" is not a supported property to be returned from a lazy route function. This property will be ignored."):N?on(!N,`Route "${o.id}" has a static property "${A}" defined but its lazy function is also returning a value for this property. The lazy route property "${A}" will be ignored.`):T[A]=_}Object.assign(o,T),Object.assign(o,{...i(o),lazy:void 0})})();return Qb.set(o,g),g.catch(()=>{}),{lazyRoutePromise:g,lazyHandlerPromise:g}}let l=Object.keys(e.lazy),f=[],d;for(let p of l){if(u&&u.includes(p))continue;let g=K2({key:p,route:e,manifest:n,mapRouteProperties:i});g&&(f.push(g),p===t&&(d=g))}let h=f.length>0?Promise.all(f).then(()=>{}):void 0;return h?.catch(()=>{}),d?.catch(()=>{}),{lazyRoutePromise:h,lazyHandlerPromise:d}}async function $b(e){let t=e.matches.filter(u=>u.shouldLoad),n={};return(await Promise.all(t.map(u=>u.resolve()))).forEach((u,o)=>{n[t[o].route.id]=u}),n}async function Hw(e){return e.matches.some(t=>t.route.unstable_middleware)?W2(e,!1,()=>$b(e),(t,n)=>({[n]:{type:"error",result:t}})):$b(e)}async function W2(e,t,n,i){let{matches:u,request:o,params:l,context:f}=e,d={handlerResult:void 0};try{let h=u.flatMap(g=>g.route.unstable_middleware?g.route.unstable_middleware.map(b=>[g.route.id,b]):[]),p=await Q2({request:o,params:l,context:f},h,t,d,n);return t?p:d.handlerResult}catch(h){if(!d.middlewareError)throw h;let p=await i(d.middlewareError.error,d.middlewareError.routeId);return d.handlerResult?Object.assign(d.handlerResult,p):p}}async function Q2(e,t,n,i,u,o=0){let{request:l}=e;if(l.signal.aborted)throw l.signal.reason?l.signal.reason:new Error(`Request aborted without an \`AbortSignal.reason\`: ${l.method} ${l.url}`);let f=t[o];if(!f)return i.handlerResult=await u(),i.handlerResult;let[d,h]=f,p=!1,g,b=async()=>{if(p)throw new Error("You may only call `next()` once per middleware");p=!0,await Q2(e,t,n,i,u,o+1)};try{let T=await h({request:e.request,params:e.params,context:e.context},b);return p?T===void 0?g:T:b()}catch(T){throw i.middlewareError?i.middlewareError.error!==T&&(i.middlewareError={routeId:d,error:T}):i.middlewareError={routeId:d,error:T},T}}function $2(e,t,n,i,u){let o=K2({key:"unstable_middleware",route:i.route,manifest:t,mapRouteProperties:e}),l=Uw(i.route,br(n.method)?"action":"loader",t,e,u);return{middleware:o,route:l.lazyRoutePromise,handler:l.lazyHandlerPromise}}function Pp(e,t,n,i,u,o,l,f=null){let d=!1,h=$2(e,t,n,i,u);return{...i,_lazyPromises:h,shouldLoad:l,unstable_shouldRevalidateArgs:f,unstable_shouldCallHandler(p){return d=!0,f?typeof p=="boolean"?Ff(i,{...f,defaultShouldRevalidate:p}):Ff(i,f):l},resolve(p){return d||l||p&&n.method==="GET"&&(i.route.lazy||i.route.loader)?Vw({request:n,match:i,lazyHandlerPromise:h?.handler,lazyRoutePromise:h?.route,handlerOverride:p,scopedContext:o}):Promise.resolve({type:"data",result:void 0})}}}function ss(e,t,n,i,u,o,l,f=null){return i.map(d=>d.route.id!==u.route.id?{...d,shouldLoad:!1,unstable_shouldRevalidateArgs:f,unstable_shouldCallHandler:()=>!1,_lazyPromises:$2(e,t,n,d,o),resolve:()=>Promise.resolve({type:"data",result:void 0})}:Pp(e,t,n,d,o,l,!0,f))}async function zw(e,t,n,i,u,o){n.some(h=>h._lazyPromises?.middleware)&&await Promise.all(n.map(h=>h._lazyPromises?.middleware));let l={request:t,params:n[0].params,context:u,matches:n},d=await e({...l,fetcherKey:i,unstable_runClientMiddleware:h=>{let p=l;return W2(p,!1,()=>h({...p,fetcherKey:i,unstable_runClientMiddleware:()=>{throw new Error("Cannot call `unstable_runClientMiddleware()` from within an `unstable_runClientMiddleware` handler")}}),(g,b)=>({[b]:{type:"error",result:g}}))}});try{await Promise.all(n.flatMap(h=>[h._lazyPromises?.handler,h._lazyPromises?.route]))}catch{}return d}async function Vw({request:e,match:t,lazyHandlerPromise:n,lazyRoutePromise:i,handlerOverride:u,scopedContext:o}){let l,f,d=br(e.method),h=d?"action":"loader",p=g=>{let b,T=new Promise((O,C)=>b=C);f=()=>b(),e.signal.addEventListener("abort",f);let A=O=>typeof g!="function"?Promise.reject(new Error(`You cannot call the handler for a route which defines a boolean "${h}" [routeId: ${t.route.id}]`)):g({request:e,params:t.params,context:o},...O!==void 0?[O]:[]),_=(async()=>{try{return{type:"data",result:await(u?u(C=>A(C)):A())}}catch(O){return{type:"error",result:O}}})();return Promise.race([_,T])};try{let g=d?t.route.action:t.route.loader;if(n||i)if(g){let b,[T]=await Promise.all([p(g).catch(A=>{b=A}),n,i]);if(b!==void 0)throw b;l=T}else{await n;let b=d?t.route.action:t.route.loader;if(b)[l]=await Promise.all([p(b),i]);else if(h==="action"){let T=new URL(e.url),A=T.pathname+T.search;throw Ir(405,{method:e.method,pathname:A,routeId:t.route.id})}else return{type:"data",result:void 0}}else if(g)l=await p(g);else{let b=new URL(e.url),T=b.pathname+b.search;throw Ir(404,{pathname:T})}}catch(g){return{type:"error",result:g}}finally{f&&e.signal.removeEventListener("abort",f)}return l}async function jw(e){let{result:t,type:n}=e;if(J2(t)){let i;try{let u=t.headers.get("Content-Type");u&&/\bapplication\/json\b/.test(u)?t.body==null?i=null:i=await t.json():i=await t.text()}catch(u){return{type:"error",error:u}}return n==="error"?{type:"error",error:new Pf(t.status,t.statusText,i),statusCode:t.status,headers:t.headers}:{type:"data",data:i,statusCode:t.status,headers:t.headers}}return n==="error"?iT(t)?t.data instanceof Error?{type:"error",error:t.data,statusCode:t.init?.status,headers:t.init?.headers?new Headers(t.init.headers):void 0}:{type:"error",error:new Pf(t.init?.status||500,void 0,t.data),statusCode:pl(t)?t.status:void 0,headers:t.init?.headers?new Headers(t.init.headers):void 0}:{type:"error",error:t,statusCode:pl(t)?t.status:void 0}:iT(t)?{type:"data",data:t.data,statusCode:t.init?.status,headers:t.init?.headers?new Headers(t.init.headers):void 0}:{type:"data",data:t}}function qw(e,t,n,i,u){let o=e.headers.get("Location");if(ot(o,"Redirects returned/thrown from loaders/actions must have a Location header"),!M0.test(o)){let l=i.slice(0,i.findIndex(f=>f.route.id===n)+1);o=Mp(new URL(t.url),l,u,o),e.headers.set("Location",o)}return e}function Zb(e,t,n){if(M0.test(e)){let i=e,u=i.startsWith("//")?new URL(t.protocol+i):new URL(i),o=Hr(u.pathname,n)!=null;if(u.origin===t.origin&&o)return u.pathname+u.search+u.hash}return e}function Ju(e,t,n,i){let u=e.createURL(Z2(t)).toString(),o={signal:n};if(i&&br(i.formMethod)){let{formMethod:l,formEncType:f}=i;o.method=l.toUpperCase(),f==="application/json"?(o.headers=new Headers({"Content-Type":f}),o.body=JSON.stringify(i.json)):f==="text/plain"?o.body=i.text:f==="application/x-www-form-urlencoded"&&i.formData?o.body=Fp(i.formData):o.body=i.formData}return new Request(u,o)}function Fp(e){let t=new URLSearchParams;for(let[n,i]of e.entries())t.append(n,typeof i=="string"?i:i.name);return t}function Jb(e){let t=new FormData;for(let[n,i]of e.entries())t.append(n,i);return t}function Yw(e,t,n,i=!1,u=!1){let o={},l=null,f,d=!1,h={},p=n&&yr(n[1])?n[1].error:void 0;return e.forEach(g=>{if(!(g.route.id in t))return;let b=g.route.id,T=t[b];if(ot(!tu(T),"Cannot handle redirect results in processLoaderData"),yr(T)){let A=T.error;if(p!==void 0&&(A=p,p=void 0),l=l||{},u)l[b]=A;else{let _=eu(e,b);l[_.route.id]==null&&(l[_.route.id]=A)}i||(o[b]=G2),d||(d=!0,f=pl(T.error)?T.error.status:500),T.headers&&(h[b]=T.headers)}else o[b]=T.data,T.statusCode&&T.statusCode!==200&&!d&&(f=T.statusCode),T.headers&&(h[b]=T.headers)}),p!==void 0&&n&&(l={[n[0]]:p},n[2]&&(o[n[2]]=void 0)),{loaderData:o,errors:l,statusCode:f||200,loaderHeaders:h}}function eT(e,t,n,i,u,o){let{loaderData:l,errors:f}=Yw(t,n,i);return u.filter(d=>!d.matches||d.matches.some(h=>h.shouldLoad)).forEach(d=>{let{key:h,match:p,controller:g}=d,b=o[h];if(ot(b,"Did not find corresponding fetcher result"),!(g&&g.signal.aborted))if(yr(b)){let T=eu(e.matches,p?.route.id);f&&f[T.route.id]||(f={...f,[T.route.id]:b.error}),e.fetchers.delete(h)}else if(tu(b))ot(!1,"Unhandled fetcher revalidation redirect");else{let T=ma(b.data);e.fetchers.set(h,T)}}),{loaderData:l,errors:f}}function tT(e,t,n,i){let u=Object.entries(t).filter(([,o])=>o!==G2).reduce((o,[l,f])=>(o[l]=f,o),{});for(let o of n){let l=o.route.id;if(!t.hasOwnProperty(l)&&e.hasOwnProperty(l)&&o.route.loader&&(u[l]=e[l]),i&&i.hasOwnProperty(l))break}return u}function nT(e){return e?yr(e[1])?{actionData:{}}:{actionData:{[e[0]]:e[1].data}}:{}}function eu(e,t){return(t?e.slice(0,e.findIndex(i=>i.route.id===t)+1):[...e]).reverse().find(i=>i.route.hasErrorBoundary===!0)||e[0]}function rT(e){let t=e.length===1?e[0]:e.find(n=>n.index||!n.path||n.path==="/")||{id:"__shim-error-route__"};return{matches:[{params:{},pathname:"",pathnameBase:"",route:t}],route:t}}function Ir(e,{pathname:t,routeId:n,method:i,type:u,message:o}={}){let l="Unknown Server Error",f="Unknown @remix-run/router error";return e===400?(l="Bad Request",i&&t&&n?f=`You made a ${i} request to "${t}" but did not provide a \`loader\` for route "${n}", so there is no way to handle the request.`:u==="invalid-body"&&(f="Unable to encode submission body")):e===403?(l="Forbidden",f=`Route "${n}" does not match URL "${t}"`):e===404?(l="Not Found",f=`No route matches URL "${t}"`):e===405&&(l="Method Not Allowed",i&&t&&n?f=`You made a ${i.toUpperCase()} request to "${t}" but did not provide an \`action\` for route "${n}", so there is no way to handle the request.`:i&&(f=`Invalid request method "${i.toUpperCase()}"`)),new Pf(e||500,l,new Error(f),!0)}function Zc(e){let t=Object.entries(e);for(let n=t.length-1;n>=0;n--){let[i,u]=t[n];if(tu(u))return{key:i,result:u}}}function Z2(e){let t=typeof e=="string"?_a(e):e;return Aa({...t,hash:""})}function Gw(e,t){return e.pathname!==t.pathname||e.search!==t.search?!1:e.hash===""?t.hash!=="":e.hash===t.hash?!0:t.hash!==""}function Xw(e){return J2(e.result)&&Nw.has(e.result.status)}function yr(e){return e.type==="error"}function tu(e){return(e&&e.type)==="redirect"}function iT(e){return typeof e=="object"&&e!=null&&"type"in e&&"data"in e&&"init"in e&&e.type==="DataWithResponseInit"}function J2(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.headers=="object"&&typeof e.body<"u"}function Kw(e){return Ow.has(e.toUpperCase())}function br(e){return Rw.has(e.toUpperCase())}function I0(e){return new URLSearchParams(e).getAll("index").some(t=>t==="")}function Zo(e,t){let n=typeof t=="string"?_a(t).search:t.search;if(e[e.length-1].route.index&&I0(n||""))return e[e.length-1];let i=j2(e);return i[i.length-1]}function aT(e){let{formMethod:t,formAction:n,formEncType:i,text:u,formData:o,json:l}=e;if(!(!t||!n||!i)){if(u!=null)return{formMethod:t,formAction:n,formEncType:i,formData:void 0,json:void 0,text:u};if(o!=null)return{formMethod:t,formAction:n,formEncType:i,formData:o,json:void 0,text:void 0};if(l!==void 0)return{formMethod:t,formAction:n,formEncType:i,formData:void 0,json:l,text:void 0}}}function Pm(e,t){return t?{state:"loading",location:e,formMethod:t.formMethod,formAction:t.formAction,formEncType:t.formEncType,formData:t.formData,json:t.json,text:t.text}:{state:"loading",location:e,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0}}function Ww(e,t){return{state:"submitting",location:e,formMethod:t.formMethod,formAction:t.formAction,formEncType:t.formEncType,formData:t.formData,json:t.json,text:t.text}}function Ro(e,t){return e?{state:"loading",formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text,data:t}:{state:"loading",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:t}}function Qw(e,t){return{state:"submitting",formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text,data:t?t.data:void 0}}function ma(e){return{state:"idle",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:e}}function $w(e,t){try{let n=e.sessionStorage.getItem(Y2);if(n){let i=JSON.parse(n);for(let[u,o]of Object.entries(i||{}))o&&Array.isArray(o)&&t.set(u,new Set(o||[]))}}catch{}}function Zw(e,t){if(t.size>0){let n={};for(let[i,u]of t)n[i]=[...u];try{e.sessionStorage.setItem(Y2,JSON.stringify(n))}catch(i){on(!1,`Failed to save applied view transitions in sessionStorage (${i}).`)}}}function Jw(){let e,t,n=new Promise((i,u)=>{e=async o=>{i(o);try{await n}catch{}},t=async o=>{u(o);try{await n}catch{}}});return{promise:n,resolve:e,reject:t}}var du=W.createContext(null);du.displayName="DataRouter";var wl=W.createContext(null);wl.displayName="DataRouterState";var P0=W.createContext({isTransitioning:!1});P0.displayName="ViewTransition";var eD=W.createContext(new Map);eD.displayName="Fetchers";var eO=W.createContext(null);eO.displayName="Await";var Zr=W.createContext(null);Zr.displayName="Navigation";var Jf=W.createContext(null);Jf.displayName="Location";var Jr=W.createContext({outlet:null,matches:[],isDataRoute:!1});Jr.displayName="Route";var F0=W.createContext(null);F0.displayName="RouteError";function tO(e,{relative:t}={}){ot(ms(),"useHref() may be used only in the context of a <Router> component.");let{basename:n,navigator:i}=W.useContext(Zr),{hash:u,pathname:o,search:l}=Ol(e,{relative:t}),f=o;return n!=="/"&&(f=o==="/"?n:mi([n,o])),i.createHref({pathname:f,search:l,hash:u})}function ms(){return W.useContext(Jf)!=null}function xa(){return ot(ms(),"useLocation() may be used only in the context of a <Router> component."),W.useContext(Jf).location}var tD="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function nD(e){W.useContext(Zr).static||W.useLayoutEffect(e)}function rD(){let{isDataRoute:e}=W.useContext(Jr);return e?mO():nO()}function nO(){ot(ms(),"useNavigate() may be used only in the context of a <Router> component.");let e=W.useContext(du),{basename:t,navigator:n}=W.useContext(Zr),{matches:i}=W.useContext(Jr),{pathname:u}=xa(),o=JSON.stringify($f(i)),l=W.useRef(!1);return nD(()=>{l.current=!0}),W.useCallback((d,h={})=>{if(on(l.current,tD),!l.current)return;if(typeof d=="number"){n.go(d);return}let p=Zf(d,JSON.parse(o),u,h.relative==="path");e==null&&t!=="/"&&(p.pathname=p.pathname==="/"?t:mi([t,p.pathname])),(h.replace?n.replace:n.push)(p,h.state,h)},[t,n,o,u,e])}W.createContext(null);function Nj(){let{matches:e}=W.useContext(Jr),t=e[e.length-1];return t?t.params:{}}function Ol(e,{relative:t}={}){let{matches:n}=W.useContext(Jr),{pathname:i}=xa(),u=JSON.stringify($f(n));return W.useMemo(()=>Zf(e,JSON.parse(u),i,t==="path"),[e,u,i,t])}function rO(e,t,n,i){ot(ms(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:u}=W.useContext(Zr),{matches:o}=W.useContext(Jr),l=o[o.length-1],f=l?l.params:{},d=l?l.pathname:"/",h=l?l.pathnameBase:"/",p=l&&l.route;{let C=p&&p.path||"";iD(d,!p||C.endsWith("*")||C.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${d}" (under <Route path="${C}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. + +Please change the parent <Route path="${C}"> to <Route path="${C==="/"?"*":`${C}/*`}">.`)}let g=xa(),b;b=g;let T=b.pathname||"/",A=T;if(h!=="/"){let C=h.replace(/^\//,"").split("/");A="/"+T.replace(/^\//,"").split("/").slice(C.length).join("/")}let _=ba(e,{pathname:A});return on(p||_!=null,`No routes matched location "${b.pathname}${b.search}${b.hash}" `),on(_==null||_[_.length-1].route.element!==void 0||_[_.length-1].route.Component!==void 0||_[_.length-1].route.lazy!==void 0,`Matched leaf route at location "${b.pathname}${b.search}${b.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`),oO(_&&_.map(C=>Object.assign({},C,{params:Object.assign({},f,C.params),pathname:mi([h,u.encodeLocation?u.encodeLocation(C.pathname).pathname:C.pathname]),pathnameBase:C.pathnameBase==="/"?h:mi([h,u.encodeLocation?u.encodeLocation(C.pathnameBase).pathname:C.pathnameBase])})),o,n,i)}function iO(){let e=hO(),t=pl(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,i="rgba(200,200,200, 0.5)",u={padding:"0.5rem",backgroundColor:i},o={padding:"2px 4px",backgroundColor:i},l=null;return console.error("Error handled by React Router default ErrorBoundary:",e),l=W.createElement(W.Fragment,null,W.createElement("p",null,"💿 Hey developer 👋"),W.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",W.createElement("code",{style:o},"ErrorBoundary")," or"," ",W.createElement("code",{style:o},"errorElement")," prop on your route.")),W.createElement(W.Fragment,null,W.createElement("h2",null,"Unexpected Application Error!"),W.createElement("h3",{style:{fontStyle:"italic"}},t),n?W.createElement("pre",{style:u},n):null,l)}var aO=W.createElement(iO,null),uO=class extends W.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!=="idle"&&e.revalidation==="idle"?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error!==void 0?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){console.error("React Router caught the following error during render",e,t)}render(){return this.state.error!==void 0?W.createElement(Jr.Provider,{value:this.props.routeContext},W.createElement(F0.Provider,{value:this.state.error,children:this.props.component})):this.props.children}};function sO({routeContext:e,match:t,children:n}){let i=W.useContext(du);return i&&i.static&&i.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(i.staticContext._deepestRenderedBoundaryId=t.route.id),W.createElement(Jr.Provider,{value:e},n)}function oO(e,t=[],n=null,i=null){if(e==null){if(!n)return null;if(n.errors)e=n.matches;else if(t.length===0&&!n.initialized&&n.matches.length>0)e=n.matches;else return null}let u=e,o=n?.errors;if(o!=null){let d=u.findIndex(h=>h.route.id&&o?.[h.route.id]!==void 0);ot(d>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),u=u.slice(0,Math.min(u.length,d+1))}let l=!1,f=-1;if(n)for(let d=0;d<u.length;d++){let h=u[d];if((h.route.HydrateFallback||h.route.hydrateFallbackElement)&&(f=d),h.route.id){let{loaderData:p,errors:g}=n,b=h.route.loader&&!p.hasOwnProperty(h.route.id)&&(!g||g[h.route.id]===void 0);if(h.route.lazy||b){l=!0,f>=0?u=u.slice(0,f+1):u=[u[0]];break}}}return u.reduceRight((d,h,p)=>{let g,b=!1,T=null,A=null;n&&(g=o&&h.route.id?o[h.route.id]:void 0,T=h.route.errorElement||aO,l&&(f<0&&p===0?(iD("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),b=!0,A=null):f===p&&(b=!0,A=h.route.hydrateFallbackElement||null)));let _=t.concat(u.slice(0,p+1)),O=()=>{let C;return g?C=T:b?C=A:h.route.Component?C=W.createElement(h.route.Component,null):h.route.element?C=h.route.element:C=d,W.createElement(sO,{match:h,routeContext:{outlet:d,matches:_,isDataRoute:n!=null},children:C})};return n&&(h.route.ErrorBoundary||h.route.errorElement||p===0)?W.createElement(uO,{location:n.location,revalidation:n.revalidation,component:T,error:g,children:O(),routeContext:{outlet:null,matches:_,isDataRoute:!0}}):O()},null)}function B0(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function lO(e){let t=W.useContext(du);return ot(t,B0(e)),t}function cO(e){let t=W.useContext(wl);return ot(t,B0(e)),t}function fO(e){let t=W.useContext(Jr);return ot(t,B0(e)),t}function U0(e){let t=fO(e),n=t.matches[t.matches.length-1];return ot(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function dO(){return U0("useRouteId")}function hO(){let e=W.useContext(F0),t=cO("useRouteError"),n=U0("useRouteError");return e!==void 0?e:t.errors?.[n]}function mO(){let{router:e}=lO("useNavigate"),t=U0("useNavigate"),n=W.useRef(!1);return nD(()=>{n.current=!0}),W.useCallback(async(u,o={})=>{on(n.current,tD),n.current&&(typeof u=="number"?e.navigate(u):await e.navigate(u,{fromRouteId:t,...o}))},[e,t])}var uT={};function iD(e,t,n){!t&&!uT[e]&&(uT[e]=!0,on(!1,n))}var sT={};function oT(e,t){!e&&!sT[t]&&(sT[t]=!0,console.warn(t))}function pO(e){let t={hasErrorBoundary:e.hasErrorBoundary||e.ErrorBoundary!=null||e.errorElement!=null};return e.Component&&(e.element&&on(!1,"You should not include both `Component` and `element` on your route - `Component` will be used."),Object.assign(t,{element:W.createElement(e.Component),Component:void 0})),e.HydrateFallback&&(e.hydrateFallbackElement&&on(!1,"You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - `HydrateFallback` will be used."),Object.assign(t,{hydrateFallbackElement:W.createElement(e.HydrateFallback),HydrateFallback:void 0})),e.ErrorBoundary&&(e.errorElement&&on(!1,"You should not include both `ErrorBoundary` and `errorElement` on your route - `ErrorBoundary` will be used."),Object.assign(t,{errorElement:W.createElement(e.ErrorBoundary),ErrorBoundary:void 0})),t}var gO=["HydrateFallback","hydrateFallbackElement"],EO=class{constructor(){this.status="pending",this.promise=new Promise((e,t)=>{this.resolve=n=>{this.status==="pending"&&(this.status="resolved",e(n))},this.reject=n=>{this.status==="pending"&&(this.status="rejected",t(n))}})}};function yO({router:e,flushSync:t}){let[n,i]=W.useState(e.state),[u,o]=W.useState(),[l,f]=W.useState({isTransitioning:!1}),[d,h]=W.useState(),[p,g]=W.useState(),[b,T]=W.useState(),A=W.useRef(new Map),_=W.useCallback((R,{deletedFetchers:Y,flushSync:M,viewTransitionOpts:v})=>{R.fetchers.forEach((P,q)=>{P.data!==void 0&&A.current.set(q,P.data)}),Y.forEach(P=>A.current.delete(P)),oT(M===!1||t!=null,'You provided the `flushSync` option to a router update, but you are not using the `<RouterProvider>` from `react-router/dom` so `ReactDOM.flushSync()` is unavailable. Please update your app to `import { RouterProvider } from "react-router/dom"` and ensure you have `react-dom` installed as a dependency to use the `flushSync` option.');let J=e.window!=null&&e.window.document!=null&&typeof e.window.document.startViewTransition=="function";if(oT(v==null||J,"You provided the `viewTransition` option to a router update, but you do not appear to be running in a DOM environment as `window.startViewTransition` is not available."),!v||!J){t&&M?t(()=>i(R)):W.startTransition(()=>i(R));return}if(t&&M){t(()=>{p&&(d&&d.resolve(),p.skipTransition()),f({isTransitioning:!0,flushSync:!0,currentLocation:v.currentLocation,nextLocation:v.nextLocation})});let P=e.window.document.startViewTransition(()=>{t(()=>i(R))});P.finished.finally(()=>{t(()=>{h(void 0),g(void 0),o(void 0),f({isTransitioning:!1})})}),t(()=>g(P));return}p?(d&&d.resolve(),p.skipTransition(),T({state:R,currentLocation:v.currentLocation,nextLocation:v.nextLocation})):(o(R),f({isTransitioning:!0,flushSync:!1,currentLocation:v.currentLocation,nextLocation:v.nextLocation}))},[e.window,t,p,d]);W.useLayoutEffect(()=>e.subscribe(_),[e,_]),W.useEffect(()=>{l.isTransitioning&&!l.flushSync&&h(new EO)},[l]),W.useEffect(()=>{if(d&&u&&e.window){let R=u,Y=d.promise,M=e.window.document.startViewTransition(async()=>{W.startTransition(()=>i(R)),await Y});M.finished.finally(()=>{h(void 0),g(void 0),o(void 0),f({isTransitioning:!1})}),g(M)}},[u,d,e.window]),W.useEffect(()=>{d&&u&&n.location.key===u.location.key&&d.resolve()},[d,p,n.location,u]),W.useEffect(()=>{!l.isTransitioning&&b&&(o(b.state),f({isTransitioning:!0,flushSync:!1,currentLocation:b.currentLocation,nextLocation:b.nextLocation}),T(void 0))},[l.isTransitioning,b]);let O=W.useMemo(()=>({createHref:e.createHref,encodeLocation:e.encodeLocation,go:R=>e.navigate(R),push:(R,Y,M)=>e.navigate(R,{state:Y,preventScrollReset:M?.preventScrollReset}),replace:(R,Y,M)=>e.navigate(R,{replace:!0,state:Y,preventScrollReset:M?.preventScrollReset})}),[e]),C=e.basename||"/",N=W.useMemo(()=>({router:e,navigator:O,static:!1,basename:C}),[e,O,C]);return W.createElement(W.Fragment,null,W.createElement(du.Provider,{value:N},W.createElement(wl.Provider,{value:n},W.createElement(eD.Provider,{value:A.current},W.createElement(P0.Provider,{value:l},W.createElement(AO,{basename:C,location:n.location,navigationType:n.historyAction,navigator:O},W.createElement(bO,{routes:e.routes,future:e.future,state:n})))))),null)}var bO=W.memo(TO);function TO({routes:e,future:t,state:n}){return rO(e,void 0,n,t)}function kj({to:e,replace:t,state:n,relative:i}){ot(ms(),"<Navigate> may be used only in the context of a <Router> component.");let{static:u}=W.useContext(Zr);on(!u,"<Navigate> must not be used on the initial render in a <StaticRouter>. This is a no-op, but you should modify your code so the <Navigate> is only ever rendered in response to some user interaction or state change.");let{matches:o}=W.useContext(Jr),{pathname:l}=xa(),f=rD(),d=Zf(e,$f(o),l,i==="path"),h=JSON.stringify(d);return W.useEffect(()=>{f(JSON.parse(h),{replace:t,state:n,relative:i})},[f,h,i,t,n]),null}function AO({basename:e="/",children:t=null,location:n,navigationType:i="POP",navigator:u,static:o=!1}){ot(!ms(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let l=e.replace(/^\/*/,"/"),f=W.useMemo(()=>({basename:l,navigator:u,static:o,future:{}}),[l,u,o]);typeof n=="string"&&(n=_a(n));let{pathname:d="/",search:h="",hash:p="",state:g=null,key:b="default"}=n,T=W.useMemo(()=>{let A=Hr(d,l);return A==null?null:{location:{pathname:A,search:h,hash:p,state:g,key:b},navigationType:i}},[l,d,h,p,g,b,i]);return on(T!=null,`<Router basename="${l}"> is not able to match the URL "${d}${h}${p}" because it does not start with the basename, so the <Router> won't render anything.`),T==null?null:W.createElement(Zr.Provider,{value:f},W.createElement(Jf.Provider,{children:t,value:T}))}var Tf="get",Af="application/x-www-form-urlencoded";function ed(e){return e!=null&&typeof e.tagName=="string"}function SO(e){return ed(e)&&e.tagName.toLowerCase()==="button"}function DO(e){return ed(e)&&e.tagName.toLowerCase()==="form"}function vO(e){return ed(e)&&e.tagName.toLowerCase()==="input"}function CO(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function _O(e,t){return e.button===0&&(!t||t==="_self")&&!CO(e)}var Jc=null;function xO(){if(Jc===null)try{new FormData(document.createElement("form"),0),Jc=!1}catch{Jc=!0}return Jc}var RO=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Fm(e){return e!=null&&!RO.has(e)?(on(!1,`"${e}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${Af}"`),null):e}function wO(e,t){let n,i,u,o,l;if(DO(e)){let f=e.getAttribute("action");i=f?Hr(f,t):null,n=e.getAttribute("method")||Tf,u=Fm(e.getAttribute("enctype"))||Af,o=new FormData(e)}else if(SO(e)||vO(e)&&(e.type==="submit"||e.type==="image")){let f=e.form;if(f==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let d=e.getAttribute("formaction")||f.getAttribute("action");if(i=d?Hr(d,t):null,n=e.getAttribute("formmethod")||f.getAttribute("method")||Tf,u=Fm(e.getAttribute("formenctype"))||Fm(f.getAttribute("enctype"))||Af,o=new FormData(f,e),!xO()){let{name:h,type:p,value:g}=e;if(p==="image"){let b=h?`${h}.`:"";o.append(`${b}x`,"0"),o.append(`${b}y`,"0")}else h&&o.append(h,g)}}else{if(ed(e))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');n=Tf,i=null,u=Af,l=e}return o&&u==="text/plain"&&(l=o,o=void 0),{action:i,method:n.toLowerCase(),encType:u,formData:o,body:l}}function H0(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}async function OO(e,t){if(e.id in t)return t[e.id];try{let n=await import(e.module);return t[e.id]=n,n}catch(n){return console.error(`Error loading route module \`${e.module}\`, reloading page...`),console.error(n),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function NO(e){return e==null?!1:e.href==null?e.rel==="preload"&&typeof e.imageSrcSet=="string"&&typeof e.imageSizes=="string":typeof e.rel=="string"&&typeof e.href=="string"}async function kO(e,t,n){let i=await Promise.all(e.map(async u=>{let o=t.routes[u.route.id];if(o){let l=await OO(o,n);return l.links?l.links():[]}return[]}));return PO(i.flat(1).filter(NO).filter(u=>u.rel==="stylesheet"||u.rel==="preload").map(u=>u.rel==="stylesheet"?{...u,rel:"prefetch",as:"style"}:{...u,rel:"prefetch"}))}function lT(e,t,n,i,u,o){let l=(d,h)=>n[h]?d.route.id!==n[h].route.id:!0,f=(d,h)=>n[h].pathname!==d.pathname||n[h].route.path?.endsWith("*")&&n[h].params["*"]!==d.params["*"];return o==="assets"?t.filter((d,h)=>l(d,h)||f(d,h)):o==="data"?t.filter((d,h)=>{let p=i.routes[d.route.id];if(!p||!p.hasLoader)return!1;if(l(d,h)||f(d,h))return!0;if(d.route.shouldRevalidate){let g=d.route.shouldRevalidate({currentUrl:new URL(u.pathname+u.search+u.hash,window.origin),currentParams:n[0]?.params||{},nextUrl:new URL(e,window.origin),nextParams:d.params,defaultShouldRevalidate:!0});if(typeof g=="boolean")return g}return!0}):[]}function LO(e,t,{includeHydrateFallback:n}={}){return MO(e.map(i=>{let u=t.routes[i.route.id];if(!u)return[];let o=[u.module];return u.clientActionModule&&(o=o.concat(u.clientActionModule)),u.clientLoaderModule&&(o=o.concat(u.clientLoaderModule)),n&&u.hydrateFallbackModule&&(o=o.concat(u.hydrateFallbackModule)),u.imports&&(o=o.concat(u.imports)),o}).flat(1))}function MO(e){return[...new Set(e)]}function IO(e){let t={},n=Object.keys(e).sort();for(let i of n)t[i]=e[i];return t}function PO(e,t){let n=new Set;return new Set(t),e.reduce((i,u)=>{let o=JSON.stringify(IO(u));return n.has(o)||(n.add(o),i.push({key:o,link:u})),i},[])}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var FO=new Set([100,101,204,205]);function BO(e,t){let n=typeof e=="string"?new URL(e,typeof window>"u"?"server://singlefetch/":window.location.origin):e;return n.pathname==="/"?n.pathname="_root.data":t&&Hr(n.pathname,t)==="/"?n.pathname=`${t.replace(/\/$/,"")}/_root.data`:n.pathname=`${n.pathname.replace(/\/$/,"")}.data`,n}function aD(){let e=W.useContext(du);return H0(e,"You must render this element inside a <DataRouterContext.Provider> element"),e}function UO(){let e=W.useContext(wl);return H0(e,"You must render this element inside a <DataRouterStateContext.Provider> element"),e}var z0=W.createContext(void 0);z0.displayName="FrameworkContext";function uD(){let e=W.useContext(z0);return H0(e,"You must render this element inside a <HydratedRouter> element"),e}function HO(e,t){let n=W.useContext(z0),[i,u]=W.useState(!1),[o,l]=W.useState(!1),{onFocus:f,onBlur:d,onMouseEnter:h,onMouseLeave:p,onTouchStart:g}=t,b=W.useRef(null);W.useEffect(()=>{if(e==="render"&&l(!0),e==="viewport"){let _=C=>{C.forEach(N=>{l(N.isIntersecting)})},O=new IntersectionObserver(_,{threshold:.5});return b.current&&O.observe(b.current),()=>{O.disconnect()}}},[e]),W.useEffect(()=>{if(i){let _=setTimeout(()=>{l(!0)},100);return()=>{clearTimeout(_)}}},[i]);let T=()=>{u(!0)},A=()=>{u(!1),l(!1)};return n?e!=="intent"?[o,b,{}]:[o,b,{onFocus:wo(f,T),onBlur:wo(d,A),onMouseEnter:wo(h,T),onMouseLeave:wo(p,A),onTouchStart:wo(g,T)}]:[!1,b,{}]}function wo(e,t){return n=>{e&&e(n),n.defaultPrevented||t(n)}}function zO({page:e,...t}){let{router:n}=aD(),i=W.useMemo(()=>ba(n.routes,e,n.basename),[n.routes,e,n.basename]);return i?W.createElement(jO,{page:e,matches:i,...t}):null}function VO(e){let{manifest:t,routeModules:n}=uD(),[i,u]=W.useState([]);return W.useEffect(()=>{let o=!1;return kO(e,t,n).then(l=>{o||u(l)}),()=>{o=!0}},[e,t,n]),i}function jO({page:e,matches:t,...n}){let i=xa(),{manifest:u,routeModules:o}=uD(),{basename:l}=aD(),{loaderData:f,matches:d}=UO(),h=W.useMemo(()=>lT(e,t,d,u,i,"data"),[e,t,d,u,i]),p=W.useMemo(()=>lT(e,t,d,u,i,"assets"),[e,t,d,u,i]),g=W.useMemo(()=>{if(e===i.pathname+i.search+i.hash)return[];let A=new Set,_=!1;if(t.forEach(C=>{let N=u.routes[C.route.id];!N||!N.hasLoader||(!h.some(R=>R.route.id===C.route.id)&&C.route.id in f&&o[C.route.id]?.shouldRevalidate||N.hasClientLoader?_=!0:A.add(C.route.id))}),A.size===0)return[];let O=BO(e,l);return _&&A.size>0&&O.searchParams.set("_routes",t.filter(C=>A.has(C.route.id)).map(C=>C.route.id).join(",")),[O.pathname+O.search]},[l,f,i,u,h,t,e,o]),b=W.useMemo(()=>LO(p,u),[p,u]),T=VO(p);return W.createElement(W.Fragment,null,g.map(A=>W.createElement("link",{key:A,rel:"prefetch",as:"fetch",href:A,...n})),b.map(A=>W.createElement("link",{key:A,rel:"modulepreload",href:A,...n})),T.map(({key:A,link:_})=>W.createElement("link",{key:A,..._})))}function qO(...e){return t=>{e.forEach(n=>{typeof n=="function"?n(t):n!=null&&(n.current=t)})}}var sD=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{sD&&(window.__reactRouterVersion="7.6.3")}catch{}function Lj(e,t){return Iw({basename:t?.basename,unstable_getContext:t?.unstable_getContext,future:t?.future,history:nw({window:t?.window}),hydrationData:YO(),routes:e,mapRouteProperties:pO,hydrationRouteProperties:gO,dataStrategy:t?.dataStrategy,patchRoutesOnNavigation:t?.patchRoutesOnNavigation,window:t?.window}).initialize()}function YO(){let e=window?.__staticRouterHydrationData;return e&&e.errors&&(e={...e,errors:GO(e.errors)}),e}function GO(e){if(!e)return null;let t=Object.entries(e),n={};for(let[i,u]of t)if(u&&u.__type==="RouteErrorResponse")n[i]=new Pf(u.status,u.statusText,u.data,u.internal===!0);else if(u&&u.__type==="Error"){if(u.__subType){let o=window[u.__subType];if(typeof o=="function")try{let l=new o(u.message);l.stack="",n[i]=l}catch{}}if(n[i]==null){let o=new Error(u.message);o.stack="",n[i]=o}}else n[i]=u;return n}var oD=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,lD=W.forwardRef(function({onClick:t,discover:n="render",prefetch:i="none",relative:u,reloadDocument:o,replace:l,state:f,target:d,to:h,preventScrollReset:p,viewTransition:g,...b},T){let{basename:A}=W.useContext(Zr),_=typeof h=="string"&&oD.test(h),O,C=!1;if(typeof h=="string"&&_&&(O=h,sD))try{let q=new URL(window.location.href),z=h.startsWith("//")?new URL(q.protocol+h):new URL(h),V=Hr(z.pathname,A);z.origin===q.origin&&V!=null?h=V+z.search+z.hash:C=!0}catch{on(!1,`<Link to="${h}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}let N=tO(h,{relative:u}),[R,Y,M]=HO(i,b),v=QO(h,{replace:l,state:f,target:d,preventScrollReset:p,relative:u,viewTransition:g});function J(q){t&&t(q),q.defaultPrevented||v(q)}let P=W.createElement("a",{...b,...M,href:O||N,onClick:C||o?t:J,ref:qO(T,Y),target:d,"data-discover":!_&&n==="render"?"true":void 0});return R&&!_?W.createElement(W.Fragment,null,P,W.createElement(zO,{page:N})):P});lD.displayName="Link";var XO=W.forwardRef(function({"aria-current":t="page",caseSensitive:n=!1,className:i="",end:u=!1,style:o,to:l,viewTransition:f,children:d,...h},p){let g=Ol(l,{relative:h.relative}),b=xa(),T=W.useContext(wl),{navigator:A,basename:_}=W.useContext(Zr),O=T!=null&&t6(g)&&f===!0,C=A.encodeLocation?A.encodeLocation(g).pathname:g.pathname,N=b.pathname,R=T&&T.navigation&&T.navigation.location?T.navigation.location.pathname:null;n||(N=N.toLowerCase(),R=R?R.toLowerCase():null,C=C.toLowerCase()),R&&_&&(R=Hr(R,_)||R);const Y=C!=="/"&&C.endsWith("/")?C.length-1:C.length;let M=N===C||!u&&N.startsWith(C)&&N.charAt(Y)==="/",v=R!=null&&(R===C||!u&&R.startsWith(C)&&R.charAt(C.length)==="/"),J={isActive:M,isPending:v,isTransitioning:O},P=M?t:void 0,q;typeof i=="function"?q=i(J):q=[i,M?"active":null,v?"pending":null,O?"transitioning":null].filter(Boolean).join(" ");let z=typeof o=="function"?o(J):o;return W.createElement(lD,{...h,"aria-current":P,className:q,ref:p,style:z,to:l,viewTransition:f},typeof d=="function"?d(J):d)});XO.displayName="NavLink";var KO=W.forwardRef(({discover:e="render",fetcherKey:t,navigate:n,reloadDocument:i,replace:u,state:o,method:l=Tf,action:f,onSubmit:d,relative:h,preventScrollReset:p,viewTransition:g,...b},T)=>{let A=JO(),_=e6(f,{relative:h}),O=l.toLowerCase()==="get"?"get":"post",C=typeof f=="string"&&oD.test(f),N=R=>{if(d&&d(R),R.defaultPrevented)return;R.preventDefault();let Y=R.nativeEvent.submitter,M=Y?.getAttribute("formmethod")||l;A(Y||R.currentTarget,{fetcherKey:t,method:M,navigate:n,replace:u,state:o,relative:h,preventScrollReset:p,viewTransition:g})};return W.createElement("form",{ref:T,method:O,action:_,onSubmit:i?d:N,...b,"data-discover":!C&&e==="render"?"true":void 0})});KO.displayName="Form";function WO(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function cD(e){let t=W.useContext(du);return ot(t,WO(e)),t}function QO(e,{target:t,replace:n,state:i,preventScrollReset:u,relative:o,viewTransition:l}={}){let f=rD(),d=xa(),h=Ol(e,{relative:o});return W.useCallback(p=>{if(_O(p,t)){p.preventDefault();let g=n!==void 0?n:Aa(d)===Aa(h);f(e,{replace:g,state:i,preventScrollReset:u,relative:o,viewTransition:l})}},[d,f,h,n,i,t,e,u,o,l])}var $O=0,ZO=()=>`__${String(++$O)}__`;function JO(){let{router:e}=cD("useSubmit"),{basename:t}=W.useContext(Zr),n=dO();return W.useCallback(async(i,u={})=>{let{action:o,method:l,encType:f,formData:d,body:h}=wO(i,t);if(u.navigate===!1){let p=u.fetcherKey||ZO();await e.fetch(p,n,u.action||o,{preventScrollReset:u.preventScrollReset,formData:d,body:h,formMethod:u.method||l,formEncType:u.encType||f,flushSync:u.flushSync})}else await e.navigate(u.action||o,{preventScrollReset:u.preventScrollReset,formData:d,body:h,formMethod:u.method||l,formEncType:u.encType||f,replace:u.replace,state:u.state,fromRouteId:n,flushSync:u.flushSync,viewTransition:u.viewTransition})},[e,t,n])}function e6(e,{relative:t}={}){let{basename:n}=W.useContext(Zr),i=W.useContext(Jr);ot(i,"useFormAction must be used inside a RouteContext");let[u]=i.matches.slice(-1),o={...Ol(e||".",{relative:t})},l=xa();if(e==null){o.search=l.search;let f=new URLSearchParams(o.search),d=f.getAll("index");if(d.some(p=>p==="")){f.delete("index"),d.filter(g=>g).forEach(g=>f.append("index",g));let p=f.toString();o.search=p?`?${p}`:""}}return(!e||e===".")&&u.route.index&&(o.search=o.search?o.search.replace(/^\?/,"?index&"):"?index"),n!=="/"&&(o.pathname=o.pathname==="/"?n:mi([n,o.pathname])),Aa(o)}function t6(e,t={}){let n=W.useContext(P0);ot(n!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:i}=cD("useViewTransitionState"),u=Ol(e,{relative:t.relative});if(!n.isTransitioning)return!1;let o=Hr(n.currentLocation.pathname,i)||n.currentLocation.pathname,l=Hr(n.nextLocation.pathname,i)||n.nextLocation.pathname;return If(u.pathname,l)!=null||If(u.pathname,o)!=null}[...FO];var n6=B2();/** + * react-router v7.6.3 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function Mj(e){return W.createElement(yO,{flushSync:n6.flushSync,...e})}const V0=W.createContext({});function j0(e){const t=W.useRef(null);return t.current===null&&(t.current=e()),t.current}const q0=typeof window<"u",fD=q0?W.useLayoutEffect:W.useEffect,td=W.createContext(null);function Y0(e,t){e.indexOf(t)===-1&&e.push(t)}function G0(e,t){const n=e.indexOf(t);n>-1&&e.splice(n,1)}const Ui=(e,t,n)=>n>t?t:n<e?e:n;let X0=()=>{};const Hi={},dD=e=>/^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(e);function hD(e){return typeof e=="object"&&e!==null}const mD=e=>/^0[^.\s]+$/u.test(e);function K0(e){let t;return()=>(t===void 0&&(t=e()),t)}const Ur=e=>e,r6=(e,t)=>n=>t(e(n)),Nl=(...e)=>e.reduce(r6),gl=(e,t,n)=>{const i=t-e;return i===0?1:(n-e)/i};class W0{constructor(){this.subscriptions=[]}add(t){return Y0(this.subscriptions,t),()=>G0(this.subscriptions,t)}notify(t,n,i){const u=this.subscriptions.length;if(u)if(u===1)this.subscriptions[0](t,n,i);else for(let o=0;o<u;o++){const l=this.subscriptions[o];l&&l(t,n,i)}}getSize(){return this.subscriptions.length}clear(){this.subscriptions.length=0}}const pi=e=>e*1e3,gi=e=>e/1e3;function pD(e,t){return t?e*(1e3/t):0}const gD=(e,t,n)=>(((1-3*n+3*t)*e+(3*n-6*t))*e+3*t)*e,i6=1e-7,a6=12;function u6(e,t,n,i,u){let o,l,f=0;do l=t+(n-t)/2,o=gD(l,i,u)-e,o>0?n=l:t=l;while(Math.abs(o)>i6&&++f<a6);return l}function kl(e,t,n,i){if(e===t&&n===i)return Ur;const u=o=>u6(o,0,1,e,n);return o=>o===0||o===1?o:gD(u(o),t,i)}const ED=e=>t=>t<=.5?e(2*t)/2:(2-e(2*(1-t)))/2,yD=e=>t=>1-e(1-t),bD=kl(.33,1.53,.69,.99),Q0=yD(bD),TD=ED(Q0),AD=e=>(e*=2)<1?.5*Q0(e):.5*(2-Math.pow(2,-10*(e-1))),$0=e=>1-Math.sin(Math.acos(e)),SD=yD($0),DD=ED($0),s6=kl(.42,0,1,1),o6=kl(0,0,.58,1),vD=kl(.42,0,.58,1),l6=e=>Array.isArray(e)&&typeof e[0]!="number",CD=e=>Array.isArray(e)&&typeof e[0]=="number",c6={linear:Ur,easeIn:s6,easeInOut:vD,easeOut:o6,circIn:$0,circInOut:DD,circOut:SD,backIn:Q0,backInOut:TD,backOut:bD,anticipate:AD},f6=e=>typeof e=="string",cT=e=>{if(CD(e)){X0(e.length===4);const[t,n,i,u]=e;return kl(t,n,i,u)}else if(f6(e))return c6[e];return e},ef=["setup","read","resolveKeyframes","preUpdate","update","preRender","render","postRender"],fT={value:null};function d6(e,t){let n=new Set,i=new Set,u=!1,o=!1;const l=new WeakSet;let f={delta:0,timestamp:0,isProcessing:!1},d=0;function h(g){l.has(g)&&(p.schedule(g),e()),d++,g(f)}const p={schedule:(g,b=!1,T=!1)=>{const _=T&&u?n:i;return b&&l.add(g),_.has(g)||_.add(g),g},cancel:g=>{i.delete(g),l.delete(g)},process:g=>{if(f=g,u){o=!0;return}u=!0,[n,i]=[i,n],n.forEach(h),t&&fT.value&&fT.value.frameloop[t].push(d),d=0,n.clear(),u=!1,o&&(o=!1,p.process(g))}};return p}const h6=40;function _D(e,t){let n=!1,i=!0;const u={delta:0,timestamp:0,isProcessing:!1},o=()=>n=!0,l=ef.reduce((R,Y)=>(R[Y]=d6(o,t?Y:void 0),R),{}),{setup:f,read:d,resolveKeyframes:h,preUpdate:p,update:g,preRender:b,render:T,postRender:A}=l,_=()=>{const R=Hi.useManualTiming?u.timestamp:performance.now();n=!1,Hi.useManualTiming||(u.delta=i?1e3/60:Math.max(Math.min(R-u.timestamp,h6),1)),u.timestamp=R,u.isProcessing=!0,f.process(u),d.process(u),h.process(u),p.process(u),g.process(u),b.process(u),T.process(u),A.process(u),u.isProcessing=!1,n&&t&&(i=!1,e(_))},O=()=>{n=!0,i=!0,u.isProcessing||e(_)};return{schedule:ef.reduce((R,Y)=>{const M=l[Y];return R[Y]=(v,J=!1,P=!1)=>(n||O(),M.schedule(v,J,P)),R},{}),cancel:R=>{for(let Y=0;Y<ef.length;Y++)l[ef[Y]].cancel(R)},state:u,steps:l}}const{schedule:jt,cancel:Sa,state:wn,steps:Bm}=_D(typeof requestAnimationFrame<"u"?requestAnimationFrame:Ur,!0);let Sf;function m6(){Sf=void 0}const nr={now:()=>(Sf===void 0&&nr.set(wn.isProcessing||Hi.useManualTiming?wn.timestamp:performance.now()),Sf),set:e=>{Sf=e,queueMicrotask(m6)}},xD=e=>t=>typeof t=="string"&&t.startsWith(e),Z0=xD("--"),p6=xD("var(--"),J0=e=>p6(e)?g6.test(e.split("/*")[0].trim()):!1,g6=/var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu,ps={test:e=>typeof e=="number",parse:parseFloat,transform:e=>e},El={...ps,transform:e=>Ui(0,1,e)},tf={...ps,default:1},tl=e=>Math.round(e*1e5)/1e5,eg=/-?(?:\d+(?:\.\d+)?|\.\d+)/gu;function E6(e){return e==null}const y6=/^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu,tg=(e,t)=>n=>!!(typeof n=="string"&&y6.test(n)&&n.startsWith(e)||t&&!E6(n)&&Object.prototype.hasOwnProperty.call(n,t)),RD=(e,t,n)=>i=>{if(typeof i!="string")return i;const[u,o,l,f]=i.match(eg);return{[e]:parseFloat(u),[t]:parseFloat(o),[n]:parseFloat(l),alpha:f!==void 0?parseFloat(f):1}},b6=e=>Ui(0,255,e),Um={...ps,transform:e=>Math.round(b6(e))},nu={test:tg("rgb","red"),parse:RD("red","green","blue"),transform:({red:e,green:t,blue:n,alpha:i=1})=>"rgba("+Um.transform(e)+", "+Um.transform(t)+", "+Um.transform(n)+", "+tl(El.transform(i))+")"};function T6(e){let t="",n="",i="",u="";return e.length>5?(t=e.substring(1,3),n=e.substring(3,5),i=e.substring(5,7),u=e.substring(7,9)):(t=e.substring(1,2),n=e.substring(2,3),i=e.substring(3,4),u=e.substring(4,5),t+=t,n+=n,i+=i,u+=u),{red:parseInt(t,16),green:parseInt(n,16),blue:parseInt(i,16),alpha:u?parseInt(u,16)/255:1}}const Bp={test:tg("#"),parse:T6,transform:nu.transform},Ll=e=>({test:t=>typeof t=="string"&&t.endsWith(e)&&t.split(" ").length===1,parse:parseFloat,transform:t=>`${t}${e}`}),pa=Ll("deg"),Ei=Ll("%"),Ke=Ll("px"),A6=Ll("vh"),S6=Ll("vw"),dT={...Ei,parse:e=>Ei.parse(e)/100,transform:e=>Ei.transform(e*100)},ts={test:tg("hsl","hue"),parse:RD("hue","saturation","lightness"),transform:({hue:e,saturation:t,lightness:n,alpha:i=1})=>"hsla("+Math.round(e)+", "+Ei.transform(tl(t))+", "+Ei.transform(tl(n))+", "+tl(El.transform(i))+")"},pn={test:e=>nu.test(e)||Bp.test(e)||ts.test(e),parse:e=>nu.test(e)?nu.parse(e):ts.test(e)?ts.parse(e):Bp.parse(e),transform:e=>typeof e=="string"?e:e.hasOwnProperty("red")?nu.transform(e):ts.transform(e),getAnimatableNone:e=>{const t=pn.parse(e);return t.alpha=0,pn.transform(t)}},D6=/(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;function v6(e){return isNaN(e)&&typeof e=="string"&&(e.match(eg)?.length||0)+(e.match(D6)?.length||0)>0}const wD="number",OD="color",C6="var",_6="var(",hT="${}",x6=/var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;function yl(e){const t=e.toString(),n=[],i={color:[],number:[],var:[]},u=[];let o=0;const f=t.replace(x6,d=>(pn.test(d)?(i.color.push(o),u.push(OD),n.push(pn.parse(d))):d.startsWith(_6)?(i.var.push(o),u.push(C6),n.push(d)):(i.number.push(o),u.push(wD),n.push(parseFloat(d))),++o,hT)).split(hT);return{values:n,split:f,indexes:i,types:u}}function ND(e){return yl(e).values}function kD(e){const{split:t,types:n}=yl(e),i=t.length;return u=>{let o="";for(let l=0;l<i;l++)if(o+=t[l],u[l]!==void 0){const f=n[l];f===wD?o+=tl(u[l]):f===OD?o+=pn.transform(u[l]):o+=u[l]}return o}}const R6=e=>typeof e=="number"?0:pn.test(e)?pn.getAnimatableNone(e):e;function w6(e){const t=ND(e);return kD(e)(t.map(R6))}const Da={test:v6,parse:ND,createTransformer:kD,getAnimatableNone:w6};function Hm(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+(t-e)*6*n:n<1/2?t:n<2/3?e+(t-e)*(2/3-n)*6:e}function O6({hue:e,saturation:t,lightness:n,alpha:i}){e/=360,t/=100,n/=100;let u=0,o=0,l=0;if(!t)u=o=l=n;else{const f=n<.5?n*(1+t):n+t-n*t,d=2*n-f;u=Hm(d,f,e+1/3),o=Hm(d,f,e),l=Hm(d,f,e-1/3)}return{red:Math.round(u*255),green:Math.round(o*255),blue:Math.round(l*255),alpha:i}}function Bf(e,t){return n=>n>0?t:e}const Kt=(e,t,n)=>e+(t-e)*n,zm=(e,t,n)=>{const i=e*e,u=n*(t*t-i)+i;return u<0?0:Math.sqrt(u)},N6=[Bp,nu,ts],k6=e=>N6.find(t=>t.test(e));function mT(e){const t=k6(e);if(!t)return!1;let n=t.parse(e);return t===ts&&(n=O6(n)),n}const pT=(e,t)=>{const n=mT(e),i=mT(t);if(!n||!i)return Bf(e,t);const u={...n};return o=>(u.red=zm(n.red,i.red,o),u.green=zm(n.green,i.green,o),u.blue=zm(n.blue,i.blue,o),u.alpha=Kt(n.alpha,i.alpha,o),nu.transform(u))},Up=new Set(["none","hidden"]);function L6(e,t){return Up.has(e)?n=>n<=0?e:t:n=>n>=1?t:e}function M6(e,t){return n=>Kt(e,t,n)}function ng(e){return typeof e=="number"?M6:typeof e=="string"?J0(e)?Bf:pn.test(e)?pT:F6:Array.isArray(e)?LD:typeof e=="object"?pn.test(e)?pT:I6:Bf}function LD(e,t){const n=[...e],i=n.length,u=e.map((o,l)=>ng(o)(o,t[l]));return o=>{for(let l=0;l<i;l++)n[l]=u[l](o);return n}}function I6(e,t){const n={...e,...t},i={};for(const u in n)e[u]!==void 0&&t[u]!==void 0&&(i[u]=ng(e[u])(e[u],t[u]));return u=>{for(const o in i)n[o]=i[o](u);return n}}function P6(e,t){const n=[],i={color:0,var:0,number:0};for(let u=0;u<t.values.length;u++){const o=t.types[u],l=e.indexes[o][i[o]],f=e.values[l]??0;n[u]=f,i[o]++}return n}const F6=(e,t)=>{const n=Da.createTransformer(t),i=yl(e),u=yl(t);return i.indexes.var.length===u.indexes.var.length&&i.indexes.color.length===u.indexes.color.length&&i.indexes.number.length>=u.indexes.number.length?Up.has(e)&&!u.values.length||Up.has(t)&&!i.values.length?L6(e,t):Nl(LD(P6(i,u),u.values),n):Bf(e,t)};function MD(e,t,n){return typeof e=="number"&&typeof t=="number"&&typeof n=="number"?Kt(e,t,n):ng(e)(e,t)}const B6=e=>{const t=({timestamp:n})=>e(n);return{start:(n=!0)=>jt.update(t,n),stop:()=>Sa(t),now:()=>wn.isProcessing?wn.timestamp:nr.now()}},ID=(e,t,n=10)=>{let i="";const u=Math.max(Math.round(t/n),2);for(let o=0;o<u;o++)i+=Math.round(e(o/(u-1))*1e4)/1e4+", ";return`linear(${i.substring(0,i.length-2)})`},Uf=2e4;function rg(e){let t=0;const n=50;let i=e.next(t);for(;!i.done&&t<Uf;)t+=n,i=e.next(t);return t>=Uf?1/0:t}function U6(e,t=100,n){const i=n({...e,keyframes:[0,t]}),u=Math.min(rg(i),Uf);return{type:"keyframes",ease:o=>i.next(u*o).value/t,duration:gi(u)}}const H6=5;function PD(e,t,n){const i=Math.max(t-H6,0);return pD(n-e(i),t-i)}const en={stiffness:100,damping:10,mass:1,velocity:0,duration:800,bounce:.3,visualDuration:.3,restSpeed:{granular:.01,default:2},restDelta:{granular:.005,default:.5},minDuration:.01,maxDuration:10,minDamping:.05,maxDamping:1},Vm=.001;function z6({duration:e=en.duration,bounce:t=en.bounce,velocity:n=en.velocity,mass:i=en.mass}){let u,o,l=1-t;l=Ui(en.minDamping,en.maxDamping,l),e=Ui(en.minDuration,en.maxDuration,gi(e)),l<1?(u=h=>{const p=h*l,g=p*e,b=p-n,T=Hp(h,l),A=Math.exp(-g);return Vm-b/T*A},o=h=>{const g=h*l*e,b=g*n+n,T=Math.pow(l,2)*Math.pow(h,2)*e,A=Math.exp(-g),_=Hp(Math.pow(h,2),l);return(-u(h)+Vm>0?-1:1)*((b-T)*A)/_}):(u=h=>{const p=Math.exp(-h*e),g=(h-n)*e+1;return-Vm+p*g},o=h=>{const p=Math.exp(-h*e),g=(n-h)*(e*e);return p*g});const f=5/e,d=j6(u,o,f);if(e=pi(e),isNaN(d))return{stiffness:en.stiffness,damping:en.damping,duration:e};{const h=Math.pow(d,2)*i;return{stiffness:h,damping:l*2*Math.sqrt(i*h),duration:e}}}const V6=12;function j6(e,t,n){let i=n;for(let u=1;u<V6;u++)i=i-e(i)/t(i);return i}function Hp(e,t){return e*Math.sqrt(1-t*t)}const q6=["duration","bounce"],Y6=["stiffness","damping","mass"];function gT(e,t){return t.some(n=>e[n]!==void 0)}function G6(e){let t={velocity:en.velocity,stiffness:en.stiffness,damping:en.damping,mass:en.mass,isResolvedFromDuration:!1,...e};if(!gT(e,Y6)&&gT(e,q6))if(e.visualDuration){const n=e.visualDuration,i=2*Math.PI/(n*1.2),u=i*i,o=2*Ui(.05,1,1-(e.bounce||0))*Math.sqrt(u);t={...t,mass:en.mass,stiffness:u,damping:o}}else{const n=z6(e);t={...t,...n,mass:en.mass},t.isResolvedFromDuration=!0}return t}function Hf(e=en.visualDuration,t=en.bounce){const n=typeof e!="object"?{visualDuration:e,keyframes:[0,1],bounce:t}:e;let{restSpeed:i,restDelta:u}=n;const o=n.keyframes[0],l=n.keyframes[n.keyframes.length-1],f={done:!1,value:o},{stiffness:d,damping:h,mass:p,duration:g,velocity:b,isResolvedFromDuration:T}=G6({...n,velocity:-gi(n.velocity||0)}),A=b||0,_=h/(2*Math.sqrt(d*p)),O=l-o,C=gi(Math.sqrt(d/p)),N=Math.abs(O)<5;i||(i=N?en.restSpeed.granular:en.restSpeed.default),u||(u=N?en.restDelta.granular:en.restDelta.default);let R;if(_<1){const M=Hp(C,_);R=v=>{const J=Math.exp(-_*C*v);return l-J*((A+_*C*O)/M*Math.sin(M*v)+O*Math.cos(M*v))}}else if(_===1)R=M=>l-Math.exp(-C*M)*(O+(A+C*O)*M);else{const M=C*Math.sqrt(_*_-1);R=v=>{const J=Math.exp(-_*C*v),P=Math.min(M*v,300);return l-J*((A+_*C*O)*Math.sinh(P)+M*O*Math.cosh(P))/M}}const Y={calculatedDuration:T&&g||null,next:M=>{const v=R(M);if(T)f.done=M>=g;else{let J=M===0?A:0;_<1&&(J=M===0?pi(A):PD(R,M,v));const P=Math.abs(J)<=i,q=Math.abs(l-v)<=u;f.done=P&&q}return f.value=f.done?l:v,f},toString:()=>{const M=Math.min(rg(Y),Uf),v=ID(J=>Y.next(M*J).value,M,30);return M+"ms "+v},toTransition:()=>{}};return Y}Hf.applyToOptions=e=>{const t=U6(e,100,Hf);return e.ease=t.ease,e.duration=pi(t.duration),e.type="keyframes",e};function zp({keyframes:e,velocity:t=0,power:n=.8,timeConstant:i=325,bounceDamping:u=10,bounceStiffness:o=500,modifyTarget:l,min:f,max:d,restDelta:h=.5,restSpeed:p}){const g=e[0],b={done:!1,value:g},T=P=>f!==void 0&&P<f||d!==void 0&&P>d,A=P=>f===void 0?d:d===void 0||Math.abs(f-P)<Math.abs(d-P)?f:d;let _=n*t;const O=g+_,C=l===void 0?O:l(O);C!==O&&(_=C-g);const N=P=>-_*Math.exp(-P/i),R=P=>C+N(P),Y=P=>{const q=N(P),z=R(P);b.done=Math.abs(q)<=h,b.value=b.done?C:z};let M,v;const J=P=>{T(b.value)&&(M=P,v=Hf({keyframes:[b.value,A(b.value)],velocity:PD(R,P,b.value),damping:u,stiffness:o,restDelta:h,restSpeed:p}))};return J(0),{calculatedDuration:null,next:P=>{let q=!1;return!v&&M===void 0&&(q=!0,Y(P),J(P)),M!==void 0&&P>=M?v.next(P-M):(!q&&Y(P),b)}}}function X6(e,t,n){const i=[],u=n||Hi.mix||MD,o=e.length-1;for(let l=0;l<o;l++){let f=u(e[l],e[l+1]);if(t){const d=Array.isArray(t)?t[l]||Ur:t;f=Nl(d,f)}i.push(f)}return i}function K6(e,t,{clamp:n=!0,ease:i,mixer:u}={}){const o=e.length;if(X0(o===t.length),o===1)return()=>t[0];if(o===2&&t[0]===t[1])return()=>t[1];const l=e[0]===e[1];e[0]>e[o-1]&&(e=[...e].reverse(),t=[...t].reverse());const f=X6(t,i,u),d=f.length,h=p=>{if(l&&p<e[0])return t[0];let g=0;if(d>1)for(;g<e.length-2&&!(p<e[g+1]);g++);const b=gl(e[g],e[g+1],p);return f[g](b)};return n?p=>h(Ui(e[0],e[o-1],p)):h}function W6(e,t){const n=e[e.length-1];for(let i=1;i<=t;i++){const u=gl(0,t,i);e.push(Kt(n,1,u))}}function Q6(e){const t=[0];return W6(t,e.length-1),t}function $6(e,t){return e.map(n=>n*t)}function Z6(e,t){return e.map(()=>t||vD).splice(0,e.length-1)}function nl({duration:e=300,keyframes:t,times:n,ease:i="easeInOut"}){const u=l6(i)?i.map(cT):cT(i),o={done:!1,value:t[0]},l=$6(n&&n.length===t.length?n:Q6(t),e),f=K6(l,t,{ease:Array.isArray(u)?u:Z6(t,u)});return{calculatedDuration:e,next:d=>(o.value=f(d),o.done=d>=e,o)}}const J6=e=>e!==null;function ig(e,{repeat:t,repeatType:n="loop"},i,u=1){const o=e.filter(J6),f=u<0||t&&n!=="loop"&&t%2===1?0:o.length-1;return!f||i===void 0?o[f]:i}const eN={decay:zp,inertia:zp,tween:nl,keyframes:nl,spring:Hf};function FD(e){typeof e.type=="string"&&(e.type=eN[e.type])}class ag{constructor(){this.updateFinished()}get finished(){return this._finished}updateFinished(){this._finished=new Promise(t=>{this.resolve=t})}notifyFinished(){this.resolve()}then(t,n){return this.finished.then(t,n)}}const tN=e=>e/100;class ug extends ag{constructor(t){super(),this.state="idle",this.startTime=null,this.isStopped=!1,this.currentTime=0,this.holdTime=null,this.playbackSpeed=1,this.stop=()=>{const{motionValue:n}=this.options;n&&n.updatedAt!==nr.now()&&this.tick(nr.now()),this.isStopped=!0,this.state!=="idle"&&(this.teardown(),this.options.onStop?.())},this.options=t,this.initAnimation(),this.play(),t.autoplay===!1&&this.pause()}initAnimation(){const{options:t}=this;FD(t);const{type:n=nl,repeat:i=0,repeatDelay:u=0,repeatType:o,velocity:l=0}=t;let{keyframes:f}=t;const d=n||nl;d!==nl&&typeof f[0]!="number"&&(this.mixKeyframes=Nl(tN,MD(f[0],f[1])),f=[0,100]);const h=d({...t,keyframes:f});o==="mirror"&&(this.mirroredGenerator=d({...t,keyframes:[...f].reverse(),velocity:-l})),h.calculatedDuration===null&&(h.calculatedDuration=rg(h));const{calculatedDuration:p}=h;this.calculatedDuration=p,this.resolvedDuration=p+u,this.totalDuration=this.resolvedDuration*(i+1)-u,this.generator=h}updateTime(t){const n=Math.round(t-this.startTime)*this.playbackSpeed;this.holdTime!==null?this.currentTime=this.holdTime:this.currentTime=n}tick(t,n=!1){const{generator:i,totalDuration:u,mixKeyframes:o,mirroredGenerator:l,resolvedDuration:f,calculatedDuration:d}=this;if(this.startTime===null)return i.next(0);const{delay:h=0,keyframes:p,repeat:g,repeatType:b,repeatDelay:T,type:A,onUpdate:_,finalKeyframe:O}=this.options;this.speed>0?this.startTime=Math.min(this.startTime,t):this.speed<0&&(this.startTime=Math.min(t-u/this.speed,this.startTime)),n?this.currentTime=t:this.updateTime(t);const C=this.currentTime-h*(this.playbackSpeed>=0?1:-1),N=this.playbackSpeed>=0?C<0:C>u;this.currentTime=Math.max(C,0),this.state==="finished"&&this.holdTime===null&&(this.currentTime=u);let R=this.currentTime,Y=i;if(g){const P=Math.min(this.currentTime,u)/f;let q=Math.floor(P),z=P%1;!z&&P>=1&&(z=1),z===1&&q--,q=Math.min(q,g+1),!!(q%2)&&(b==="reverse"?(z=1-z,T&&(z-=T/f)):b==="mirror"&&(Y=l)),R=Ui(0,1,z)*f}const M=N?{done:!1,value:p[0]}:Y.next(R);o&&(M.value=o(M.value));let{done:v}=M;!N&&d!==null&&(v=this.playbackSpeed>=0?this.currentTime>=u:this.currentTime<=0);const J=this.holdTime===null&&(this.state==="finished"||this.state==="running"&&v);return J&&A!==zp&&(M.value=ig(p,this.options,O,this.speed)),_&&_(M.value),J&&this.finish(),M}then(t,n){return this.finished.then(t,n)}get duration(){return gi(this.calculatedDuration)}get time(){return gi(this.currentTime)}set time(t){t=pi(t),this.currentTime=t,this.startTime===null||this.holdTime!==null||this.playbackSpeed===0?this.holdTime=t:this.driver&&(this.startTime=this.driver.now()-t/this.playbackSpeed),this.driver?.start(!1)}get speed(){return this.playbackSpeed}set speed(t){this.updateTime(nr.now());const n=this.playbackSpeed!==t;this.playbackSpeed=t,n&&(this.time=gi(this.currentTime))}play(){if(this.isStopped)return;const{driver:t=B6,startTime:n}=this.options;this.driver||(this.driver=t(u=>this.tick(u))),this.options.onPlay?.();const i=this.driver.now();this.state==="finished"?(this.updateFinished(),this.startTime=i):this.holdTime!==null?this.startTime=i-this.holdTime:this.startTime||(this.startTime=n??i),this.state==="finished"&&this.speed<0&&(this.startTime+=this.calculatedDuration),this.holdTime=null,this.state="running",this.driver.start()}pause(){this.state="paused",this.updateTime(nr.now()),this.holdTime=this.currentTime}complete(){this.state!=="running"&&this.play(),this.state="finished",this.holdTime=null}finish(){this.notifyFinished(),this.teardown(),this.state="finished",this.options.onComplete?.()}cancel(){this.holdTime=null,this.startTime=0,this.tick(0),this.teardown(),this.options.onCancel?.()}teardown(){this.state="idle",this.stopDriver(),this.startTime=this.holdTime=null}stopDriver(){this.driver&&(this.driver.stop(),this.driver=void 0)}sample(t){return this.startTime=0,this.tick(t,!0)}attachTimeline(t){return this.options.allowFlatten&&(this.options.type="keyframes",this.options.ease="linear",this.initAnimation()),this.driver?.stop(),t.observe(this)}}function nN(e){for(let t=1;t<e.length;t++)e[t]??(e[t]=e[t-1])}const ru=e=>e*180/Math.PI,Vp=e=>{const t=ru(Math.atan2(e[1],e[0]));return jp(t)},rN={x:4,y:5,translateX:4,translateY:5,scaleX:0,scaleY:3,scale:e=>(Math.abs(e[0])+Math.abs(e[3]))/2,rotate:Vp,rotateZ:Vp,skewX:e=>ru(Math.atan(e[1])),skewY:e=>ru(Math.atan(e[2])),skew:e=>(Math.abs(e[1])+Math.abs(e[2]))/2},jp=e=>(e=e%360,e<0&&(e+=360),e),ET=Vp,yT=e=>Math.sqrt(e[0]*e[0]+e[1]*e[1]),bT=e=>Math.sqrt(e[4]*e[4]+e[5]*e[5]),iN={x:12,y:13,z:14,translateX:12,translateY:13,translateZ:14,scaleX:yT,scaleY:bT,scale:e=>(yT(e)+bT(e))/2,rotateX:e=>jp(ru(Math.atan2(e[6],e[5]))),rotateY:e=>jp(ru(Math.atan2(-e[2],e[0]))),rotateZ:ET,rotate:ET,skewX:e=>ru(Math.atan(e[4])),skewY:e=>ru(Math.atan(e[1])),skew:e=>(Math.abs(e[1])+Math.abs(e[4]))/2};function qp(e){return e.includes("scale")?1:0}function Yp(e,t){if(!e||e==="none")return qp(t);const n=e.match(/^matrix3d\(([-\d.e\s,]+)\)$/u);let i,u;if(n)i=iN,u=n;else{const f=e.match(/^matrix\(([-\d.e\s,]+)\)$/u);i=rN,u=f}if(!u)return qp(t);const o=i[t],l=u[1].split(",").map(uN);return typeof o=="function"?o(l):l[o]}const aN=(e,t)=>{const{transform:n="none"}=getComputedStyle(e);return Yp(n,t)};function uN(e){return parseFloat(e.trim())}const gs=["transformPerspective","x","y","z","translateX","translateY","translateZ","scale","scaleX","scaleY","rotate","rotateX","rotateY","rotateZ","skew","skewX","skewY"],Es=new Set(gs),TT=e=>e===ps||e===Ke,sN=new Set(["x","y","z"]),oN=gs.filter(e=>!sN.has(e));function lN(e){const t=[];return oN.forEach(n=>{const i=e.getValue(n);i!==void 0&&(t.push([n,i.get()]),i.set(n.startsWith("scale")?1:0))}),t}const uu={width:({x:e},{paddingLeft:t="0",paddingRight:n="0"})=>e.max-e.min-parseFloat(t)-parseFloat(n),height:({y:e},{paddingTop:t="0",paddingBottom:n="0"})=>e.max-e.min-parseFloat(t)-parseFloat(n),top:(e,{top:t})=>parseFloat(t),left:(e,{left:t})=>parseFloat(t),bottom:({y:e},{top:t})=>parseFloat(t)+(e.max-e.min),right:({x:e},{left:t})=>parseFloat(t)+(e.max-e.min),x:(e,{transform:t})=>Yp(t,"x"),y:(e,{transform:t})=>Yp(t,"y")};uu.translateX=uu.x;uu.translateY=uu.y;const su=new Set;let Gp=!1,Xp=!1,Kp=!1;function BD(){if(Xp){const e=Array.from(su).filter(i=>i.needsMeasurement),t=new Set(e.map(i=>i.element)),n=new Map;t.forEach(i=>{const u=lN(i);u.length&&(n.set(i,u),i.render())}),e.forEach(i=>i.measureInitialState()),t.forEach(i=>{i.render();const u=n.get(i);u&&u.forEach(([o,l])=>{i.getValue(o)?.set(l)})}),e.forEach(i=>i.measureEndState()),e.forEach(i=>{i.suspendedScrollY!==void 0&&window.scrollTo(0,i.suspendedScrollY)})}Xp=!1,Gp=!1,su.forEach(e=>e.complete(Kp)),su.clear()}function UD(){su.forEach(e=>{e.readKeyframes(),e.needsMeasurement&&(Xp=!0)})}function cN(){Kp=!0,UD(),BD(),Kp=!1}class sg{constructor(t,n,i,u,o,l=!1){this.state="pending",this.isAsync=!1,this.needsMeasurement=!1,this.unresolvedKeyframes=[...t],this.onComplete=n,this.name=i,this.motionValue=u,this.element=o,this.isAsync=l}scheduleResolve(){this.state="scheduled",this.isAsync?(su.add(this),Gp||(Gp=!0,jt.read(UD),jt.resolveKeyframes(BD))):(this.readKeyframes(),this.complete())}readKeyframes(){const{unresolvedKeyframes:t,name:n,element:i,motionValue:u}=this;if(t[0]===null){const o=u?.get(),l=t[t.length-1];if(o!==void 0)t[0]=o;else if(i&&n){const f=i.readValue(n,l);f!=null&&(t[0]=f)}t[0]===void 0&&(t[0]=l),u&&o===void 0&&u.set(t[0])}nN(t)}setFinalKeyframe(){}measureInitialState(){}renderEndStyles(){}measureEndState(){}complete(t=!1){this.state="complete",this.onComplete(this.unresolvedKeyframes,this.finalKeyframe,t),su.delete(this)}cancel(){this.state==="scheduled"&&(su.delete(this),this.state="pending")}resume(){this.state==="pending"&&this.scheduleResolve()}}const fN=e=>e.startsWith("--");function dN(e,t,n){fN(t)?e.style.setProperty(t,n):e.style[t]=n}const hN=K0(()=>window.ScrollTimeline!==void 0),mN={};function pN(e,t){const n=K0(e);return()=>mN[t]??n()}const HD=pN(()=>{try{document.createElement("div").animate({opacity:0},{easing:"linear(0, 1)"})}catch{return!1}return!0},"linearEasing"),Jo=([e,t,n,i])=>`cubic-bezier(${e}, ${t}, ${n}, ${i})`,AT={linear:"linear",ease:"ease",easeIn:"ease-in",easeOut:"ease-out",easeInOut:"ease-in-out",circIn:Jo([0,.65,.55,1]),circOut:Jo([.55,0,1,.45]),backIn:Jo([.31,.01,.66,-.59]),backOut:Jo([.33,1.53,.69,.99])};function zD(e,t){if(e)return typeof e=="function"?HD()?ID(e,t):"ease-out":CD(e)?Jo(e):Array.isArray(e)?e.map(n=>zD(n,t)||AT.easeOut):AT[e]}function gN(e,t,n,{delay:i=0,duration:u=300,repeat:o=0,repeatType:l="loop",ease:f="easeOut",times:d}={},h=void 0){const p={[t]:n};d&&(p.offset=d);const g=zD(f,u);Array.isArray(g)&&(p.easing=g);const b={delay:i,duration:u,easing:Array.isArray(g)?"linear":g,fill:"both",iterations:o+1,direction:l==="reverse"?"alternate":"normal"};return h&&(b.pseudoElement=h),e.animate(p,b)}function VD(e){return typeof e=="function"&&"applyToOptions"in e}function EN({type:e,...t}){return VD(e)&&HD()?e.applyToOptions(t):(t.duration??(t.duration=300),t.ease??(t.ease="easeOut"),t)}class yN extends ag{constructor(t){if(super(),this.finishedTime=null,this.isStopped=!1,!t)return;const{element:n,name:i,keyframes:u,pseudoElement:o,allowFlatten:l=!1,finalKeyframe:f,onComplete:d}=t;this.isPseudoElement=!!o,this.allowFlatten=l,this.options=t,X0(typeof t.type!="string");const h=EN(t);this.animation=gN(n,i,u,h,o),h.autoplay===!1&&this.animation.pause(),this.animation.onfinish=()=>{if(this.finishedTime=this.time,!o){const p=ig(u,this.options,f,this.speed);this.updateMotionValue?this.updateMotionValue(p):dN(n,i,p),this.animation.cancel()}d?.(),this.notifyFinished()}}play(){this.isStopped||(this.animation.play(),this.state==="finished"&&this.updateFinished())}pause(){this.animation.pause()}complete(){this.animation.finish?.()}cancel(){try{this.animation.cancel()}catch{}}stop(){if(this.isStopped)return;this.isStopped=!0;const{state:t}=this;t==="idle"||t==="finished"||(this.updateMotionValue?this.updateMotionValue():this.commitStyles(),this.isPseudoElement||this.cancel())}commitStyles(){this.isPseudoElement||this.animation.commitStyles?.()}get duration(){const t=this.animation.effect?.getComputedTiming?.().duration||0;return gi(Number(t))}get time(){return gi(Number(this.animation.currentTime)||0)}set time(t){this.finishedTime=null,this.animation.currentTime=pi(t)}get speed(){return this.animation.playbackRate}set speed(t){t<0&&(this.finishedTime=null),this.animation.playbackRate=t}get state(){return this.finishedTime!==null?"finished":this.animation.playState}get startTime(){return Number(this.animation.startTime)}set startTime(t){this.animation.startTime=t}attachTimeline({timeline:t,observe:n}){return this.allowFlatten&&this.animation.effect?.updateTiming({easing:"linear"}),this.animation.onfinish=null,t&&hN()?(this.animation.timeline=t,Ur):n(this)}}const jD={anticipate:AD,backInOut:TD,circInOut:DD};function bN(e){return e in jD}function TN(e){typeof e.ease=="string"&&bN(e.ease)&&(e.ease=jD[e.ease])}const ST=10;class AN extends yN{constructor(t){TN(t),FD(t),super(t),t.startTime&&(this.startTime=t.startTime),this.options=t}updateMotionValue(t){const{motionValue:n,onUpdate:i,onComplete:u,element:o,...l}=this.options;if(!n)return;if(t!==void 0){n.set(t);return}const f=new ug({...l,autoplay:!1}),d=pi(this.finishedTime??this.time);n.setWithVelocity(f.sample(d-ST).value,f.sample(d).value,ST),f.stop()}}const DT=(e,t)=>t==="zIndex"?!1:!!(typeof e=="number"||Array.isArray(e)||typeof e=="string"&&(Da.test(e)||e==="0")&&!e.startsWith("url("));function SN(e){const t=e[0];if(e.length===1)return!0;for(let n=0;n<e.length;n++)if(e[n]!==t)return!0}function DN(e,t,n,i){const u=e[0];if(u===null)return!1;if(t==="display"||t==="visibility")return!0;const o=e[e.length-1],l=DT(u,t),f=DT(o,t);return!l||!f?!1:SN(e)||(n==="spring"||VD(n))&&i}function og(e){return hD(e)&&"offsetHeight"in e}const vN=new Set(["opacity","clipPath","filter","transform"]),CN=K0(()=>Object.hasOwnProperty.call(Element.prototype,"animate"));function _N(e){const{motionValue:t,name:n,repeatDelay:i,repeatType:u,damping:o,type:l}=e;if(!og(t?.owner?.current))return!1;const{onUpdate:f,transformTemplate:d}=t.owner.getProps();return CN()&&n&&vN.has(n)&&(n!=="transform"||!d)&&!f&&!i&&u!=="mirror"&&o!==0&&l!=="inertia"}const xN=40;class RN extends ag{constructor({autoplay:t=!0,delay:n=0,type:i="keyframes",repeat:u=0,repeatDelay:o=0,repeatType:l="loop",keyframes:f,name:d,motionValue:h,element:p,...g}){super(),this.stop=()=>{this._animation&&(this._animation.stop(),this.stopTimeline?.()),this.keyframeResolver?.cancel()},this.createdAt=nr.now();const b={autoplay:t,delay:n,type:i,repeat:u,repeatDelay:o,repeatType:l,name:d,motionValue:h,element:p,...g},T=p?.KeyframeResolver||sg;this.keyframeResolver=new T(f,(A,_,O)=>this.onKeyframesResolved(A,_,b,!O),d,h,p),this.keyframeResolver?.scheduleResolve()}onKeyframesResolved(t,n,i,u){this.keyframeResolver=void 0;const{name:o,type:l,velocity:f,delay:d,isHandoff:h,onUpdate:p}=i;this.resolvedAt=nr.now(),DN(t,o,l,f)||((Hi.instantAnimations||!d)&&p?.(ig(t,i,n)),t[0]=t[t.length-1],i.duration=0,i.repeat=0);const b={startTime:u?this.resolvedAt?this.resolvedAt-this.createdAt>xN?this.resolvedAt:this.createdAt:this.createdAt:void 0,finalKeyframe:n,...i,keyframes:t},T=!h&&_N(b)?new AN({...b,element:b.motionValue.owner.current}):new ug(b);T.finished.then(()=>this.notifyFinished()).catch(Ur),this.pendingTimeline&&(this.stopTimeline=T.attachTimeline(this.pendingTimeline),this.pendingTimeline=void 0),this._animation=T}get finished(){return this._animation?this.animation.finished:this._finished}then(t,n){return this.finished.finally(t).then(()=>{})}get animation(){return this._animation||(this.keyframeResolver?.resume(),cN()),this._animation}get duration(){return this.animation.duration}get time(){return this.animation.time}set time(t){this.animation.time=t}get speed(){return this.animation.speed}get state(){return this.animation.state}set speed(t){this.animation.speed=t}get startTime(){return this.animation.startTime}attachTimeline(t){return this._animation?this.stopTimeline=this.animation.attachTimeline(t):this.pendingTimeline=t,()=>this.stop()}play(){this.animation.play()}pause(){this.animation.pause()}complete(){this.animation.complete()}cancel(){this._animation&&this.animation.cancel(),this.keyframeResolver?.cancel()}}const wN=/^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;function ON(e){const t=wN.exec(e);if(!t)return[,];const[,n,i,u]=t;return[`--${n??i}`,u]}function qD(e,t,n=1){const[i,u]=ON(e);if(!i)return;const o=window.getComputedStyle(t).getPropertyValue(i);if(o){const l=o.trim();return dD(l)?parseFloat(l):l}return J0(u)?qD(u,t,n+1):u}function lg(e,t){return e?.[t]??e?.default??e}const YD=new Set(["width","height","top","left","right","bottom",...gs]),NN={test:e=>e==="auto",parse:e=>e},GD=e=>t=>t.test(e),XD=[ps,Ke,Ei,pa,S6,A6,NN],vT=e=>XD.find(GD(e));function kN(e){return typeof e=="number"?e===0:e!==null?e==="none"||e==="0"||mD(e):!0}const LN=new Set(["brightness","contrast","saturate","opacity"]);function MN(e){const[t,n]=e.slice(0,-1).split("(");if(t==="drop-shadow")return e;const[i]=n.match(eg)||[];if(!i)return e;const u=n.replace(i,"");let o=LN.has(t)?1:0;return i!==n&&(o*=100),t+"("+o+u+")"}const IN=/\b([a-z-]*)\(.*?\)/gu,Wp={...Da,getAnimatableNone:e=>{const t=e.match(IN);return t?t.map(MN).join(" "):e}},CT={...ps,transform:Math.round},PN={rotate:pa,rotateX:pa,rotateY:pa,rotateZ:pa,scale:tf,scaleX:tf,scaleY:tf,scaleZ:tf,skew:pa,skewX:pa,skewY:pa,distance:Ke,translateX:Ke,translateY:Ke,translateZ:Ke,x:Ke,y:Ke,z:Ke,perspective:Ke,transformPerspective:Ke,opacity:El,originX:dT,originY:dT,originZ:Ke},cg={borderWidth:Ke,borderTopWidth:Ke,borderRightWidth:Ke,borderBottomWidth:Ke,borderLeftWidth:Ke,borderRadius:Ke,radius:Ke,borderTopLeftRadius:Ke,borderTopRightRadius:Ke,borderBottomRightRadius:Ke,borderBottomLeftRadius:Ke,width:Ke,maxWidth:Ke,height:Ke,maxHeight:Ke,top:Ke,right:Ke,bottom:Ke,left:Ke,padding:Ke,paddingTop:Ke,paddingRight:Ke,paddingBottom:Ke,paddingLeft:Ke,margin:Ke,marginTop:Ke,marginRight:Ke,marginBottom:Ke,marginLeft:Ke,backgroundPositionX:Ke,backgroundPositionY:Ke,...PN,zIndex:CT,fillOpacity:El,strokeOpacity:El,numOctaves:CT},FN={...cg,color:pn,backgroundColor:pn,outlineColor:pn,fill:pn,stroke:pn,borderColor:pn,borderTopColor:pn,borderRightColor:pn,borderBottomColor:pn,borderLeftColor:pn,filter:Wp,WebkitFilter:Wp},KD=e=>FN[e];function WD(e,t){let n=KD(e);return n!==Wp&&(n=Da),n.getAnimatableNone?n.getAnimatableNone(t):void 0}const BN=new Set(["auto","none","0"]);function UN(e,t,n){let i=0,u;for(;i<e.length&&!u;){const o=e[i];typeof o=="string"&&!BN.has(o)&&yl(o).values.length&&(u=e[i]),i++}if(u&&n)for(const o of t)e[o]=WD(n,u)}class HN extends sg{constructor(t,n,i,u,o){super(t,n,i,u,o,!0)}readKeyframes(){const{unresolvedKeyframes:t,element:n,name:i}=this;if(!n||!n.current)return;super.readKeyframes();for(let d=0;d<t.length;d++){let h=t[d];if(typeof h=="string"&&(h=h.trim(),J0(h))){const p=qD(h,n.current);p!==void 0&&(t[d]=p),d===t.length-1&&(this.finalKeyframe=h)}}if(this.resolveNoneKeyframes(),!YD.has(i)||t.length!==2)return;const[u,o]=t,l=vT(u),f=vT(o);if(l!==f)if(TT(l)&&TT(f))for(let d=0;d<t.length;d++){const h=t[d];typeof h=="string"&&(t[d]=parseFloat(h))}else uu[i]&&(this.needsMeasurement=!0)}resolveNoneKeyframes(){const{unresolvedKeyframes:t,name:n}=this,i=[];for(let u=0;u<t.length;u++)(t[u]===null||kN(t[u]))&&i.push(u);i.length&&UN(t,i,n)}measureInitialState(){const{element:t,unresolvedKeyframes:n,name:i}=this;if(!t||!t.current)return;i==="height"&&(this.suspendedScrollY=window.pageYOffset),this.measuredOrigin=uu[i](t.measureViewportBox(),window.getComputedStyle(t.current)),n[0]=this.measuredOrigin;const u=n[n.length-1];u!==void 0&&t.getValue(i,u).jump(u,!1)}measureEndState(){const{element:t,name:n,unresolvedKeyframes:i}=this;if(!t||!t.current)return;const u=t.getValue(n);u&&u.jump(this.measuredOrigin,!1);const o=i.length-1,l=i[o];i[o]=uu[n](t.measureViewportBox(),window.getComputedStyle(t.current)),l!==null&&this.finalKeyframe===void 0&&(this.finalKeyframe=l),this.removedTransforms?.length&&this.removedTransforms.forEach(([f,d])=>{t.getValue(f).set(d)}),this.resolveNoneKeyframes()}}function zN(e,t,n){if(e instanceof EventTarget)return[e];if(typeof e=="string"){let i=document;const u=n?.[e]??i.querySelectorAll(e);return u?Array.from(u):[]}return Array.from(e)}const QD=(e,t)=>t&&typeof e=="number"?t.transform(e):e,_T=30,VN=e=>!isNaN(parseFloat(e));class jN{constructor(t,n={}){this.canTrackVelocity=null,this.events={},this.updateAndNotify=(i,u=!0)=>{const o=nr.now();if(this.updatedAt!==o&&this.setPrevFrameValue(),this.prev=this.current,this.setCurrent(i),this.current!==this.prev&&(this.events.change?.notify(this.current),this.dependents))for(const l of this.dependents)l.dirty();u&&this.events.renderRequest?.notify(this.current)},this.hasAnimated=!1,this.setCurrent(t),this.owner=n.owner}setCurrent(t){this.current=t,this.updatedAt=nr.now(),this.canTrackVelocity===null&&t!==void 0&&(this.canTrackVelocity=VN(this.current))}setPrevFrameValue(t=this.current){this.prevFrameValue=t,this.prevUpdatedAt=this.updatedAt}onChange(t){return this.on("change",t)}on(t,n){this.events[t]||(this.events[t]=new W0);const i=this.events[t].add(n);return t==="change"?()=>{i(),jt.read(()=>{this.events.change.getSize()||this.stop()})}:i}clearListeners(){for(const t in this.events)this.events[t].clear()}attach(t,n){this.passiveEffect=t,this.stopPassiveEffect=n}set(t,n=!0){!n||!this.passiveEffect?this.updateAndNotify(t,n):this.passiveEffect(t,this.updateAndNotify)}setWithVelocity(t,n,i){this.set(n),this.prev=void 0,this.prevFrameValue=t,this.prevUpdatedAt=this.updatedAt-i}jump(t,n=!0){this.updateAndNotify(t),this.prev=t,this.prevUpdatedAt=this.prevFrameValue=void 0,n&&this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}dirty(){this.events.change?.notify(this.current)}addDependent(t){this.dependents||(this.dependents=new Set),this.dependents.add(t)}removeDependent(t){this.dependents&&this.dependents.delete(t)}get(){return this.current}getPrevious(){return this.prev}getVelocity(){const t=nr.now();if(!this.canTrackVelocity||this.prevFrameValue===void 0||t-this.updatedAt>_T)return 0;const n=Math.min(this.updatedAt-this.prevUpdatedAt,_T);return pD(parseFloat(this.current)-parseFloat(this.prevFrameValue),n)}start(t){return this.stop(),new Promise(n=>{this.hasAnimated=!0,this.animation=t(n),this.events.animationStart&&this.events.animationStart.notify()}).then(()=>{this.events.animationComplete&&this.events.animationComplete.notify(),this.clearAnimation()})}stop(){this.animation&&(this.animation.stop(),this.events.animationCancel&&this.events.animationCancel.notify()),this.clearAnimation()}isAnimating(){return!!this.animation}clearAnimation(){delete this.animation}destroy(){this.dependents?.clear(),this.events.destroy?.notify(),this.clearListeners(),this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}}function cs(e,t){return new jN(e,t)}const{schedule:fg}=_D(queueMicrotask,!1),Wr={x:!1,y:!1};function $D(){return Wr.x||Wr.y}function qN(e){return e==="x"||e==="y"?Wr[e]?null:(Wr[e]=!0,()=>{Wr[e]=!1}):Wr.x||Wr.y?null:(Wr.x=Wr.y=!0,()=>{Wr.x=Wr.y=!1})}function ZD(e,t){const n=zN(e),i=new AbortController,u={passive:!0,...t,signal:i.signal};return[n,u,()=>i.abort()]}function xT(e){return!(e.pointerType==="touch"||$D())}function YN(e,t,n={}){const[i,u,o]=ZD(e,n),l=f=>{if(!xT(f))return;const{target:d}=f,h=t(d,f);if(typeof h!="function"||!d)return;const p=g=>{xT(g)&&(h(g),d.removeEventListener("pointerleave",p))};d.addEventListener("pointerleave",p,u)};return i.forEach(f=>{f.addEventListener("pointerenter",l,u)}),o}const JD=(e,t)=>t?e===t?!0:JD(e,t.parentElement):!1,dg=e=>e.pointerType==="mouse"?typeof e.button!="number"||e.button<=0:e.isPrimary!==!1,GN=new Set(["BUTTON","INPUT","SELECT","TEXTAREA","A"]);function XN(e){return GN.has(e.tagName)||e.tabIndex!==-1}const Df=new WeakSet;function RT(e){return t=>{t.key==="Enter"&&e(t)}}function jm(e,t){e.dispatchEvent(new PointerEvent("pointer"+t,{isPrimary:!0,bubbles:!0}))}const KN=(e,t)=>{const n=e.currentTarget;if(!n)return;const i=RT(()=>{if(Df.has(n))return;jm(n,"down");const u=RT(()=>{jm(n,"up")}),o=()=>jm(n,"cancel");n.addEventListener("keyup",u,t),n.addEventListener("blur",o,t)});n.addEventListener("keydown",i,t),n.addEventListener("blur",()=>n.removeEventListener("keydown",i),t)};function wT(e){return dg(e)&&!$D()}function WN(e,t,n={}){const[i,u,o]=ZD(e,n),l=f=>{const d=f.currentTarget;if(!wT(f))return;Df.add(d);const h=t(d,f),p=(T,A)=>{window.removeEventListener("pointerup",g),window.removeEventListener("pointercancel",b),Df.has(d)&&Df.delete(d),wT(T)&&typeof h=="function"&&h(T,{success:A})},g=T=>{p(T,d===window||d===document||n.useGlobalTarget||JD(d,T.target))},b=T=>{p(T,!1)};window.addEventListener("pointerup",g,u),window.addEventListener("pointercancel",b,u)};return i.forEach(f=>{(n.useGlobalTarget?window:f).addEventListener("pointerdown",l,u),og(f)&&(f.addEventListener("focus",h=>KN(h,u)),!XN(f)&&!f.hasAttribute("tabindex")&&(f.tabIndex=0))}),o}function ev(e){return hD(e)&&"ownerSVGElement"in e}function QN(e){return ev(e)&&e.tagName==="svg"}const Mn=e=>!!(e&&e.getVelocity),$N=[...XD,pn,Da],ZN=e=>$N.find(GD(e)),hg=W.createContext({transformPagePoint:e=>e,isStatic:!1,reducedMotion:"never"});class JN extends W.Component{getSnapshotBeforeUpdate(t){const n=this.props.childRef.current;if(n&&t.isPresent&&!this.props.isPresent){const i=n.offsetParent,u=og(i)&&i.offsetWidth||0,o=this.props.sizeRef.current;o.height=n.offsetHeight||0,o.width=n.offsetWidth||0,o.top=n.offsetTop,o.left=n.offsetLeft,o.right=u-o.width-o.left}return null}componentDidUpdate(){}render(){return this.props.children}}function ek({children:e,isPresent:t,anchorX:n,root:i}){const u=W.useId(),o=W.useRef(null),l=W.useRef({width:0,height:0,top:0,left:0,right:0}),{nonce:f}=W.useContext(hg);return W.useInsertionEffect(()=>{const{width:d,height:h,top:p,left:g,right:b}=l.current;if(t||!o.current||!d||!h)return;const T=n==="left"?`left: ${g}`:`right: ${b}`;o.current.dataset.motionPopId=u;const A=document.createElement("style");f&&(A.nonce=f);const _=i??document.head;return _.appendChild(A),A.sheet&&A.sheet.insertRule(` + [data-motion-pop-id="${u}"] { + position: absolute !important; + width: ${d}px !important; + height: ${h}px !important; + ${T}px !important; + top: ${p}px !important; + } + `),()=>{_.removeChild(A),_.contains(A)&&_.removeChild(A)}},[t]),Br.jsx(JN,{isPresent:t,childRef:o,sizeRef:l,children:W.cloneElement(e,{ref:o})})}const tk=({children:e,initial:t,isPresent:n,onExitComplete:i,custom:u,presenceAffectsLayout:o,mode:l,anchorX:f,root:d})=>{const h=j0(nk),p=W.useId();let g=!0,b=W.useMemo(()=>(g=!1,{id:p,initial:t,isPresent:n,custom:u,onExitComplete:T=>{h.set(T,!0);for(const A of h.values())if(!A)return;i&&i()},register:T=>(h.set(T,!1),()=>h.delete(T))}),[n,h,i]);return o&&g&&(b={...b}),W.useMemo(()=>{h.forEach((T,A)=>h.set(A,!1))},[n]),W.useEffect(()=>{!n&&!h.size&&i&&i()},[n]),l==="popLayout"&&(e=Br.jsx(ek,{isPresent:n,anchorX:f,root:d,children:e})),Br.jsx(td.Provider,{value:b,children:e})};function nk(){return new Map}function tv(e=!0){const t=W.useContext(td);if(t===null)return[!0,null];const{isPresent:n,onExitComplete:i,register:u}=t,o=W.useId();W.useEffect(()=>{if(e)return u(o)},[e]);const l=W.useCallback(()=>e&&i&&i(o),[o,i,e]);return!n&&i?[!1,l]:[!0]}const nf=e=>e.key||"";function OT(e){const t=[];return W.Children.forEach(e,n=>{W.isValidElement(n)&&t.push(n)}),t}const Ij=({children:e,custom:t,initial:n=!0,onExitComplete:i,presenceAffectsLayout:u=!0,mode:o="sync",propagate:l=!1,anchorX:f="left",root:d})=>{const[h,p]=tv(l),g=W.useMemo(()=>OT(e),[e]),b=l&&!h?[]:g.map(nf),T=W.useRef(!0),A=W.useRef(g),_=j0(()=>new Map),[O,C]=W.useState(g),[N,R]=W.useState(g);fD(()=>{T.current=!1,A.current=g;for(let v=0;v<N.length;v++){const J=nf(N[v]);b.includes(J)?_.delete(J):_.get(J)!==!0&&_.set(J,!1)}},[N,b.length,b.join("-")]);const Y=[];if(g!==O){let v=[...g];for(let J=0;J<N.length;J++){const P=N[J],q=nf(P);b.includes(q)||(v.splice(J,0,P),Y.push(P))}return o==="wait"&&Y.length&&(v=Y),R(OT(v)),C(g),null}const{forceRender:M}=W.useContext(V0);return Br.jsx(Br.Fragment,{children:N.map(v=>{const J=nf(v),P=l&&!h?!1:g===N||b.includes(J),q=()=>{if(_.has(J))_.set(J,!0);else return;let z=!0;_.forEach(V=>{V||(z=!1)}),z&&(M?.(),R(A.current),l&&p?.(),i&&i())};return Br.jsx(tk,{isPresent:P,initial:!T.current||n?void 0:!1,custom:t,presenceAffectsLayout:u,mode:o,root:d,onExitComplete:P?void 0:q,anchorX:f,children:v},J)})})},nv=W.createContext({strict:!1}),NT={animation:["animate","variants","whileHover","whileTap","exit","whileInView","whileFocus","whileDrag"],exit:["exit"],drag:["drag","dragControls"],focus:["whileFocus"],hover:["whileHover","onHoverStart","onHoverEnd"],tap:["whileTap","onTap","onTapStart","onTapCancel"],pan:["onPan","onPanStart","onPanSessionStart","onPanEnd"],inView:["whileInView","onViewportEnter","onViewportLeave"],layout:["layout","layoutId"]},fs={};for(const e in NT)fs[e]={isEnabled:t=>NT[e].some(n=>!!t[n])};function rk(e){for(const t in e)fs[t]={...fs[t],...e[t]}}const ik=new Set(["animate","exit","variants","initial","style","values","variants","transition","transformTemplate","custom","inherit","onBeforeLayoutMeasure","onAnimationStart","onAnimationComplete","onUpdate","onDragStart","onDrag","onDragEnd","onMeasureDragConstraints","onDirectionLock","onDragTransitionEnd","_dragX","_dragY","onHoverStart","onHoverEnd","onViewportEnter","onViewportLeave","globalTapTarget","ignoreStrict","viewport"]);function zf(e){return e.startsWith("while")||e.startsWith("drag")&&e!=="draggable"||e.startsWith("layout")||e.startsWith("onTap")||e.startsWith("onPan")||e.startsWith("onLayout")||ik.has(e)}let rv=e=>!zf(e);function ak(e){typeof e=="function"&&(rv=t=>t.startsWith("on")?!zf(t):e(t))}try{ak(require("@emotion/is-prop-valid").default)}catch{}function uk(e,t,n){const i={};for(const u in e)u==="values"&&typeof e.values=="object"||(rv(u)||n===!0&&zf(u)||!t&&!zf(u)||e.draggable&&u.startsWith("onDrag"))&&(i[u]=e[u]);return i}function sk(e){if(typeof Proxy>"u")return e;const t=new Map,n=(...i)=>e(...i);return new Proxy(n,{get:(i,u)=>u==="create"?e:(t.has(u)||t.set(u,e(u)),t.get(u))})}const nd=W.createContext({});function rd(e){return e!==null&&typeof e=="object"&&typeof e.start=="function"}function bl(e){return typeof e=="string"||Array.isArray(e)}const mg=["animate","whileInView","whileFocus","whileHover","whileTap","whileDrag","exit"],pg=["initial",...mg];function id(e){return rd(e.animate)||pg.some(t=>bl(e[t]))}function iv(e){return!!(id(e)||e.variants)}function ok(e,t){if(id(e)){const{initial:n,animate:i}=e;return{initial:n===!1||bl(n)?n:void 0,animate:bl(i)?i:void 0}}return e.inherit!==!1?t:{}}function lk(e){const{initial:t,animate:n}=ok(e,W.useContext(nd));return W.useMemo(()=>({initial:t,animate:n}),[kT(t),kT(n)])}function kT(e){return Array.isArray(e)?e.join(" "):e}const ck=Symbol.for("motionComponentSymbol");function ns(e){return e&&typeof e=="object"&&Object.prototype.hasOwnProperty.call(e,"current")}function fk(e,t,n){return W.useCallback(i=>{i&&e.onMount&&e.onMount(i),t&&(i?t.mount(i):t.unmount()),n&&(typeof n=="function"?n(i):ns(n)&&(n.current=i))},[t])}const gg=e=>e.replace(/([a-z])([A-Z])/gu,"$1-$2").toLowerCase(),dk="framerAppearId",av="data-"+gg(dk),uv=W.createContext({});function hk(e,t,n,i,u){const{visualElement:o}=W.useContext(nd),l=W.useContext(nv),f=W.useContext(td),d=W.useContext(hg).reducedMotion,h=W.useRef(null);i=i||l.renderer,!h.current&&i&&(h.current=i(e,{visualState:t,parent:o,props:n,presenceContext:f,blockInitialAnimation:f?f.initial===!1:!1,reducedMotionConfig:d}));const p=h.current,g=W.useContext(uv);p&&!p.projection&&u&&(p.type==="html"||p.type==="svg")&&mk(h.current,n,u,g);const b=W.useRef(!1);W.useInsertionEffect(()=>{p&&b.current&&p.update(n,f)});const T=n[av],A=W.useRef(!!T&&!window.MotionHandoffIsComplete?.(T)&&window.MotionHasOptimisedAnimation?.(T));return fD(()=>{p&&(b.current=!0,window.MotionIsMounted=!0,p.updateFeatures(),fg.render(p.render),A.current&&p.animationState&&p.animationState.animateChanges())}),W.useEffect(()=>{p&&(!A.current&&p.animationState&&p.animationState.animateChanges(),A.current&&(queueMicrotask(()=>{window.MotionHandoffMarkAsComplete?.(T)}),A.current=!1))}),p}function mk(e,t,n,i){const{layoutId:u,layout:o,drag:l,dragConstraints:f,layoutScroll:d,layoutRoot:h,layoutCrossfade:p}=t;e.projection=new n(e.latestValues,t["data-framer-portal-id"]?void 0:sv(e.parent)),e.projection.setOptions({layoutId:u,layout:o,alwaysMeasureLayout:!!l||f&&ns(f),visualElement:e,animationType:typeof o=="string"?o:"both",initialPromotionConfig:i,crossfade:p,layoutScroll:d,layoutRoot:h})}function sv(e){if(e)return e.options.allowProjection!==!1?e.projection:sv(e.parent)}function pk({preloadedFeatures:e,createVisualElement:t,useRender:n,useVisualState:i,Component:u}){e&&rk(e);function o(f,d){let h;const p={...W.useContext(hg),...f,layoutId:gk(f)},{isStatic:g}=p,b=lk(f),T=i(f,g);if(!g&&q0){Ek();const A=yk(p);h=A.MeasureLayout,b.visualElement=hk(u,T,p,t,A.ProjectionNode)}return Br.jsxs(nd.Provider,{value:b,children:[h&&b.visualElement?Br.jsx(h,{visualElement:b.visualElement,...p}):null,n(u,f,fk(T,b.visualElement,d),T,g,b.visualElement)]})}o.displayName=`motion.${typeof u=="string"?u:`create(${u.displayName??u.name??""})`}`;const l=W.forwardRef(o);return l[ck]=u,l}function gk({layoutId:e}){const t=W.useContext(V0).id;return t&&e!==void 0?t+"-"+e:e}function Ek(e,t){W.useContext(nv).strict}function yk(e){const{drag:t,layout:n}=fs;if(!t&&!n)return{};const i={...t,...n};return{MeasureLayout:t?.isEnabled(e)||n?.isEnabled(e)?i.MeasureLayout:void 0,ProjectionNode:i.ProjectionNode}}const Tl={};function bk(e){for(const t in e)Tl[t]=e[t],Z0(t)&&(Tl[t].isCSSVariable=!0)}function ov(e,{layout:t,layoutId:n}){return Es.has(e)||e.startsWith("origin")||(t||n!==void 0)&&(!!Tl[e]||e==="opacity")}const Tk={x:"translateX",y:"translateY",z:"translateZ",transformPerspective:"perspective"},Ak=gs.length;function Sk(e,t,n){let i="",u=!0;for(let o=0;o<Ak;o++){const l=gs[o],f=e[l];if(f===void 0)continue;let d=!0;if(typeof f=="number"?d=f===(l.startsWith("scale")?1:0):d=parseFloat(f)===0,!d||n){const h=QD(f,cg[l]);if(!d){u=!1;const p=Tk[l]||l;i+=`${p}(${h}) `}n&&(t[l]=h)}}return i=i.trim(),n?i=n(t,u?"":i):u&&(i="none"),i}function Eg(e,t,n){const{style:i,vars:u,transformOrigin:o}=e;let l=!1,f=!1;for(const d in t){const h=t[d];if(Es.has(d)){l=!0;continue}else if(Z0(d)){u[d]=h;continue}else{const p=QD(h,cg[d]);d.startsWith("origin")?(f=!0,o[d]=p):i[d]=p}}if(t.transform||(l||n?i.transform=Sk(t,e.transform,n):i.transform&&(i.transform="none")),f){const{originX:d="50%",originY:h="50%",originZ:p=0}=o;i.transformOrigin=`${d} ${h} ${p}`}}const yg=()=>({style:{},transform:{},transformOrigin:{},vars:{}});function lv(e,t,n){for(const i in t)!Mn(t[i])&&!ov(i,n)&&(e[i]=t[i])}function Dk({transformTemplate:e},t){return W.useMemo(()=>{const n=yg();return Eg(n,t,e),Object.assign({},n.vars,n.style)},[t])}function vk(e,t){const n=e.style||{},i={};return lv(i,n,e),Object.assign(i,Dk(e,t)),i}function Ck(e,t){const n={},i=vk(e,t);return e.drag&&e.dragListener!==!1&&(n.draggable=!1,i.userSelect=i.WebkitUserSelect=i.WebkitTouchCallout="none",i.touchAction=e.drag===!0?"none":`pan-${e.drag==="x"?"y":"x"}`),e.tabIndex===void 0&&(e.onTap||e.onTapStart||e.whileTap)&&(n.tabIndex=0),n.style=i,n}const _k={offset:"stroke-dashoffset",array:"stroke-dasharray"},xk={offset:"strokeDashoffset",array:"strokeDasharray"};function Rk(e,t,n=1,i=0,u=!0){e.pathLength=1;const o=u?_k:xk;e[o.offset]=Ke.transform(-i);const l=Ke.transform(t),f=Ke.transform(n);e[o.array]=`${l} ${f}`}function cv(e,{attrX:t,attrY:n,attrScale:i,pathLength:u,pathSpacing:o=1,pathOffset:l=0,...f},d,h,p){if(Eg(e,f,h),d){e.style.viewBox&&(e.attrs.viewBox=e.style.viewBox);return}e.attrs=e.style,e.style={};const{attrs:g,style:b}=e;g.transform&&(b.transform=g.transform,delete g.transform),(b.transform||g.transformOrigin)&&(b.transformOrigin=g.transformOrigin??"50% 50%",delete g.transformOrigin),b.transform&&(b.transformBox=p?.transformBox??"fill-box",delete g.transformBox),t!==void 0&&(g.x=t),n!==void 0&&(g.y=n),i!==void 0&&(g.scale=i),u!==void 0&&Rk(g,u,o,l,!1)}const fv=()=>({...yg(),attrs:{}}),dv=e=>typeof e=="string"&&e.toLowerCase()==="svg";function wk(e,t,n,i){const u=W.useMemo(()=>{const o=fv();return cv(o,t,dv(i),e.transformTemplate,e.style),{...o.attrs,style:{...o.style}}},[t]);if(e.style){const o={};lv(o,e.style,e),u.style={...o,...u.style}}return u}const Ok=["animate","circle","defs","desc","ellipse","g","image","line","filter","marker","mask","metadata","path","pattern","polygon","polyline","rect","stop","switch","symbol","svg","text","tspan","use","view"];function bg(e){return typeof e!="string"||e.includes("-")?!1:!!(Ok.indexOf(e)>-1||/[A-Z]/u.test(e))}function Nk(e=!1){return(n,i,u,{latestValues:o},l)=>{const d=(bg(n)?wk:Ck)(i,o,l,n),h=uk(i,typeof n=="string",e),p=n!==W.Fragment?{...h,...d,ref:u}:{},{children:g}=i,b=W.useMemo(()=>Mn(g)?g.get():g,[g]);return W.createElement(n,{...p,children:b})}}function LT(e){const t=[{},{}];return e?.values.forEach((n,i)=>{t[0][i]=n.get(),t[1][i]=n.getVelocity()}),t}function Tg(e,t,n,i){if(typeof t=="function"){const[u,o]=LT(i);t=t(n!==void 0?n:e.custom,u,o)}if(typeof t=="string"&&(t=e.variants&&e.variants[t]),typeof t=="function"){const[u,o]=LT(i);t=t(n!==void 0?n:e.custom,u,o)}return t}function vf(e){return Mn(e)?e.get():e}function kk({scrapeMotionValuesFromProps:e,createRenderState:t},n,i,u){return{latestValues:Lk(n,i,u,e),renderState:t()}}const hv=e=>(t,n)=>{const i=W.useContext(nd),u=W.useContext(td),o=()=>kk(e,t,i,u);return n?o():j0(o)};function Lk(e,t,n,i){const u={},o=i(e,{});for(const b in o)u[b]=vf(o[b]);let{initial:l,animate:f}=e;const d=id(e),h=iv(e);t&&h&&!d&&e.inherit!==!1&&(l===void 0&&(l=t.initial),f===void 0&&(f=t.animate));let p=n?n.initial===!1:!1;p=p||l===!1;const g=p?f:l;if(g&&typeof g!="boolean"&&!rd(g)){const b=Array.isArray(g)?g:[g];for(let T=0;T<b.length;T++){const A=Tg(e,b[T]);if(A){const{transitionEnd:_,transition:O,...C}=A;for(const N in C){let R=C[N];if(Array.isArray(R)){const Y=p?R.length-1:0;R=R[Y]}R!==null&&(u[N]=R)}for(const N in _)u[N]=_[N]}}}return u}function Ag(e,t,n){const{style:i}=e,u={};for(const o in i)(Mn(i[o])||t.style&&Mn(t.style[o])||ov(o,e)||n?.getValue(o)?.liveStyle!==void 0)&&(u[o]=i[o]);return u}const Mk={useVisualState:hv({scrapeMotionValuesFromProps:Ag,createRenderState:yg})};function mv(e,t,n){const i=Ag(e,t,n);for(const u in e)if(Mn(e[u])||Mn(t[u])){const o=gs.indexOf(u)!==-1?"attr"+u.charAt(0).toUpperCase()+u.substring(1):u;i[o]=e[u]}return i}const Ik={useVisualState:hv({scrapeMotionValuesFromProps:mv,createRenderState:fv})};function Pk(e,t){return function(i,{forwardMotionProps:u}={forwardMotionProps:!1}){const l={...bg(i)?Ik:Mk,preloadedFeatures:e,useRender:Nk(u),createVisualElement:t,Component:i};return pk(l)}}function Al(e,t,n){const i=e.getProps();return Tg(i,t,n!==void 0?n:i.custom,e)}const Qp=e=>Array.isArray(e);function Fk(e,t,n){e.hasValue(t)?e.getValue(t).set(n):e.addValue(t,cs(n))}function Bk(e){return Qp(e)?e[e.length-1]||0:e}function Uk(e,t){const n=Al(e,t);let{transitionEnd:i={},transition:u={},...o}=n||{};o={...o,...i};for(const l in o){const f=Bk(o[l]);Fk(e,l,f)}}function Hk(e){return!!(Mn(e)&&e.add)}function $p(e,t){const n=e.getValue("willChange");if(Hk(n))return n.add(t);if(!n&&Hi.WillChange){const i=new Hi.WillChange("auto");e.addValue("willChange",i),i.add(t)}}function pv(e){return e.props[av]}const zk=e=>e!==null;function Vk(e,{repeat:t,repeatType:n="loop"},i){const u=e.filter(zk),o=t&&n!=="loop"&&t%2===1?0:u.length-1;return u[o]}const jk={type:"spring",stiffness:500,damping:25,restSpeed:10},qk=e=>({type:"spring",stiffness:550,damping:e===0?2*Math.sqrt(550):30,restSpeed:10}),Yk={type:"keyframes",duration:.8},Gk={type:"keyframes",ease:[.25,.1,.35,1],duration:.3},Xk=(e,{keyframes:t})=>t.length>2?Yk:Es.has(e)?e.startsWith("scale")?qk(t[1]):jk:Gk;function Kk({when:e,delay:t,delayChildren:n,staggerChildren:i,staggerDirection:u,repeat:o,repeatType:l,repeatDelay:f,from:d,elapsed:h,...p}){return!!Object.keys(p).length}const Sg=(e,t,n,i={},u,o)=>l=>{const f=lg(i,e)||{},d=f.delay||i.delay||0;let{elapsed:h=0}=i;h=h-pi(d);const p={keyframes:Array.isArray(n)?n:[null,n],ease:"easeOut",velocity:t.getVelocity(),...f,delay:-h,onUpdate:b=>{t.set(b),f.onUpdate&&f.onUpdate(b)},onComplete:()=>{l(),f.onComplete&&f.onComplete()},name:e,motionValue:t,element:o?void 0:u};Kk(f)||Object.assign(p,Xk(e,p)),p.duration&&(p.duration=pi(p.duration)),p.repeatDelay&&(p.repeatDelay=pi(p.repeatDelay)),p.from!==void 0&&(p.keyframes[0]=p.from);let g=!1;if((p.type===!1||p.duration===0&&!p.repeatDelay)&&(p.duration=0,p.delay===0&&(g=!0)),(Hi.instantAnimations||Hi.skipAnimations)&&(g=!0,p.duration=0,p.delay=0),p.allowFlatten=!f.type&&!f.ease,g&&!o&&t.get()!==void 0){const b=Vk(p.keyframes,f);if(b!==void 0){jt.update(()=>{p.onUpdate(b),p.onComplete()});return}}return f.isSync?new ug(p):new RN(p)};function Wk({protectedKeys:e,needsAnimating:t},n){const i=e.hasOwnProperty(n)&&t[n]!==!0;return t[n]=!1,i}function gv(e,t,{delay:n=0,transitionOverride:i,type:u}={}){let{transition:o=e.getDefaultTransition(),transitionEnd:l,...f}=t;i&&(o=i);const d=[],h=u&&e.animationState&&e.animationState.getState()[u];for(const p in f){const g=e.getValue(p,e.latestValues[p]??null),b=f[p];if(b===void 0||h&&Wk(h,p))continue;const T={delay:n,...lg(o||{},p)},A=g.get();if(A!==void 0&&!g.isAnimating&&!Array.isArray(b)&&b===A&&!T.velocity)continue;let _=!1;if(window.MotionHandoffAnimation){const C=pv(e);if(C){const N=window.MotionHandoffAnimation(C,p,jt);N!==null&&(T.startTime=N,_=!0)}}$p(e,p),g.start(Sg(p,g,b,e.shouldReduceMotion&&YD.has(p)?{type:!1}:T,e,_));const O=g.animation;O&&d.push(O)}return l&&Promise.all(d).then(()=>{jt.update(()=>{l&&Uk(e,l)})}),d}function Zp(e,t,n={}){const i=Al(e,t,n.type==="exit"?e.presenceContext?.custom:void 0);let{transition:u=e.getDefaultTransition()||{}}=i||{};n.transitionOverride&&(u=n.transitionOverride);const o=i?()=>Promise.all(gv(e,i,n)):()=>Promise.resolve(),l=e.variantChildren&&e.variantChildren.size?(d=0)=>{const{delayChildren:h=0,staggerChildren:p,staggerDirection:g}=u;return Qk(e,t,d,h,p,g,n)}:()=>Promise.resolve(),{when:f}=u;if(f){const[d,h]=f==="beforeChildren"?[o,l]:[l,o];return d().then(()=>h())}else return Promise.all([o(),l(n.delay)])}function Qk(e,t,n=0,i=0,u=0,o=1,l){const f=[],d=e.variantChildren.size,h=(d-1)*u,p=typeof i=="function",g=p?b=>i(b,d):o===1?(b=0)=>b*u:(b=0)=>h-b*u;return Array.from(e.variantChildren).sort($k).forEach((b,T)=>{b.notify("AnimationStart",t),f.push(Zp(b,t,{...l,delay:n+(p?0:i)+g(T)}).then(()=>b.notify("AnimationComplete",t)))}),Promise.all(f)}function $k(e,t){return e.sortNodePosition(t)}function Zk(e,t,n={}){e.notify("AnimationStart",t);let i;if(Array.isArray(t)){const u=t.map(o=>Zp(e,o,n));i=Promise.all(u)}else if(typeof t=="string")i=Zp(e,t,n);else{const u=typeof t=="function"?Al(e,t,n.custom):t;i=Promise.all(gv(e,u,n))}return i.then(()=>{e.notify("AnimationComplete",t)})}function Ev(e,t){if(!Array.isArray(t))return!1;const n=t.length;if(n!==e.length)return!1;for(let i=0;i<n;i++)if(t[i]!==e[i])return!1;return!0}const Jk=pg.length;function yv(e){if(!e)return;if(!e.isControllingVariants){const n=e.parent?yv(e.parent)||{}:{};return e.props.initial!==void 0&&(n.initial=e.props.initial),n}const t={};for(let n=0;n<Jk;n++){const i=pg[n],u=e.props[i];(bl(u)||u===!1)&&(t[i]=u)}return t}const eL=[...mg].reverse(),tL=mg.length;function nL(e){return t=>Promise.all(t.map(({animation:n,options:i})=>Zk(e,n,i)))}function rL(e){let t=nL(e),n=MT(),i=!0;const u=d=>(h,p)=>{const g=Al(e,p,d==="exit"?e.presenceContext?.custom:void 0);if(g){const{transition:b,transitionEnd:T,...A}=g;h={...h,...A,...T}}return h};function o(d){t=d(e)}function l(d){const{props:h}=e,p=yv(e.parent)||{},g=[],b=new Set;let T={},A=1/0;for(let O=0;O<tL;O++){const C=eL[O],N=n[C],R=h[C]!==void 0?h[C]:p[C],Y=bl(R),M=C===d?N.isActive:null;M===!1&&(A=O);let v=R===p[C]&&R!==h[C]&&Y;if(v&&i&&e.manuallyAnimateOnMount&&(v=!1),N.protectedKeys={...T},!N.isActive&&M===null||!R&&!N.prevProp||rd(R)||typeof R=="boolean")continue;const J=iL(N.prevProp,R);let P=J||C===d&&N.isActive&&!v&&Y||O>A&&Y,q=!1;const z=Array.isArray(R)?R:[R];let V=z.reduce(u(C),{});M===!1&&(V={});const{prevResolvedValues:F={}}=N,$={...F,...V},Z=K=>{P=!0,b.has(K)&&(q=!0,b.delete(K)),N.needsAnimating[K]=!0;const Q=e.getValue(K);Q&&(Q.liveStyle=!1)};for(const K in $){const Q=V[K],_e=F[K];if(T.hasOwnProperty(K))continue;let S=!1;Qp(Q)&&Qp(_e)?S=!Ev(Q,_e):S=Q!==_e,S?Q!=null?Z(K):b.add(K):Q!==void 0&&b.has(K)?Z(K):N.protectedKeys[K]=!0}N.prevProp=R,N.prevResolvedValues=V,N.isActive&&(T={...T,...V}),i&&e.blockInitialAnimation&&(P=!1),P&&(!(v&&J)||q)&&g.push(...z.map(K=>({animation:K,options:{type:C}})))}if(b.size){const O={};if(typeof h.initial!="boolean"){const C=Al(e,Array.isArray(h.initial)?h.initial[0]:h.initial);C&&C.transition&&(O.transition=C.transition)}b.forEach(C=>{const N=e.getBaseTarget(C),R=e.getValue(C);R&&(R.liveStyle=!0),O[C]=N??null}),g.push({animation:O})}let _=!!g.length;return i&&(h.initial===!1||h.initial===h.animate)&&!e.manuallyAnimateOnMount&&(_=!1),i=!1,_?t(g):Promise.resolve()}function f(d,h){if(n[d].isActive===h)return Promise.resolve();e.variantChildren?.forEach(g=>g.animationState?.setActive(d,h)),n[d].isActive=h;const p=l(d);for(const g in n)n[g].protectedKeys={};return p}return{animateChanges:l,setActive:f,setAnimateFunction:o,getState:()=>n,reset:()=>{n=MT(),i=!0}}}function iL(e,t){return typeof t=="string"?t!==e:Array.isArray(t)?!Ev(t,e):!1}function Ka(e=!1){return{isActive:e,protectedKeys:{},needsAnimating:{},prevResolvedValues:{}}}function MT(){return{animate:Ka(!0),whileInView:Ka(),whileHover:Ka(),whileTap:Ka(),whileDrag:Ka(),whileFocus:Ka(),exit:Ka()}}class Ra{constructor(t){this.isMounted=!1,this.node=t}update(){}}class aL extends Ra{constructor(t){super(t),t.animationState||(t.animationState=rL(t))}updateAnimationControlsSubscription(){const{animate:t}=this.node.getProps();rd(t)&&(this.unmountControls=t.subscribe(this.node))}mount(){this.updateAnimationControlsSubscription()}update(){const{animate:t}=this.node.getProps(),{animate:n}=this.node.prevProps||{};t!==n&&this.updateAnimationControlsSubscription()}unmount(){this.node.animationState.reset(),this.unmountControls?.()}}let uL=0;class sL extends Ra{constructor(){super(...arguments),this.id=uL++}update(){if(!this.node.presenceContext)return;const{isPresent:t,onExitComplete:n}=this.node.presenceContext,{isPresent:i}=this.node.prevPresenceContext||{};if(!this.node.animationState||t===i)return;const u=this.node.animationState.setActive("exit",!t);n&&!t&&u.then(()=>{n(this.id)})}mount(){const{register:t,onExitComplete:n}=this.node.presenceContext||{};n&&n(this.id),t&&(this.unmount=t(this.id))}unmount(){}}const oL={animation:{Feature:aL},exit:{Feature:sL}};function Sl(e,t,n,i={passive:!0}){return e.addEventListener(t,n,i),()=>e.removeEventListener(t,n)}function Ml(e){return{point:{x:e.pageX,y:e.pageY}}}const lL=e=>t=>dg(t)&&e(t,Ml(t));function rl(e,t,n,i){return Sl(e,t,lL(n),i)}function bv({top:e,left:t,right:n,bottom:i}){return{x:{min:t,max:n},y:{min:e,max:i}}}function cL({x:e,y:t}){return{top:t.min,right:e.max,bottom:t.max,left:e.min}}function fL(e,t){if(!t)return e;const n=t({x:e.left,y:e.top}),i=t({x:e.right,y:e.bottom});return{top:n.y,left:n.x,bottom:i.y,right:i.x}}const Tv=1e-4,dL=1-Tv,hL=1+Tv,Av=.01,mL=0-Av,pL=0+Av;function Vn(e){return e.max-e.min}function gL(e,t,n){return Math.abs(e-t)<=n}function IT(e,t,n,i=.5){e.origin=i,e.originPoint=Kt(t.min,t.max,e.origin),e.scale=Vn(n)/Vn(t),e.translate=Kt(n.min,n.max,e.origin)-e.originPoint,(e.scale>=dL&&e.scale<=hL||isNaN(e.scale))&&(e.scale=1),(e.translate>=mL&&e.translate<=pL||isNaN(e.translate))&&(e.translate=0)}function il(e,t,n,i){IT(e.x,t.x,n.x,i?i.originX:void 0),IT(e.y,t.y,n.y,i?i.originY:void 0)}function PT(e,t,n){e.min=n.min+t.min,e.max=e.min+Vn(t)}function EL(e,t,n){PT(e.x,t.x,n.x),PT(e.y,t.y,n.y)}function FT(e,t,n){e.min=t.min-n.min,e.max=e.min+Vn(t)}function al(e,t,n){FT(e.x,t.x,n.x),FT(e.y,t.y,n.y)}const BT=()=>({translate:0,scale:1,origin:0,originPoint:0}),rs=()=>({x:BT(),y:BT()}),UT=()=>({min:0,max:0}),un=()=>({x:UT(),y:UT()});function Mr(e){return[e("x"),e("y")]}function qm(e){return e===void 0||e===1}function Jp({scale:e,scaleX:t,scaleY:n}){return!qm(e)||!qm(t)||!qm(n)}function Ja(e){return Jp(e)||Sv(e)||e.z||e.rotate||e.rotateX||e.rotateY||e.skewX||e.skewY}function Sv(e){return HT(e.x)||HT(e.y)}function HT(e){return e&&e!=="0%"}function Vf(e,t,n){const i=e-n,u=t*i;return n+u}function zT(e,t,n,i,u){return u!==void 0&&(e=Vf(e,u,i)),Vf(e,n,i)+t}function e0(e,t=0,n=1,i,u){e.min=zT(e.min,t,n,i,u),e.max=zT(e.max,t,n,i,u)}function Dv(e,{x:t,y:n}){e0(e.x,t.translate,t.scale,t.originPoint),e0(e.y,n.translate,n.scale,n.originPoint)}const VT=.999999999999,jT=1.0000000000001;function yL(e,t,n,i=!1){const u=n.length;if(!u)return;t.x=t.y=1;let o,l;for(let f=0;f<u;f++){o=n[f],l=o.projectionDelta;const{visualElement:d}=o.options;d&&d.props.style&&d.props.style.display==="contents"||(i&&o.options.layoutScroll&&o.scroll&&o!==o.root&&as(e,{x:-o.scroll.offset.x,y:-o.scroll.offset.y}),l&&(t.x*=l.x.scale,t.y*=l.y.scale,Dv(e,l)),i&&Ja(o.latestValues)&&as(e,o.latestValues))}t.x<jT&&t.x>VT&&(t.x=1),t.y<jT&&t.y>VT&&(t.y=1)}function is(e,t){e.min=e.min+t,e.max=e.max+t}function qT(e,t,n,i,u=.5){const o=Kt(e.min,e.max,u);e0(e,t,n,o,i)}function as(e,t){qT(e.x,t.x,t.scaleX,t.scale,t.originX),qT(e.y,t.y,t.scaleY,t.scale,t.originY)}function vv(e,t){return bv(fL(e.getBoundingClientRect(),t))}function bL(e,t,n){const i=vv(e,n),{scroll:u}=t;return u&&(is(i.x,u.offset.x),is(i.y,u.offset.y)),i}const Cv=({current:e})=>e?e.ownerDocument.defaultView:null,YT=(e,t)=>Math.abs(e-t);function TL(e,t){const n=YT(e.x,t.x),i=YT(e.y,t.y);return Math.sqrt(n**2+i**2)}class _v{constructor(t,n,{transformPagePoint:i,contextWindow:u=window,dragSnapToOrigin:o=!1,distanceThreshold:l=3}={}){if(this.startEvent=null,this.lastMoveEvent=null,this.lastMoveEventInfo=null,this.handlers={},this.contextWindow=window,this.updatePoint=()=>{if(!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const b=Gm(this.lastMoveEventInfo,this.history),T=this.startEvent!==null,A=TL(b.offset,{x:0,y:0})>=this.distanceThreshold;if(!T&&!A)return;const{point:_}=b,{timestamp:O}=wn;this.history.push({..._,timestamp:O});const{onStart:C,onMove:N}=this.handlers;T||(C&&C(this.lastMoveEvent,b),this.startEvent=this.lastMoveEvent),N&&N(this.lastMoveEvent,b)},this.handlePointerMove=(b,T)=>{this.lastMoveEvent=b,this.lastMoveEventInfo=Ym(T,this.transformPagePoint),jt.update(this.updatePoint,!0)},this.handlePointerUp=(b,T)=>{this.end();const{onEnd:A,onSessionEnd:_,resumeAnimation:O}=this.handlers;if(this.dragSnapToOrigin&&O&&O(),!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const C=Gm(b.type==="pointercancel"?this.lastMoveEventInfo:Ym(T,this.transformPagePoint),this.history);this.startEvent&&A&&A(b,C),_&&_(b,C)},!dg(t))return;this.dragSnapToOrigin=o,this.handlers=n,this.transformPagePoint=i,this.distanceThreshold=l,this.contextWindow=u||window;const f=Ml(t),d=Ym(f,this.transformPagePoint),{point:h}=d,{timestamp:p}=wn;this.history=[{...h,timestamp:p}];const{onSessionStart:g}=n;g&&g(t,Gm(d,this.history)),this.removeListeners=Nl(rl(this.contextWindow,"pointermove",this.handlePointerMove),rl(this.contextWindow,"pointerup",this.handlePointerUp),rl(this.contextWindow,"pointercancel",this.handlePointerUp))}updateHandlers(t){this.handlers=t}end(){this.removeListeners&&this.removeListeners(),Sa(this.updatePoint)}}function Ym(e,t){return t?{point:t(e.point)}:e}function GT(e,t){return{x:e.x-t.x,y:e.y-t.y}}function Gm({point:e},t){return{point:e,delta:GT(e,xv(t)),offset:GT(e,AL(t)),velocity:SL(t,.1)}}function AL(e){return e[0]}function xv(e){return e[e.length-1]}function SL(e,t){if(e.length<2)return{x:0,y:0};let n=e.length-1,i=null;const u=xv(e);for(;n>=0&&(i=e[n],!(u.timestamp-i.timestamp>pi(t)));)n--;if(!i)return{x:0,y:0};const o=gi(u.timestamp-i.timestamp);if(o===0)return{x:0,y:0};const l={x:(u.x-i.x)/o,y:(u.y-i.y)/o};return l.x===1/0&&(l.x=0),l.y===1/0&&(l.y=0),l}function DL(e,{min:t,max:n},i){return t!==void 0&&e<t?e=i?Kt(t,e,i.min):Math.max(e,t):n!==void 0&&e>n&&(e=i?Kt(n,e,i.max):Math.min(e,n)),e}function XT(e,t,n){return{min:t!==void 0?e.min+t:void 0,max:n!==void 0?e.max+n-(e.max-e.min):void 0}}function vL(e,{top:t,left:n,bottom:i,right:u}){return{x:XT(e.x,n,u),y:XT(e.y,t,i)}}function KT(e,t){let n=t.min-e.min,i=t.max-e.max;return t.max-t.min<e.max-e.min&&([n,i]=[i,n]),{min:n,max:i}}function CL(e,t){return{x:KT(e.x,t.x),y:KT(e.y,t.y)}}function _L(e,t){let n=.5;const i=Vn(e),u=Vn(t);return u>i?n=gl(t.min,t.max-i,e.min):i>u&&(n=gl(e.min,e.max-u,t.min)),Ui(0,1,n)}function xL(e,t){const n={};return t.min!==void 0&&(n.min=t.min-e.min),t.max!==void 0&&(n.max=t.max-e.min),n}const t0=.35;function RL(e=t0){return e===!1?e=0:e===!0&&(e=t0),{x:WT(e,"left","right"),y:WT(e,"top","bottom")}}function WT(e,t,n){return{min:QT(e,t),max:QT(e,n)}}function QT(e,t){return typeof e=="number"?e:e[t]||0}const wL=new WeakMap;class OL{constructor(t){this.openDragLock=null,this.isDragging=!1,this.currentDirection=null,this.originPoint={x:0,y:0},this.constraints=!1,this.hasMutatedConstraints=!1,this.elastic=un(),this.latestPointerEvent=null,this.latestPanInfo=null,this.visualElement=t}start(t,{snapToCursor:n=!1,distanceThreshold:i}={}){const{presenceContext:u}=this.visualElement;if(u&&u.isPresent===!1)return;const o=g=>{const{dragSnapToOrigin:b}=this.getProps();b?this.pauseAnimation():this.stopAnimation(),n&&this.snapToCursor(Ml(g).point)},l=(g,b)=>{const{drag:T,dragPropagation:A,onDragStart:_}=this.getProps();if(T&&!A&&(this.openDragLock&&this.openDragLock(),this.openDragLock=qN(T),!this.openDragLock))return;this.latestPointerEvent=g,this.latestPanInfo=b,this.isDragging=!0,this.currentDirection=null,this.resolveConstraints(),this.visualElement.projection&&(this.visualElement.projection.isAnimationBlocked=!0,this.visualElement.projection.target=void 0),Mr(C=>{let N=this.getAxisMotionValue(C).get()||0;if(Ei.test(N)){const{projection:R}=this.visualElement;if(R&&R.layout){const Y=R.layout.layoutBox[C];Y&&(N=Vn(Y)*(parseFloat(N)/100))}}this.originPoint[C]=N}),_&&jt.postRender(()=>_(g,b)),$p(this.visualElement,"transform");const{animationState:O}=this.visualElement;O&&O.setActive("whileDrag",!0)},f=(g,b)=>{this.latestPointerEvent=g,this.latestPanInfo=b;const{dragPropagation:T,dragDirectionLock:A,onDirectionLock:_,onDrag:O}=this.getProps();if(!T&&!this.openDragLock)return;const{offset:C}=b;if(A&&this.currentDirection===null){this.currentDirection=NL(C),this.currentDirection!==null&&_&&_(this.currentDirection);return}this.updateAxis("x",b.point,C),this.updateAxis("y",b.point,C),this.visualElement.render(),O&&O(g,b)},d=(g,b)=>{this.latestPointerEvent=g,this.latestPanInfo=b,this.stop(g,b),this.latestPointerEvent=null,this.latestPanInfo=null},h=()=>Mr(g=>this.getAnimationState(g)==="paused"&&this.getAxisMotionValue(g).animation?.play()),{dragSnapToOrigin:p}=this.getProps();this.panSession=new _v(t,{onSessionStart:o,onStart:l,onMove:f,onSessionEnd:d,resumeAnimation:h},{transformPagePoint:this.visualElement.getTransformPagePoint(),dragSnapToOrigin:p,distanceThreshold:i,contextWindow:Cv(this.visualElement)})}stop(t,n){const i=t||this.latestPointerEvent,u=n||this.latestPanInfo,o=this.isDragging;if(this.cancel(),!o||!u||!i)return;const{velocity:l}=u;this.startAnimation(l);const{onDragEnd:f}=this.getProps();f&&jt.postRender(()=>f(i,u))}cancel(){this.isDragging=!1;const{projection:t,animationState:n}=this.visualElement;t&&(t.isAnimationBlocked=!1),this.panSession&&this.panSession.end(),this.panSession=void 0;const{dragPropagation:i}=this.getProps();!i&&this.openDragLock&&(this.openDragLock(),this.openDragLock=null),n&&n.setActive("whileDrag",!1)}updateAxis(t,n,i){const{drag:u}=this.getProps();if(!i||!rf(t,u,this.currentDirection))return;const o=this.getAxisMotionValue(t);let l=this.originPoint[t]+i[t];this.constraints&&this.constraints[t]&&(l=DL(l,this.constraints[t],this.elastic[t])),o.set(l)}resolveConstraints(){const{dragConstraints:t,dragElastic:n}=this.getProps(),i=this.visualElement.projection&&!this.visualElement.projection.layout?this.visualElement.projection.measure(!1):this.visualElement.projection?.layout,u=this.constraints;t&&ns(t)?this.constraints||(this.constraints=this.resolveRefConstraints()):t&&i?this.constraints=vL(i.layoutBox,t):this.constraints=!1,this.elastic=RL(n),u!==this.constraints&&i&&this.constraints&&!this.hasMutatedConstraints&&Mr(o=>{this.constraints!==!1&&this.getAxisMotionValue(o)&&(this.constraints[o]=xL(i.layoutBox[o],this.constraints[o]))})}resolveRefConstraints(){const{dragConstraints:t,onMeasureDragConstraints:n}=this.getProps();if(!t||!ns(t))return!1;const i=t.current,{projection:u}=this.visualElement;if(!u||!u.layout)return!1;const o=bL(i,u.root,this.visualElement.getTransformPagePoint());let l=CL(u.layout.layoutBox,o);if(n){const f=n(cL(l));this.hasMutatedConstraints=!!f,f&&(l=bv(f))}return l}startAnimation(t){const{drag:n,dragMomentum:i,dragElastic:u,dragTransition:o,dragSnapToOrigin:l,onDragTransitionEnd:f}=this.getProps(),d=this.constraints||{},h=Mr(p=>{if(!rf(p,n,this.currentDirection))return;let g=d&&d[p]||{};l&&(g={min:0,max:0});const b=u?200:1e6,T=u?40:1e7,A={type:"inertia",velocity:i?t[p]:0,bounceStiffness:b,bounceDamping:T,timeConstant:750,restDelta:1,restSpeed:10,...o,...g};return this.startAxisValueAnimation(p,A)});return Promise.all(h).then(f)}startAxisValueAnimation(t,n){const i=this.getAxisMotionValue(t);return $p(this.visualElement,t),i.start(Sg(t,i,0,n,this.visualElement,!1))}stopAnimation(){Mr(t=>this.getAxisMotionValue(t).stop())}pauseAnimation(){Mr(t=>this.getAxisMotionValue(t).animation?.pause())}getAnimationState(t){return this.getAxisMotionValue(t).animation?.state}getAxisMotionValue(t){const n=`_drag${t.toUpperCase()}`,i=this.visualElement.getProps(),u=i[n];return u||this.visualElement.getValue(t,(i.initial?i.initial[t]:void 0)||0)}snapToCursor(t){Mr(n=>{const{drag:i}=this.getProps();if(!rf(n,i,this.currentDirection))return;const{projection:u}=this.visualElement,o=this.getAxisMotionValue(n);if(u&&u.layout){const{min:l,max:f}=u.layout.layoutBox[n];o.set(t[n]-Kt(l,f,.5))}})}scalePositionWithinConstraints(){if(!this.visualElement.current)return;const{drag:t,dragConstraints:n}=this.getProps(),{projection:i}=this.visualElement;if(!ns(n)||!i||!this.constraints)return;this.stopAnimation();const u={x:0,y:0};Mr(l=>{const f=this.getAxisMotionValue(l);if(f&&this.constraints!==!1){const d=f.get();u[l]=_L({min:d,max:d},this.constraints[l])}});const{transformTemplate:o}=this.visualElement.getProps();this.visualElement.current.style.transform=o?o({},""):"none",i.root&&i.root.updateScroll(),i.updateLayout(),this.resolveConstraints(),Mr(l=>{if(!rf(l,t,null))return;const f=this.getAxisMotionValue(l),{min:d,max:h}=this.constraints[l];f.set(Kt(d,h,u[l]))})}addListeners(){if(!this.visualElement.current)return;wL.set(this.visualElement,this);const t=this.visualElement.current,n=rl(t,"pointerdown",d=>{const{drag:h,dragListener:p=!0}=this.getProps();h&&p&&this.start(d)}),i=()=>{const{dragConstraints:d}=this.getProps();ns(d)&&d.current&&(this.constraints=this.resolveRefConstraints())},{projection:u}=this.visualElement,o=u.addEventListener("measure",i);u&&!u.layout&&(u.root&&u.root.updateScroll(),u.updateLayout()),jt.read(i);const l=Sl(window,"resize",()=>this.scalePositionWithinConstraints()),f=u.addEventListener("didUpdate",({delta:d,hasLayoutChanged:h})=>{this.isDragging&&h&&(Mr(p=>{const g=this.getAxisMotionValue(p);g&&(this.originPoint[p]+=d[p].translate,g.set(g.get()+d[p].translate))}),this.visualElement.render())});return()=>{l(),n(),o(),f&&f()}}getProps(){const t=this.visualElement.getProps(),{drag:n=!1,dragDirectionLock:i=!1,dragPropagation:u=!1,dragConstraints:o=!1,dragElastic:l=t0,dragMomentum:f=!0}=t;return{...t,drag:n,dragDirectionLock:i,dragPropagation:u,dragConstraints:o,dragElastic:l,dragMomentum:f}}}function rf(e,t,n){return(t===!0||t===e)&&(n===null||n===e)}function NL(e,t=10){let n=null;return Math.abs(e.y)>t?n="y":Math.abs(e.x)>t&&(n="x"),n}class kL extends Ra{constructor(t){super(t),this.removeGroupControls=Ur,this.removeListeners=Ur,this.controls=new OL(t)}mount(){const{dragControls:t}=this.node.getProps();t&&(this.removeGroupControls=t.subscribe(this.controls)),this.removeListeners=this.controls.addListeners()||Ur}unmount(){this.removeGroupControls(),this.removeListeners()}}const $T=e=>(t,n)=>{e&&jt.postRender(()=>e(t,n))};class LL extends Ra{constructor(){super(...arguments),this.removePointerDownListener=Ur}onPointerDown(t){this.session=new _v(t,this.createPanHandlers(),{transformPagePoint:this.node.getTransformPagePoint(),contextWindow:Cv(this.node)})}createPanHandlers(){const{onPanSessionStart:t,onPanStart:n,onPan:i,onPanEnd:u}=this.node.getProps();return{onSessionStart:$T(t),onStart:$T(n),onMove:i,onEnd:(o,l)=>{delete this.session,u&&jt.postRender(()=>u(o,l))}}}mount(){this.removePointerDownListener=rl(this.node.current,"pointerdown",t=>this.onPointerDown(t))}update(){this.session&&this.session.updateHandlers(this.createPanHandlers())}unmount(){this.removePointerDownListener(),this.session&&this.session.end()}}const Cf={hasAnimatedSinceResize:!0,hasEverUpdated:!1};function ZT(e,t){return t.max===t.min?0:e/(t.max-t.min)*100}const Oo={correct:(e,t)=>{if(!t.target)return e;if(typeof e=="string")if(Ke.test(e))e=parseFloat(e);else return e;const n=ZT(e,t.target.x),i=ZT(e,t.target.y);return`${n}% ${i}%`}},ML={correct:(e,{treeScale:t,projectionDelta:n})=>{const i=e,u=Da.parse(e);if(u.length>5)return i;const o=Da.createTransformer(e),l=typeof u[0]!="number"?1:0,f=n.x.scale*t.x,d=n.y.scale*t.y;u[0+l]/=f,u[1+l]/=d;const h=Kt(f,d,.5);return typeof u[2+l]=="number"&&(u[2+l]/=h),typeof u[3+l]=="number"&&(u[3+l]/=h),o(u)}};let JT=!1;class IL extends W.Component{componentDidMount(){const{visualElement:t,layoutGroup:n,switchLayoutGroup:i,layoutId:u}=this.props,{projection:o}=t;bk(PL),o&&(n.group&&n.group.add(o),i&&i.register&&u&&i.register(o),JT&&o.root.didUpdate(),o.addEventListener("animationComplete",()=>{this.safeToRemove()}),o.setOptions({...o.options,onExitComplete:()=>this.safeToRemove()})),Cf.hasEverUpdated=!0}getSnapshotBeforeUpdate(t){const{layoutDependency:n,visualElement:i,drag:u,isPresent:o}=this.props,{projection:l}=i;return l&&(l.isPresent=o,JT=!0,u||t.layoutDependency!==n||n===void 0||t.isPresent!==o?l.willUpdate():this.safeToRemove(),t.isPresent!==o&&(o?l.promote():l.relegate()||jt.postRender(()=>{const f=l.getStack();(!f||!f.members.length)&&this.safeToRemove()}))),null}componentDidUpdate(){const{projection:t}=this.props.visualElement;t&&(t.root.didUpdate(),fg.postRender(()=>{!t.currentAnimation&&t.isLead()&&this.safeToRemove()}))}componentWillUnmount(){const{visualElement:t,layoutGroup:n,switchLayoutGroup:i}=this.props,{projection:u}=t;u&&(u.scheduleCheckAfterUnmount(),n&&n.group&&n.group.remove(u),i&&i.deregister&&i.deregister(u))}safeToRemove(){const{safeToRemove:t}=this.props;t&&t()}render(){return null}}function Rv(e){const[t,n]=tv(),i=W.useContext(V0);return Br.jsx(IL,{...e,layoutGroup:i,switchLayoutGroup:W.useContext(uv),isPresent:t,safeToRemove:n})}const PL={borderRadius:{...Oo,applyTo:["borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"]},borderTopLeftRadius:Oo,borderTopRightRadius:Oo,borderBottomLeftRadius:Oo,borderBottomRightRadius:Oo,boxShadow:ML};function FL(e,t,n){const i=Mn(e)?e:cs(e);return i.start(Sg("",i,t,n)),i.animation}const BL=(e,t)=>e.depth-t.depth;class UL{constructor(){this.children=[],this.isDirty=!1}add(t){Y0(this.children,t),this.isDirty=!0}remove(t){G0(this.children,t),this.isDirty=!0}forEach(t){this.isDirty&&this.children.sort(BL),this.isDirty=!1,this.children.forEach(t)}}function HL(e,t){const n=nr.now(),i=({timestamp:u})=>{const o=u-n;o>=t&&(Sa(i),e(o-t))};return jt.setup(i,!0),()=>Sa(i)}const wv=["TopLeft","TopRight","BottomLeft","BottomRight"],zL=wv.length,eA=e=>typeof e=="string"?parseFloat(e):e,tA=e=>typeof e=="number"||Ke.test(e);function VL(e,t,n,i,u,o){u?(e.opacity=Kt(0,n.opacity??1,jL(i)),e.opacityExit=Kt(t.opacity??1,0,qL(i))):o&&(e.opacity=Kt(t.opacity??1,n.opacity??1,i));for(let l=0;l<zL;l++){const f=`border${wv[l]}Radius`;let d=nA(t,f),h=nA(n,f);if(d===void 0&&h===void 0)continue;d||(d=0),h||(h=0),d===0||h===0||tA(d)===tA(h)?(e[f]=Math.max(Kt(eA(d),eA(h),i),0),(Ei.test(h)||Ei.test(d))&&(e[f]+="%")):e[f]=h}(t.rotate||n.rotate)&&(e.rotate=Kt(t.rotate||0,n.rotate||0,i))}function nA(e,t){return e[t]!==void 0?e[t]:e.borderRadius}const jL=Ov(0,.5,SD),qL=Ov(.5,.95,Ur);function Ov(e,t,n){return i=>i<e?0:i>t?1:n(gl(e,t,i))}function rA(e,t){e.min=t.min,e.max=t.max}function Lr(e,t){rA(e.x,t.x),rA(e.y,t.y)}function iA(e,t){e.translate=t.translate,e.scale=t.scale,e.originPoint=t.originPoint,e.origin=t.origin}function aA(e,t,n,i,u){return e-=t,e=Vf(e,1/n,i),u!==void 0&&(e=Vf(e,1/u,i)),e}function YL(e,t=0,n=1,i=.5,u,o=e,l=e){if(Ei.test(t)&&(t=parseFloat(t),t=Kt(l.min,l.max,t/100)-l.min),typeof t!="number")return;let f=Kt(o.min,o.max,i);e===o&&(f-=t),e.min=aA(e.min,t,n,f,u),e.max=aA(e.max,t,n,f,u)}function uA(e,t,[n,i,u],o,l){YL(e,t[n],t[i],t[u],t.scale,o,l)}const GL=["x","scaleX","originX"],XL=["y","scaleY","originY"];function sA(e,t,n,i){uA(e.x,t,GL,n?n.x:void 0,i?i.x:void 0),uA(e.y,t,XL,n?n.y:void 0,i?i.y:void 0)}function oA(e){return e.translate===0&&e.scale===1}function Nv(e){return oA(e.x)&&oA(e.y)}function lA(e,t){return e.min===t.min&&e.max===t.max}function KL(e,t){return lA(e.x,t.x)&&lA(e.y,t.y)}function cA(e,t){return Math.round(e.min)===Math.round(t.min)&&Math.round(e.max)===Math.round(t.max)}function kv(e,t){return cA(e.x,t.x)&&cA(e.y,t.y)}function fA(e){return Vn(e.x)/Vn(e.y)}function dA(e,t){return e.translate===t.translate&&e.scale===t.scale&&e.originPoint===t.originPoint}class WL{constructor(){this.members=[]}add(t){Y0(this.members,t),t.scheduleRender()}remove(t){if(G0(this.members,t),t===this.prevLead&&(this.prevLead=void 0),t===this.lead){const n=this.members[this.members.length-1];n&&this.promote(n)}}relegate(t){const n=this.members.findIndex(u=>t===u);if(n===0)return!1;let i;for(let u=n;u>=0;u--){const o=this.members[u];if(o.isPresent!==!1){i=o;break}}return i?(this.promote(i),!0):!1}promote(t,n){const i=this.lead;if(t!==i&&(this.prevLead=i,this.lead=t,t.show(),i)){i.instance&&i.scheduleRender(),t.scheduleRender(),t.resumeFrom=i,n&&(t.resumeFrom.preserveOpacity=!0),i.snapshot&&(t.snapshot=i.snapshot,t.snapshot.latestValues=i.animationValues||i.latestValues),t.root&&t.root.isUpdating&&(t.isLayoutDirty=!0);const{crossfade:u}=t.options;u===!1&&i.hide()}}exitAnimationComplete(){this.members.forEach(t=>{const{options:n,resumingFrom:i}=t;n.onExitComplete&&n.onExitComplete(),i&&i.options.onExitComplete&&i.options.onExitComplete()})}scheduleRender(){this.members.forEach(t=>{t.instance&&t.scheduleRender(!1)})}removeLeadSnapshot(){this.lead&&this.lead.snapshot&&(this.lead.snapshot=void 0)}}function QL(e,t,n){let i="";const u=e.x.translate/t.x,o=e.y.translate/t.y,l=n?.z||0;if((u||o||l)&&(i=`translate3d(${u}px, ${o}px, ${l}px) `),(t.x!==1||t.y!==1)&&(i+=`scale(${1/t.x}, ${1/t.y}) `),n){const{transformPerspective:h,rotate:p,rotateX:g,rotateY:b,skewX:T,skewY:A}=n;h&&(i=`perspective(${h}px) ${i}`),p&&(i+=`rotate(${p}deg) `),g&&(i+=`rotateX(${g}deg) `),b&&(i+=`rotateY(${b}deg) `),T&&(i+=`skewX(${T}deg) `),A&&(i+=`skewY(${A}deg) `)}const f=e.x.scale*t.x,d=e.y.scale*t.y;return(f!==1||d!==1)&&(i+=`scale(${f}, ${d})`),i||"none"}const Xm=["","X","Y","Z"],$L=1e3;let ZL=0;function Km(e,t,n,i){const{latestValues:u}=t;u[e]&&(n[e]=u[e],t.setStaticValue(e,0),i&&(i[e]=0))}function Lv(e){if(e.hasCheckedOptimisedAppear=!0,e.root===e)return;const{visualElement:t}=e.options;if(!t)return;const n=pv(t);if(window.MotionHasOptimisedAnimation(n,"transform")){const{layout:u,layoutId:o}=e.options;window.MotionCancelOptimisedAnimation(n,"transform",jt,!(u||o))}const{parent:i}=e;i&&!i.hasCheckedOptimisedAppear&&Lv(i)}function Mv({attachResizeListener:e,defaultParent:t,measureScroll:n,checkIsScrollRoot:i,resetTransform:u}){return class{constructor(l={},f=t?.()){this.id=ZL++,this.animationId=0,this.animationCommitId=0,this.children=new Set,this.options={},this.isTreeAnimating=!1,this.isAnimationBlocked=!1,this.isLayoutDirty=!1,this.isProjectionDirty=!1,this.isSharedProjectionDirty=!1,this.isTransformDirty=!1,this.updateManuallyBlocked=!1,this.updateBlockedByResize=!1,this.isUpdating=!1,this.isSVG=!1,this.needsReset=!1,this.shouldResetTransform=!1,this.hasCheckedOptimisedAppear=!1,this.treeScale={x:1,y:1},this.eventHandlers=new Map,this.hasTreeAnimated=!1,this.updateScheduled=!1,this.scheduleUpdate=()=>this.update(),this.projectionUpdateScheduled=!1,this.checkUpdateFailed=()=>{this.isUpdating&&(this.isUpdating=!1,this.clearAllSnapshots())},this.updateProjection=()=>{this.projectionUpdateScheduled=!1,this.nodes.forEach(t4),this.nodes.forEach(a4),this.nodes.forEach(u4),this.nodes.forEach(n4)},this.resolvedRelativeTargetAt=0,this.hasProjected=!1,this.isVisible=!0,this.animationProgress=0,this.sharedNodes=new Map,this.latestValues=l,this.root=f?f.root||f:this,this.path=f?[...f.path,f]:[],this.parent=f,this.depth=f?f.depth+1:0;for(let d=0;d<this.path.length;d++)this.path[d].shouldResetTransform=!0;this.root===this&&(this.nodes=new UL)}addEventListener(l,f){return this.eventHandlers.has(l)||this.eventHandlers.set(l,new W0),this.eventHandlers.get(l).add(f)}notifyListeners(l,...f){const d=this.eventHandlers.get(l);d&&d.notify(...f)}hasListeners(l){return this.eventHandlers.has(l)}mount(l){if(this.instance)return;this.isSVG=ev(l)&&!QN(l),this.instance=l;const{layoutId:f,layout:d,visualElement:h}=this.options;if(h&&!h.current&&h.mount(l),this.root.nodes.add(this),this.parent&&this.parent.children.add(this),this.root.hasTreeAnimated&&(d||f)&&(this.isLayoutDirty=!0),e){let p,g=0;const b=()=>this.root.updateBlockedByResize=!1;jt.read(()=>{g=window.innerWidth}),e(l,()=>{const T=window.innerWidth;T!==g&&(g=T,this.root.updateBlockedByResize=!0,p&&p(),p=HL(b,250),Cf.hasAnimatedSinceResize&&(Cf.hasAnimatedSinceResize=!1,this.nodes.forEach(pA)))})}f&&this.root.registerSharedNode(f,this),this.options.animate!==!1&&h&&(f||d)&&this.addEventListener("didUpdate",({delta:p,hasLayoutChanged:g,hasRelativeLayoutChanged:b,layout:T})=>{if(this.isTreeAnimationBlocked()){this.target=void 0,this.relativeTarget=void 0;return}const A=this.options.transition||h.getDefaultTransition()||f4,{onLayoutAnimationStart:_,onLayoutAnimationComplete:O}=h.getProps(),C=!this.targetLayout||!kv(this.targetLayout,T),N=!g&&b;if(this.options.layoutRoot||this.resumeFrom||N||g&&(C||!this.currentAnimation)){this.resumeFrom&&(this.resumingFrom=this.resumeFrom,this.resumingFrom.resumingFrom=void 0);const R={...lg(A,"layout"),onPlay:_,onComplete:O};(h.shouldReduceMotion||this.options.layoutRoot)&&(R.delay=0,R.type=!1),this.startAnimation(R),this.setAnimationOrigin(p,N)}else g||pA(this),this.isLead()&&this.options.onExitComplete&&this.options.onExitComplete();this.targetLayout=T})}unmount(){this.options.layoutId&&this.willUpdate(),this.root.nodes.remove(this);const l=this.getStack();l&&l.remove(this),this.parent&&this.parent.children.delete(this),this.instance=void 0,this.eventHandlers.clear(),Sa(this.updateProjection)}blockUpdate(){this.updateManuallyBlocked=!0}unblockUpdate(){this.updateManuallyBlocked=!1}isUpdateBlocked(){return this.updateManuallyBlocked||this.updateBlockedByResize}isTreeAnimationBlocked(){return this.isAnimationBlocked||this.parent&&this.parent.isTreeAnimationBlocked()||!1}startUpdate(){this.isUpdateBlocked()||(this.isUpdating=!0,this.nodes&&this.nodes.forEach(s4),this.animationId++)}getTransformTemplate(){const{visualElement:l}=this.options;return l&&l.getProps().transformTemplate}willUpdate(l=!0){if(this.root.hasTreeAnimated=!0,this.root.isUpdateBlocked()){this.options.onExitComplete&&this.options.onExitComplete();return}if(window.MotionCancelOptimisedAnimation&&!this.hasCheckedOptimisedAppear&&Lv(this),!this.root.isUpdating&&this.root.startUpdate(),this.isLayoutDirty)return;this.isLayoutDirty=!0;for(let p=0;p<this.path.length;p++){const g=this.path[p];g.shouldResetTransform=!0,g.updateScroll("snapshot"),g.options.layoutRoot&&g.willUpdate(!1)}const{layoutId:f,layout:d}=this.options;if(f===void 0&&!d)return;const h=this.getTransformTemplate();this.prevTransformTemplateValue=h?h(this.latestValues,""):void 0,this.updateSnapshot(),l&&this.notifyListeners("willUpdate")}update(){if(this.updateScheduled=!1,this.isUpdateBlocked()){this.unblockUpdate(),this.clearAllSnapshots(),this.nodes.forEach(hA);return}if(this.animationId<=this.animationCommitId){this.nodes.forEach(mA);return}this.animationCommitId=this.animationId,this.isUpdating?(this.isUpdating=!1,this.nodes.forEach(i4),this.nodes.forEach(JL),this.nodes.forEach(e4)):this.nodes.forEach(mA),this.clearAllSnapshots();const f=nr.now();wn.delta=Ui(0,1e3/60,f-wn.timestamp),wn.timestamp=f,wn.isProcessing=!0,Bm.update.process(wn),Bm.preRender.process(wn),Bm.render.process(wn),wn.isProcessing=!1}didUpdate(){this.updateScheduled||(this.updateScheduled=!0,fg.read(this.scheduleUpdate))}clearAllSnapshots(){this.nodes.forEach(r4),this.sharedNodes.forEach(o4)}scheduleUpdateProjection(){this.projectionUpdateScheduled||(this.projectionUpdateScheduled=!0,jt.preRender(this.updateProjection,!1,!0))}scheduleCheckAfterUnmount(){jt.postRender(()=>{this.isLayoutDirty?this.root.didUpdate():this.root.checkUpdateFailed()})}updateSnapshot(){this.snapshot||!this.instance||(this.snapshot=this.measure(),this.snapshot&&!Vn(this.snapshot.measuredBox.x)&&!Vn(this.snapshot.measuredBox.y)&&(this.snapshot=void 0))}updateLayout(){if(!this.instance||(this.updateScroll(),!(this.options.alwaysMeasureLayout&&this.isLead())&&!this.isLayoutDirty))return;if(this.resumeFrom&&!this.resumeFrom.instance)for(let d=0;d<this.path.length;d++)this.path[d].updateScroll();const l=this.layout;this.layout=this.measure(!1),this.layoutCorrected=un(),this.isLayoutDirty=!1,this.projectionDelta=void 0,this.notifyListeners("measure",this.layout.layoutBox);const{visualElement:f}=this.options;f&&f.notify("LayoutMeasure",this.layout.layoutBox,l?l.layoutBox:void 0)}updateScroll(l="measure"){let f=!!(this.options.layoutScroll&&this.instance);if(this.scroll&&this.scroll.animationId===this.root.animationId&&this.scroll.phase===l&&(f=!1),f&&this.instance){const d=i(this.instance);this.scroll={animationId:this.root.animationId,phase:l,isRoot:d,offset:n(this.instance),wasRoot:this.scroll?this.scroll.isRoot:d}}}resetTransform(){if(!u)return;const l=this.isLayoutDirty||this.shouldResetTransform||this.options.alwaysMeasureLayout,f=this.projectionDelta&&!Nv(this.projectionDelta),d=this.getTransformTemplate(),h=d?d(this.latestValues,""):void 0,p=h!==this.prevTransformTemplateValue;l&&this.instance&&(f||Ja(this.latestValues)||p)&&(u(this.instance,h),this.shouldResetTransform=!1,this.scheduleRender())}measure(l=!0){const f=this.measurePageBox();let d=this.removeElementScroll(f);return l&&(d=this.removeTransform(d)),d4(d),{animationId:this.root.animationId,measuredBox:f,layoutBox:d,latestValues:{},source:this.id}}measurePageBox(){const{visualElement:l}=this.options;if(!l)return un();const f=l.measureViewportBox();if(!(this.scroll?.wasRoot||this.path.some(h4))){const{scroll:h}=this.root;h&&(is(f.x,h.offset.x),is(f.y,h.offset.y))}return f}removeElementScroll(l){const f=un();if(Lr(f,l),this.scroll?.wasRoot)return f;for(let d=0;d<this.path.length;d++){const h=this.path[d],{scroll:p,options:g}=h;h!==this.root&&p&&g.layoutScroll&&(p.wasRoot&&Lr(f,l),is(f.x,p.offset.x),is(f.y,p.offset.y))}return f}applyTransform(l,f=!1){const d=un();Lr(d,l);for(let h=0;h<this.path.length;h++){const p=this.path[h];!f&&p.options.layoutScroll&&p.scroll&&p!==p.root&&as(d,{x:-p.scroll.offset.x,y:-p.scroll.offset.y}),Ja(p.latestValues)&&as(d,p.latestValues)}return Ja(this.latestValues)&&as(d,this.latestValues),d}removeTransform(l){const f=un();Lr(f,l);for(let d=0;d<this.path.length;d++){const h=this.path[d];if(!h.instance||!Ja(h.latestValues))continue;Jp(h.latestValues)&&h.updateSnapshot();const p=un(),g=h.measurePageBox();Lr(p,g),sA(f,h.latestValues,h.snapshot?h.snapshot.layoutBox:void 0,p)}return Ja(this.latestValues)&&sA(f,this.latestValues),f}setTargetDelta(l){this.targetDelta=l,this.root.scheduleUpdateProjection(),this.isProjectionDirty=!0}setOptions(l){this.options={...this.options,...l,crossfade:l.crossfade!==void 0?l.crossfade:!0}}clearMeasurements(){this.scroll=void 0,this.layout=void 0,this.snapshot=void 0,this.prevTransformTemplateValue=void 0,this.targetDelta=void 0,this.target=void 0,this.isLayoutDirty=!1}forceRelativeParentToResolveTarget(){this.relativeParent&&this.relativeParent.resolvedRelativeTargetAt!==wn.timestamp&&this.relativeParent.resolveTargetDelta(!0)}resolveTargetDelta(l=!1){const f=this.getLead();this.isProjectionDirty||(this.isProjectionDirty=f.isProjectionDirty),this.isTransformDirty||(this.isTransformDirty=f.isTransformDirty),this.isSharedProjectionDirty||(this.isSharedProjectionDirty=f.isSharedProjectionDirty);const d=!!this.resumingFrom||this!==f;if(!(l||d&&this.isSharedProjectionDirty||this.isProjectionDirty||this.parent?.isProjectionDirty||this.attemptToResolveRelativeTarget||this.root.updateBlockedByResize))return;const{layout:p,layoutId:g}=this.options;if(!(!this.layout||!(p||g))){if(this.resolvedRelativeTargetAt=wn.timestamp,!this.targetDelta&&!this.relativeTarget){const b=this.getClosestProjectingParent();b&&b.layout&&this.animationProgress!==1?(this.relativeParent=b,this.forceRelativeParentToResolveTarget(),this.relativeTarget=un(),this.relativeTargetOrigin=un(),al(this.relativeTargetOrigin,this.layout.layoutBox,b.layout.layoutBox),Lr(this.relativeTarget,this.relativeTargetOrigin)):this.relativeParent=this.relativeTarget=void 0}if(!(!this.relativeTarget&&!this.targetDelta)&&(this.target||(this.target=un(),this.targetWithTransforms=un()),this.relativeTarget&&this.relativeTargetOrigin&&this.relativeParent&&this.relativeParent.target?(this.forceRelativeParentToResolveTarget(),EL(this.target,this.relativeTarget,this.relativeParent.target)):this.targetDelta?(this.resumingFrom?this.target=this.applyTransform(this.layout.layoutBox):Lr(this.target,this.layout.layoutBox),Dv(this.target,this.targetDelta)):Lr(this.target,this.layout.layoutBox),this.attemptToResolveRelativeTarget)){this.attemptToResolveRelativeTarget=!1;const b=this.getClosestProjectingParent();b&&!!b.resumingFrom==!!this.resumingFrom&&!b.options.layoutScroll&&b.target&&this.animationProgress!==1?(this.relativeParent=b,this.forceRelativeParentToResolveTarget(),this.relativeTarget=un(),this.relativeTargetOrigin=un(),al(this.relativeTargetOrigin,this.target,b.target),Lr(this.relativeTarget,this.relativeTargetOrigin)):this.relativeParent=this.relativeTarget=void 0}}}getClosestProjectingParent(){if(!(!this.parent||Jp(this.parent.latestValues)||Sv(this.parent.latestValues)))return this.parent.isProjecting()?this.parent:this.parent.getClosestProjectingParent()}isProjecting(){return!!((this.relativeTarget||this.targetDelta||this.options.layoutRoot)&&this.layout)}calcProjection(){const l=this.getLead(),f=!!this.resumingFrom||this!==l;let d=!0;if((this.isProjectionDirty||this.parent?.isProjectionDirty)&&(d=!1),f&&(this.isSharedProjectionDirty||this.isTransformDirty)&&(d=!1),this.resolvedRelativeTargetAt===wn.timestamp&&(d=!1),d)return;const{layout:h,layoutId:p}=this.options;if(this.isTreeAnimating=!!(this.parent&&this.parent.isTreeAnimating||this.currentAnimation||this.pendingAnimation),this.isTreeAnimating||(this.targetDelta=this.relativeTarget=void 0),!this.layout||!(h||p))return;Lr(this.layoutCorrected,this.layout.layoutBox);const g=this.treeScale.x,b=this.treeScale.y;yL(this.layoutCorrected,this.treeScale,this.path,f),l.layout&&!l.target&&(this.treeScale.x!==1||this.treeScale.y!==1)&&(l.target=l.layout.layoutBox,l.targetWithTransforms=un());const{target:T}=l;if(!T){this.prevProjectionDelta&&(this.createProjectionDeltas(),this.scheduleRender());return}!this.projectionDelta||!this.prevProjectionDelta?this.createProjectionDeltas():(iA(this.prevProjectionDelta.x,this.projectionDelta.x),iA(this.prevProjectionDelta.y,this.projectionDelta.y)),il(this.projectionDelta,this.layoutCorrected,T,this.latestValues),(this.treeScale.x!==g||this.treeScale.y!==b||!dA(this.projectionDelta.x,this.prevProjectionDelta.x)||!dA(this.projectionDelta.y,this.prevProjectionDelta.y))&&(this.hasProjected=!0,this.scheduleRender(),this.notifyListeners("projectionUpdate",T))}hide(){this.isVisible=!1}show(){this.isVisible=!0}scheduleRender(l=!0){if(this.options.visualElement?.scheduleRender(),l){const f=this.getStack();f&&f.scheduleRender()}this.resumingFrom&&!this.resumingFrom.instance&&(this.resumingFrom=void 0)}createProjectionDeltas(){this.prevProjectionDelta=rs(),this.projectionDelta=rs(),this.projectionDeltaWithTransform=rs()}setAnimationOrigin(l,f=!1){const d=this.snapshot,h=d?d.latestValues:{},p={...this.latestValues},g=rs();(!this.relativeParent||!this.relativeParent.options.layoutRoot)&&(this.relativeTarget=this.relativeTargetOrigin=void 0),this.attemptToResolveRelativeTarget=!f;const b=un(),T=d?d.source:void 0,A=this.layout?this.layout.source:void 0,_=T!==A,O=this.getStack(),C=!O||O.members.length<=1,N=!!(_&&!C&&this.options.crossfade===!0&&!this.path.some(c4));this.animationProgress=0;let R;this.mixTargetDelta=Y=>{const M=Y/1e3;gA(g.x,l.x,M),gA(g.y,l.y,M),this.setTargetDelta(g),this.relativeTarget&&this.relativeTargetOrigin&&this.layout&&this.relativeParent&&this.relativeParent.layout&&(al(b,this.layout.layoutBox,this.relativeParent.layout.layoutBox),l4(this.relativeTarget,this.relativeTargetOrigin,b,M),R&&KL(this.relativeTarget,R)&&(this.isProjectionDirty=!1),R||(R=un()),Lr(R,this.relativeTarget)),_&&(this.animationValues=p,VL(p,h,this.latestValues,M,N,C)),this.root.scheduleUpdateProjection(),this.scheduleRender(),this.animationProgress=M},this.mixTargetDelta(this.options.layoutRoot?1e3:0)}startAnimation(l){this.notifyListeners("animationStart"),this.currentAnimation?.stop(),this.resumingFrom?.currentAnimation?.stop(),this.pendingAnimation&&(Sa(this.pendingAnimation),this.pendingAnimation=void 0),this.pendingAnimation=jt.update(()=>{Cf.hasAnimatedSinceResize=!0,this.motionValue||(this.motionValue=cs(0)),this.currentAnimation=FL(this.motionValue,[0,1e3],{...l,velocity:0,isSync:!0,onUpdate:f=>{this.mixTargetDelta(f),l.onUpdate&&l.onUpdate(f)},onStop:()=>{},onComplete:()=>{l.onComplete&&l.onComplete(),this.completeAnimation()}}),this.resumingFrom&&(this.resumingFrom.currentAnimation=this.currentAnimation),this.pendingAnimation=void 0})}completeAnimation(){this.resumingFrom&&(this.resumingFrom.currentAnimation=void 0,this.resumingFrom.preserveOpacity=void 0);const l=this.getStack();l&&l.exitAnimationComplete(),this.resumingFrom=this.currentAnimation=this.animationValues=void 0,this.notifyListeners("animationComplete")}finishAnimation(){this.currentAnimation&&(this.mixTargetDelta&&this.mixTargetDelta($L),this.currentAnimation.stop()),this.completeAnimation()}applyTransformsToTarget(){const l=this.getLead();let{targetWithTransforms:f,target:d,layout:h,latestValues:p}=l;if(!(!f||!d||!h)){if(this!==l&&this.layout&&h&&Iv(this.options.animationType,this.layout.layoutBox,h.layoutBox)){d=this.target||un();const g=Vn(this.layout.layoutBox.x);d.x.min=l.target.x.min,d.x.max=d.x.min+g;const b=Vn(this.layout.layoutBox.y);d.y.min=l.target.y.min,d.y.max=d.y.min+b}Lr(f,d),as(f,p),il(this.projectionDeltaWithTransform,this.layoutCorrected,f,p)}}registerSharedNode(l,f){this.sharedNodes.has(l)||this.sharedNodes.set(l,new WL),this.sharedNodes.get(l).add(f);const h=f.options.initialPromotionConfig;f.promote({transition:h?h.transition:void 0,preserveFollowOpacity:h&&h.shouldPreserveFollowOpacity?h.shouldPreserveFollowOpacity(f):void 0})}isLead(){const l=this.getStack();return l?l.lead===this:!0}getLead(){const{layoutId:l}=this.options;return l?this.getStack()?.lead||this:this}getPrevLead(){const{layoutId:l}=this.options;return l?this.getStack()?.prevLead:void 0}getStack(){const{layoutId:l}=this.options;if(l)return this.root.sharedNodes.get(l)}promote({needsReset:l,transition:f,preserveFollowOpacity:d}={}){const h=this.getStack();h&&h.promote(this,d),l&&(this.projectionDelta=void 0,this.needsReset=!0),f&&this.setOptions({transition:f})}relegate(){const l=this.getStack();return l?l.relegate(this):!1}resetSkewAndRotation(){const{visualElement:l}=this.options;if(!l)return;let f=!1;const{latestValues:d}=l;if((d.z||d.rotate||d.rotateX||d.rotateY||d.rotateZ||d.skewX||d.skewY)&&(f=!0),!f)return;const h={};d.z&&Km("z",l,h,this.animationValues);for(let p=0;p<Xm.length;p++)Km(`rotate${Xm[p]}`,l,h,this.animationValues),Km(`skew${Xm[p]}`,l,h,this.animationValues);l.render();for(const p in h)l.setStaticValue(p,h[p]),this.animationValues&&(this.animationValues[p]=h[p]);l.scheduleRender()}applyProjectionStyles(l,f){if(!this.instance||this.isSVG)return;if(!this.isVisible){l.visibility="hidden";return}const d=this.getTransformTemplate();if(this.needsReset){this.needsReset=!1,l.visibility="",l.opacity="",l.pointerEvents=vf(f?.pointerEvents)||"",l.transform=d?d(this.latestValues,""):"none";return}const h=this.getLead();if(!this.projectionDelta||!this.layout||!h.target){this.options.layoutId&&(l.opacity=this.latestValues.opacity!==void 0?this.latestValues.opacity:1,l.pointerEvents=vf(f?.pointerEvents)||""),this.hasProjected&&!Ja(this.latestValues)&&(l.transform=d?d({},""):"none",this.hasProjected=!1);return}l.visibility="";const p=h.animationValues||h.latestValues;this.applyTransformsToTarget();let g=QL(this.projectionDeltaWithTransform,this.treeScale,p);d&&(g=d(p,g)),l.transform=g;const{x:b,y:T}=this.projectionDelta;l.transformOrigin=`${b.origin*100}% ${T.origin*100}% 0`,h.animationValues?l.opacity=h===this?p.opacity??this.latestValues.opacity??1:this.preserveOpacity?this.latestValues.opacity:p.opacityExit:l.opacity=h===this?p.opacity!==void 0?p.opacity:"":p.opacityExit!==void 0?p.opacityExit:0;for(const A in Tl){if(p[A]===void 0)continue;const{correct:_,applyTo:O,isCSSVariable:C}=Tl[A],N=g==="none"?p[A]:_(p[A],h);if(O){const R=O.length;for(let Y=0;Y<R;Y++)l[O[Y]]=N}else C?this.options.visualElement.renderState.vars[A]=N:l[A]=N}this.options.layoutId&&(l.pointerEvents=h===this?vf(f?.pointerEvents)||"":"none")}clearSnapshot(){this.resumeFrom=this.snapshot=void 0}resetTree(){this.root.nodes.forEach(l=>l.currentAnimation?.stop()),this.root.nodes.forEach(hA),this.root.sharedNodes.clear()}}}function JL(e){e.updateLayout()}function e4(e){const t=e.resumeFrom?.snapshot||e.snapshot;if(e.isLead()&&e.layout&&t&&e.hasListeners("didUpdate")){const{layoutBox:n,measuredBox:i}=e.layout,{animationType:u}=e.options,o=t.source!==e.layout.source;u==="size"?Mr(p=>{const g=o?t.measuredBox[p]:t.layoutBox[p],b=Vn(g);g.min=n[p].min,g.max=g.min+b}):Iv(u,t.layoutBox,n)&&Mr(p=>{const g=o?t.measuredBox[p]:t.layoutBox[p],b=Vn(n[p]);g.max=g.min+b,e.relativeTarget&&!e.currentAnimation&&(e.isProjectionDirty=!0,e.relativeTarget[p].max=e.relativeTarget[p].min+b)});const l=rs();il(l,n,t.layoutBox);const f=rs();o?il(f,e.applyTransform(i,!0),t.measuredBox):il(f,n,t.layoutBox);const d=!Nv(l);let h=!1;if(!e.resumeFrom){const p=e.getClosestProjectingParent();if(p&&!p.resumeFrom){const{snapshot:g,layout:b}=p;if(g&&b){const T=un();al(T,t.layoutBox,g.layoutBox);const A=un();al(A,n,b.layoutBox),kv(T,A)||(h=!0),p.options.layoutRoot&&(e.relativeTarget=A,e.relativeTargetOrigin=T,e.relativeParent=p)}}}e.notifyListeners("didUpdate",{layout:n,snapshot:t,delta:f,layoutDelta:l,hasLayoutChanged:d,hasRelativeLayoutChanged:h})}else if(e.isLead()){const{onExitComplete:n}=e.options;n&&n()}e.options.transition=void 0}function t4(e){e.parent&&(e.isProjecting()||(e.isProjectionDirty=e.parent.isProjectionDirty),e.isSharedProjectionDirty||(e.isSharedProjectionDirty=!!(e.isProjectionDirty||e.parent.isProjectionDirty||e.parent.isSharedProjectionDirty)),e.isTransformDirty||(e.isTransformDirty=e.parent.isTransformDirty))}function n4(e){e.isProjectionDirty=e.isSharedProjectionDirty=e.isTransformDirty=!1}function r4(e){e.clearSnapshot()}function hA(e){e.clearMeasurements()}function mA(e){e.isLayoutDirty=!1}function i4(e){const{visualElement:t}=e.options;t&&t.getProps().onBeforeLayoutMeasure&&t.notify("BeforeLayoutMeasure"),e.resetTransform()}function pA(e){e.finishAnimation(),e.targetDelta=e.relativeTarget=e.target=void 0,e.isProjectionDirty=!0}function a4(e){e.resolveTargetDelta()}function u4(e){e.calcProjection()}function s4(e){e.resetSkewAndRotation()}function o4(e){e.removeLeadSnapshot()}function gA(e,t,n){e.translate=Kt(t.translate,0,n),e.scale=Kt(t.scale,1,n),e.origin=t.origin,e.originPoint=t.originPoint}function EA(e,t,n,i){e.min=Kt(t.min,n.min,i),e.max=Kt(t.max,n.max,i)}function l4(e,t,n,i){EA(e.x,t.x,n.x,i),EA(e.y,t.y,n.y,i)}function c4(e){return e.animationValues&&e.animationValues.opacityExit!==void 0}const f4={duration:.45,ease:[.4,0,.1,1]},yA=e=>typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().includes(e),bA=yA("applewebkit/")&&!yA("chrome/")?Math.round:Ur;function TA(e){e.min=bA(e.min),e.max=bA(e.max)}function d4(e){TA(e.x),TA(e.y)}function Iv(e,t,n){return e==="position"||e==="preserve-aspect"&&!gL(fA(t),fA(n),.2)}function h4(e){return e!==e.root&&e.scroll?.wasRoot}const m4=Mv({attachResizeListener:(e,t)=>Sl(e,"resize",t),measureScroll:()=>({x:document.documentElement.scrollLeft||document.body.scrollLeft,y:document.documentElement.scrollTop||document.body.scrollTop}),checkIsScrollRoot:()=>!0}),Wm={current:void 0},Pv=Mv({measureScroll:e=>({x:e.scrollLeft,y:e.scrollTop}),defaultParent:()=>{if(!Wm.current){const e=new m4({});e.mount(window),e.setOptions({layoutScroll:!0}),Wm.current=e}return Wm.current},resetTransform:(e,t)=>{e.style.transform=t!==void 0?t:"none"},checkIsScrollRoot:e=>window.getComputedStyle(e).position==="fixed"}),p4={pan:{Feature:LL},drag:{Feature:kL,ProjectionNode:Pv,MeasureLayout:Rv}};function AA(e,t,n){const{props:i}=e;e.animationState&&i.whileHover&&e.animationState.setActive("whileHover",n==="Start");const u="onHover"+n,o=i[u];o&&jt.postRender(()=>o(t,Ml(t)))}class g4 extends Ra{mount(){const{current:t}=this.node;t&&(this.unmount=YN(t,(n,i)=>(AA(this.node,i,"Start"),u=>AA(this.node,u,"End"))))}unmount(){}}class E4 extends Ra{constructor(){super(...arguments),this.isActive=!1}onFocus(){let t=!1;try{t=this.node.current.matches(":focus-visible")}catch{t=!0}!t||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!0),this.isActive=!0)}onBlur(){!this.isActive||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!1),this.isActive=!1)}mount(){this.unmount=Nl(Sl(this.node.current,"focus",()=>this.onFocus()),Sl(this.node.current,"blur",()=>this.onBlur()))}unmount(){}}function SA(e,t,n){const{props:i}=e;if(e.current instanceof HTMLButtonElement&&e.current.disabled)return;e.animationState&&i.whileTap&&e.animationState.setActive("whileTap",n==="Start");const u="onTap"+(n==="End"?"":n),o=i[u];o&&jt.postRender(()=>o(t,Ml(t)))}class y4 extends Ra{mount(){const{current:t}=this.node;t&&(this.unmount=WN(t,(n,i)=>(SA(this.node,i,"Start"),(u,{success:o})=>SA(this.node,u,o?"End":"Cancel")),{useGlobalTarget:this.node.props.globalTapTarget}))}unmount(){}}const n0=new WeakMap,Qm=new WeakMap,b4=e=>{const t=n0.get(e.target);t&&t(e)},T4=e=>{e.forEach(b4)};function A4({root:e,...t}){const n=e||document;Qm.has(n)||Qm.set(n,{});const i=Qm.get(n),u=JSON.stringify(t);return i[u]||(i[u]=new IntersectionObserver(T4,{root:e,...t})),i[u]}function S4(e,t,n){const i=A4(t);return n0.set(e,n),i.observe(e),()=>{n0.delete(e),i.unobserve(e)}}const D4={some:0,all:1};class v4 extends Ra{constructor(){super(...arguments),this.hasEnteredView=!1,this.isInView=!1}startObserver(){this.unmount();const{viewport:t={}}=this.node.getProps(),{root:n,margin:i,amount:u="some",once:o}=t,l={root:n?n.current:void 0,rootMargin:i,threshold:typeof u=="number"?u:D4[u]},f=d=>{const{isIntersecting:h}=d;if(this.isInView===h||(this.isInView=h,o&&!h&&this.hasEnteredView))return;h&&(this.hasEnteredView=!0),this.node.animationState&&this.node.animationState.setActive("whileInView",h);const{onViewportEnter:p,onViewportLeave:g}=this.node.getProps(),b=h?p:g;b&&b(d)};return S4(this.node.current,l,f)}mount(){this.startObserver()}update(){if(typeof IntersectionObserver>"u")return;const{props:t,prevProps:n}=this.node;["amount","margin","root"].some(C4(t,n))&&this.startObserver()}unmount(){}}function C4({viewport:e={}},{viewport:t={}}={}){return n=>e[n]!==t[n]}const _4={inView:{Feature:v4},tap:{Feature:y4},focus:{Feature:E4},hover:{Feature:g4}},x4={layout:{ProjectionNode:Pv,MeasureLayout:Rv}},r0={current:null},Fv={current:!1};function R4(){if(Fv.current=!0,!!q0)if(window.matchMedia){const e=window.matchMedia("(prefers-reduced-motion)"),t=()=>r0.current=e.matches;e.addEventListener("change",t),t()}else r0.current=!1}const w4=new WeakMap;function O4(e,t,n){for(const i in t){const u=t[i],o=n[i];if(Mn(u))e.addValue(i,u);else if(Mn(o))e.addValue(i,cs(u,{owner:e}));else if(o!==u)if(e.hasValue(i)){const l=e.getValue(i);l.liveStyle===!0?l.jump(u):l.hasAnimated||l.set(u)}else{const l=e.getStaticValue(i);e.addValue(i,cs(l!==void 0?l:u,{owner:e}))}}for(const i in n)t[i]===void 0&&e.removeValue(i);return t}const DA=["AnimationStart","AnimationComplete","Update","BeforeLayoutMeasure","LayoutMeasure","LayoutAnimationStart","LayoutAnimationComplete"];class N4{scrapeMotionValuesFromProps(t,n,i){return{}}constructor({parent:t,props:n,presenceContext:i,reducedMotionConfig:u,blockInitialAnimation:o,visualState:l},f={}){this.current=null,this.children=new Set,this.isVariantNode=!1,this.isControllingVariants=!1,this.shouldReduceMotion=null,this.values=new Map,this.KeyframeResolver=sg,this.features={},this.valueSubscriptions=new Map,this.prevMotionValues={},this.events={},this.propEventSubscriptions={},this.notifyUpdate=()=>this.notify("Update",this.latestValues),this.render=()=>{this.current&&(this.triggerBuild(),this.renderInstance(this.current,this.renderState,this.props.style,this.projection))},this.renderScheduledAt=0,this.scheduleRender=()=>{const b=nr.now();this.renderScheduledAt<b&&(this.renderScheduledAt=b,jt.render(this.render,!1,!0))};const{latestValues:d,renderState:h}=l;this.latestValues=d,this.baseTarget={...d},this.initialValues=n.initial?{...d}:{},this.renderState=h,this.parent=t,this.props=n,this.presenceContext=i,this.depth=t?t.depth+1:0,this.reducedMotionConfig=u,this.options=f,this.blockInitialAnimation=!!o,this.isControllingVariants=id(n),this.isVariantNode=iv(n),this.isVariantNode&&(this.variantChildren=new Set),this.manuallyAnimateOnMount=!!(t&&t.current);const{willChange:p,...g}=this.scrapeMotionValuesFromProps(n,{},this);for(const b in g){const T=g[b];d[b]!==void 0&&Mn(T)&&T.set(d[b],!1)}}mount(t){this.current=t,w4.set(t,this),this.projection&&!this.projection.instance&&this.projection.mount(t),this.parent&&this.isVariantNode&&!this.isControllingVariants&&(this.removeFromVariantTree=this.parent.addVariantChild(this)),this.values.forEach((n,i)=>this.bindToMotionValue(i,n)),Fv.current||R4(),this.shouldReduceMotion=this.reducedMotionConfig==="never"?!1:this.reducedMotionConfig==="always"?!0:r0.current,this.parent&&this.parent.children.add(this),this.update(this.props,this.presenceContext)}unmount(){this.projection&&this.projection.unmount(),Sa(this.notifyUpdate),Sa(this.render),this.valueSubscriptions.forEach(t=>t()),this.valueSubscriptions.clear(),this.removeFromVariantTree&&this.removeFromVariantTree(),this.parent&&this.parent.children.delete(this);for(const t in this.events)this.events[t].clear();for(const t in this.features){const n=this.features[t];n&&(n.unmount(),n.isMounted=!1)}this.current=null}bindToMotionValue(t,n){this.valueSubscriptions.has(t)&&this.valueSubscriptions.get(t)();const i=Es.has(t);i&&this.onBindTransform&&this.onBindTransform();const u=n.on("change",f=>{this.latestValues[t]=f,this.props.onUpdate&&jt.preRender(this.notifyUpdate),i&&this.projection&&(this.projection.isTransformDirty=!0)}),o=n.on("renderRequest",this.scheduleRender);let l;window.MotionCheckAppearSync&&(l=window.MotionCheckAppearSync(this,t,n)),this.valueSubscriptions.set(t,()=>{u(),o(),l&&l(),n.owner&&n.stop()})}sortNodePosition(t){return!this.current||!this.sortInstanceNodePosition||this.type!==t.type?0:this.sortInstanceNodePosition(this.current,t.current)}updateFeatures(){let t="animation";for(t in fs){const n=fs[t];if(!n)continue;const{isEnabled:i,Feature:u}=n;if(!this.features[t]&&u&&i(this.props)&&(this.features[t]=new u(this)),this.features[t]){const o=this.features[t];o.isMounted?o.update():(o.mount(),o.isMounted=!0)}}}triggerBuild(){this.build(this.renderState,this.latestValues,this.props)}measureViewportBox(){return this.current?this.measureInstanceViewportBox(this.current,this.props):un()}getStaticValue(t){return this.latestValues[t]}setStaticValue(t,n){this.latestValues[t]=n}update(t,n){(t.transformTemplate||this.props.transformTemplate)&&this.scheduleRender(),this.prevProps=this.props,this.props=t,this.prevPresenceContext=this.presenceContext,this.presenceContext=n;for(let i=0;i<DA.length;i++){const u=DA[i];this.propEventSubscriptions[u]&&(this.propEventSubscriptions[u](),delete this.propEventSubscriptions[u]);const o="on"+u,l=t[o];l&&(this.propEventSubscriptions[u]=this.on(u,l))}this.prevMotionValues=O4(this,this.scrapeMotionValuesFromProps(t,this.prevProps,this),this.prevMotionValues),this.handleChildMotionValue&&this.handleChildMotionValue()}getProps(){return this.props}getVariant(t){return this.props.variants?this.props.variants[t]:void 0}getDefaultTransition(){return this.props.transition}getTransformPagePoint(){return this.props.transformPagePoint}getClosestVariantNode(){return this.isVariantNode?this:this.parent?this.parent.getClosestVariantNode():void 0}addVariantChild(t){const n=this.getClosestVariantNode();if(n)return n.variantChildren&&n.variantChildren.add(t),()=>n.variantChildren.delete(t)}addValue(t,n){const i=this.values.get(t);n!==i&&(i&&this.removeValue(t),this.bindToMotionValue(t,n),this.values.set(t,n),this.latestValues[t]=n.get())}removeValue(t){this.values.delete(t);const n=this.valueSubscriptions.get(t);n&&(n(),this.valueSubscriptions.delete(t)),delete this.latestValues[t],this.removeValueFromRenderState(t,this.renderState)}hasValue(t){return this.values.has(t)}getValue(t,n){if(this.props.values&&this.props.values[t])return this.props.values[t];let i=this.values.get(t);return i===void 0&&n!==void 0&&(i=cs(n===null?void 0:n,{owner:this}),this.addValue(t,i)),i}readValue(t,n){let i=this.latestValues[t]!==void 0||!this.current?this.latestValues[t]:this.getBaseTargetFromProps(this.props,t)??this.readValueFromInstance(this.current,t,this.options);return i!=null&&(typeof i=="string"&&(dD(i)||mD(i))?i=parseFloat(i):!ZN(i)&&Da.test(n)&&(i=WD(t,n)),this.setBaseTarget(t,Mn(i)?i.get():i)),Mn(i)?i.get():i}setBaseTarget(t,n){this.baseTarget[t]=n}getBaseTarget(t){const{initial:n}=this.props;let i;if(typeof n=="string"||typeof n=="object"){const o=Tg(this.props,n,this.presenceContext?.custom);o&&(i=o[t])}if(n&&i!==void 0)return i;const u=this.getBaseTargetFromProps(this.props,t);return u!==void 0&&!Mn(u)?u:this.initialValues[t]!==void 0&&i===void 0?void 0:this.baseTarget[t]}on(t,n){return this.events[t]||(this.events[t]=new W0),this.events[t].add(n)}notify(t,...n){this.events[t]&&this.events[t].notify(...n)}}class Bv extends N4{constructor(){super(...arguments),this.KeyframeResolver=HN}sortInstanceNodePosition(t,n){return t.compareDocumentPosition(n)&2?1:-1}getBaseTargetFromProps(t,n){return t.style?t.style[n]:void 0}removeValueFromRenderState(t,{vars:n,style:i}){delete n[t],delete i[t]}handleChildMotionValue(){this.childSubscription&&(this.childSubscription(),delete this.childSubscription);const{children:t}=this.props;Mn(t)&&(this.childSubscription=t.on("change",n=>{this.current&&(this.current.textContent=`${n}`)}))}}function Uv(e,{style:t,vars:n},i,u){const o=e.style;let l;for(l in t)o[l]=t[l];u?.applyProjectionStyles(o,i);for(l in n)o.setProperty(l,n[l])}function k4(e){return window.getComputedStyle(e)}class L4 extends Bv{constructor(){super(...arguments),this.type="html",this.renderInstance=Uv}readValueFromInstance(t,n){if(Es.has(n))return this.projection?.isProjecting?qp(n):aN(t,n);{const i=k4(t),u=(Z0(n)?i.getPropertyValue(n):i[n])||0;return typeof u=="string"?u.trim():u}}measureInstanceViewportBox(t,{transformPagePoint:n}){return vv(t,n)}build(t,n,i){Eg(t,n,i.transformTemplate)}scrapeMotionValuesFromProps(t,n,i){return Ag(t,n,i)}}const Hv=new Set(["baseFrequency","diffuseConstant","kernelMatrix","kernelUnitLength","keySplines","keyTimes","limitingConeAngle","markerHeight","markerWidth","numOctaves","targetX","targetY","surfaceScale","specularConstant","specularExponent","stdDeviation","tableValues","viewBox","gradientTransform","pathLength","startOffset","textLength","lengthAdjust"]);function M4(e,t,n,i){Uv(e,t,void 0,i);for(const u in t.attrs)e.setAttribute(Hv.has(u)?u:gg(u),t.attrs[u])}class I4 extends Bv{constructor(){super(...arguments),this.type="svg",this.isSVGTag=!1,this.measureInstanceViewportBox=un}getBaseTargetFromProps(t,n){return t[n]}readValueFromInstance(t,n){if(Es.has(n)){const i=KD(n);return i&&i.default||0}return n=Hv.has(n)?n:gg(n),t.getAttribute(n)}scrapeMotionValuesFromProps(t,n,i){return mv(t,n,i)}build(t,n,i){cv(t,n,this.isSVGTag,i.transformTemplate,i.style)}renderInstance(t,n,i,u){M4(t,n,i,u)}mount(t){this.isSVGTag=dv(t.tagName),super.mount(t)}}const P4=(e,t)=>bg(e)?new I4(t):new L4(t,{allowProjection:e!==W.Fragment}),F4=Pk({...oL,..._4,...p4,...x4},P4),Fj=sk(F4);var $m={},No={},af={},uf={},Zm={exports:{}},Jm,vA;function B4(){if(vA)return Jm;vA=1;var e="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";return Jm=e,Jm}var ep,CA;function U4(){if(CA)return ep;CA=1;var e=B4();function t(){}function n(){}return n.resetWarningCache=t,ep=function(){function i(l,f,d,h,p,g){if(g!==e){var b=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw b.name="Invariant Violation",b}}i.isRequired=i;function u(){return i}var o={array:i,bigint:i,bool:i,func:i,number:i,object:i,string:i,symbol:i,any:i,arrayOf:u,element:i,elementType:i,instanceOf:u,node:i,objectOf:u,oneOf:u,oneOfType:u,shape:u,exact:u,checkPropTypes:n,resetWarningCache:t};return o.PropTypes=o,o},ep}var _A;function H4(){return _A||(_A=1,Zm.exports=U4()()),Zm.exports}var xA;function z4(){return xA||(xA=1,function(e){(function(t,n){n(e,Ca(),H4())})(uf,function(t,n,i){Object.defineProperty(t,"__esModule",{value:!0}),t.setHasSupportToCaptureOption=A;var u=l(n),o=l(i);function l(N){return N&&N.__esModule?N:{default:N}}var f=Object.assign||function(N){for(var R=1;R<arguments.length;R++){var Y=arguments[R];for(var M in Y)Object.prototype.hasOwnProperty.call(Y,M)&&(N[M]=Y[M])}return N};function d(N,R){var Y={};for(var M in N)R.indexOf(M)>=0||Object.prototype.hasOwnProperty.call(N,M)&&(Y[M]=N[M]);return Y}function h(N,R){if(!(N instanceof R))throw new TypeError("Cannot call a class as a function")}var p=function(){function N(R,Y){for(var M=0;M<Y.length;M++){var v=Y[M];v.enumerable=v.enumerable||!1,v.configurable=!0,"value"in v&&(v.writable=!0),Object.defineProperty(R,v.key,v)}}return function(R,Y,M){return Y&&N(R.prototype,Y),M&&N(R,M),R}}();function g(N,R){if(!N)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return R&&(typeof R=="object"||typeof R=="function")?R:N}function b(N,R){if(typeof R!="function"&&R!==null)throw new TypeError("Super expression must either be null or a function, not "+typeof R);N.prototype=Object.create(R&&R.prototype,{constructor:{value:N,enumerable:!1,writable:!0,configurable:!0}}),R&&(Object.setPrototypeOf?Object.setPrototypeOf(N,R):N.__proto__=R)}var T=!1;function A(N){T=N}try{addEventListener("test",null,Object.defineProperty({},"capture",{get:function(){A(!0)}}))}catch{}function _(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{capture:!0};return T?N:N.capture}function O(N){if("touches"in N){var R=N.touches[0],Y=R.pageX,M=R.pageY;return{x:Y,y:M}}var v=N.screenX,J=N.screenY;return{x:v,y:J}}var C=function(N){b(R,N);function R(){var Y;h(this,R);for(var M=arguments.length,v=Array(M),J=0;J<M;J++)v[J]=arguments[J];var P=g(this,(Y=R.__proto__||Object.getPrototypeOf(R)).call.apply(Y,[this].concat(v)));return P._handleSwipeStart=P._handleSwipeStart.bind(P),P._handleSwipeMove=P._handleSwipeMove.bind(P),P._handleSwipeEnd=P._handleSwipeEnd.bind(P),P._onMouseDown=P._onMouseDown.bind(P),P._onMouseMove=P._onMouseMove.bind(P),P._onMouseUp=P._onMouseUp.bind(P),P._setSwiperRef=P._setSwiperRef.bind(P),P}return p(R,[{key:"componentDidMount",value:function(){this.swiper&&this.swiper.addEventListener("touchmove",this._handleSwipeMove,_({capture:!0,passive:!1}))}},{key:"componentWillUnmount",value:function(){this.swiper&&this.swiper.removeEventListener("touchmove",this._handleSwipeMove,_({capture:!0,passive:!1}))}},{key:"_onMouseDown",value:function(M){this.props.allowMouseEvents&&(this.mouseDown=!0,document.addEventListener("mouseup",this._onMouseUp),document.addEventListener("mousemove",this._onMouseMove),this._handleSwipeStart(M))}},{key:"_onMouseMove",value:function(M){this.mouseDown&&this._handleSwipeMove(M)}},{key:"_onMouseUp",value:function(M){this.mouseDown=!1,document.removeEventListener("mouseup",this._onMouseUp),document.removeEventListener("mousemove",this._onMouseMove),this._handleSwipeEnd(M)}},{key:"_handleSwipeStart",value:function(M){var v=O(M),J=v.x,P=v.y;this.moveStart={x:J,y:P},this.props.onSwipeStart(M)}},{key:"_handleSwipeMove",value:function(M){if(this.moveStart){var v=O(M),J=v.x,P=v.y,q=J-this.moveStart.x,z=P-this.moveStart.y;this.moving=!0;var V=this.props.onSwipeMove({x:q,y:z},M);V&&M.cancelable&&M.preventDefault(),this.movePosition={deltaX:q,deltaY:z}}}},{key:"_handleSwipeEnd",value:function(M){this.props.onSwipeEnd(M);var v=this.props.tolerance;this.moving&&this.movePosition&&(this.movePosition.deltaX<-v?this.props.onSwipeLeft(1,M):this.movePosition.deltaX>v&&this.props.onSwipeRight(1,M),this.movePosition.deltaY<-v?this.props.onSwipeUp(1,M):this.movePosition.deltaY>v&&this.props.onSwipeDown(1,M)),this.moveStart=null,this.moving=!1,this.movePosition=null}},{key:"_setSwiperRef",value:function(M){this.swiper=M,this.props.innerRef(M)}},{key:"render",value:function(){var M=this.props;M.tagName;var v=M.className,J=M.style,P=M.children;M.allowMouseEvents,M.onSwipeUp,M.onSwipeDown,M.onSwipeLeft,M.onSwipeRight,M.onSwipeStart,M.onSwipeMove,M.onSwipeEnd,M.innerRef,M.tolerance;var q=d(M,["tagName","className","style","children","allowMouseEvents","onSwipeUp","onSwipeDown","onSwipeLeft","onSwipeRight","onSwipeStart","onSwipeMove","onSwipeEnd","innerRef","tolerance"]);return u.default.createElement(this.props.tagName,f({ref:this._setSwiperRef,onMouseDown:this._onMouseDown,onTouchStart:this._handleSwipeStart,onTouchEnd:this._handleSwipeEnd,className:v,style:J},q),P)}}]),R}(n.Component);C.displayName="ReactSwipe",C.propTypes={tagName:o.default.string,className:o.default.string,style:o.default.object,children:o.default.node,allowMouseEvents:o.default.bool,onSwipeUp:o.default.func,onSwipeDown:o.default.func,onSwipeLeft:o.default.func,onSwipeRight:o.default.func,onSwipeStart:o.default.func,onSwipeMove:o.default.func,onSwipeEnd:o.default.func,innerRef:o.default.func,tolerance:o.default.number.isRequired},C.defaultProps={tagName:"div",allowMouseEvents:!1,onSwipeUp:function(){},onSwipeDown:function(){},onSwipeLeft:function(){},onSwipeRight:function(){},onSwipeStart:function(){},onSwipeMove:function(){},onSwipeEnd:function(){},innerRef:function(){},tolerance:0},t.default=C})}(uf)),uf}var RA;function zv(){return RA||(RA=1,function(e){(function(t,n){n(e,z4())})(af,function(t,n){Object.defineProperty(t,"__esModule",{value:!0});var i=u(n);function u(o){return o&&o.__esModule?o:{default:o}}t.default=i.default})}(af)),af}var ko={},tp={exports:{}};/*! + Copyright (c) 2018 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames +*/var wA;function V4(){return wA||(wA=1,function(e){(function(){var t={}.hasOwnProperty;function n(){for(var o="",l=0;l<arguments.length;l++){var f=arguments[l];f&&(o=u(o,i(f)))}return o}function i(o){if(typeof o=="string"||typeof o=="number")return o;if(typeof o!="object")return"";if(Array.isArray(o))return n.apply(null,o);if(o.toString!==Object.prototype.toString&&!o.toString.toString().includes("[native code]"))return o.toString();var l="";for(var f in o)t.call(o,f)&&o[f]&&(l=u(l,f));return l}function u(o,l){return l?o?o+" "+l:o+l:o}e.exports?(n.default=n,e.exports=n):window.classNames=n})()}(tp)),tp.exports}var OA;function Vv(){if(OA)return ko;OA=1,Object.defineProperty(ko,"__esModule",{value:!0}),ko.default=void 0;var e=t(V4());function t(u){return u&&u.__esModule?u:{default:u}}function n(u,o,l){return o in u?Object.defineProperty(u,o,{value:l,enumerable:!0,configurable:!0,writable:!0}):u[o]=l,u}var i={ROOT:function(o){return(0,e.default)(n({"carousel-root":!0},o||"",!!o))},CAROUSEL:function(o){return(0,e.default)({carousel:!0,"carousel-slider":o})},WRAPPER:function(o,l){return(0,e.default)({"thumbs-wrapper":!o,"slider-wrapper":o,"axis-horizontal":l==="horizontal","axis-vertical":l!=="horizontal"})},SLIDER:function(o,l){return(0,e.default)({thumbs:!o,slider:o,animated:!l})},ITEM:function(o,l,f){return(0,e.default)({thumb:!o,slide:o,selected:l,previous:f})},ARROW_PREV:function(o){return(0,e.default)({"control-arrow control-prev":!0,"control-disabled":o})},ARROW_NEXT:function(o){return(0,e.default)({"control-arrow control-next":!0,"control-disabled":o})},DOT:function(o){return(0,e.default)({dot:!0,selected:o})}};return ko.default=i,ko}var Lo={},Mo={},NA;function j4(){if(NA)return Mo;NA=1,Object.defineProperty(Mo,"__esModule",{value:!0}),Mo.outerWidth=void 0;var e=function(n){var i=n.offsetWidth,u=getComputedStyle(n);return i+=parseInt(u.marginLeft)+parseInt(u.marginRight),i};return Mo.outerWidth=e,Mo}var Io={},kA;function Dg(){if(kA)return Io;kA=1,Object.defineProperty(Io,"__esModule",{value:!0}),Io.default=void 0;var e=function(n,i,u){var o=n===0?n:n+i,l=u==="horizontal"?[o,0,0]:[0,o,0],f="translate3d",d="("+l.join(",")+")";return f+d};return Io.default=e,Io}var Po={},LA;function jv(){if(LA)return Po;LA=1,Object.defineProperty(Po,"__esModule",{value:!0}),Po.default=void 0;var e=function(){return window};return Po.default=e,Po}var MA;function qv(){if(MA)return Lo;MA=1,Object.defineProperty(Lo,"__esModule",{value:!0}),Lo.default=void 0;var e=d(Ca()),t=l(Vv()),n=j4(),i=l(Dg()),u=l(zv()),o=l(jv());function l(P){return P&&P.__esModule?P:{default:P}}function f(){if(typeof WeakMap!="function")return null;var P=new WeakMap;return f=function(){return P},P}function d(P){if(P&&P.__esModule)return P;if(P===null||h(P)!=="object"&&typeof P!="function")return{default:P};var q=f();if(q&&q.has(P))return q.get(P);var z={},V=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var F in P)if(Object.prototype.hasOwnProperty.call(P,F)){var $=V?Object.getOwnPropertyDescriptor(P,F):null;$&&($.get||$.set)?Object.defineProperty(z,F,$):z[F]=P[F]}return z.default=P,q&&q.set(P,z),z}function h(P){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?h=function(z){return typeof z}:h=function(z){return z&&typeof Symbol=="function"&&z.constructor===Symbol&&z!==Symbol.prototype?"symbol":typeof z},h(P)}function p(){return p=Object.assign||function(P){for(var q=1;q<arguments.length;q++){var z=arguments[q];for(var V in z)Object.prototype.hasOwnProperty.call(z,V)&&(P[V]=z[V])}return P},p.apply(this,arguments)}function g(P,q){if(!(P instanceof q))throw new TypeError("Cannot call a class as a function")}function b(P,q){for(var z=0;z<q.length;z++){var V=q[z];V.enumerable=V.enumerable||!1,V.configurable=!0,"value"in V&&(V.writable=!0),Object.defineProperty(P,V.key,V)}}function T(P,q,z){return q&&b(P.prototype,q),P}function A(P,q){if(typeof q!="function"&&q!==null)throw new TypeError("Super expression must either be null or a function");P.prototype=Object.create(q&&q.prototype,{constructor:{value:P,writable:!0,configurable:!0}}),q&&_(P,q)}function _(P,q){return _=Object.setPrototypeOf||function(V,F){return V.__proto__=F,V},_(P,q)}function O(P){var q=R();return function(){var V=Y(P),F;if(q){var $=Y(this).constructor;F=Reflect.construct(V,arguments,$)}else F=V.apply(this,arguments);return C(this,F)}}function C(P,q){return q&&(h(q)==="object"||typeof q=="function")?q:N(P)}function N(P){if(P===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return P}function R(){if(typeof Reflect>"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch{return!1}}function Y(P){return Y=Object.setPrototypeOf?Object.getPrototypeOf:function(z){return z.__proto__||Object.getPrototypeOf(z)},Y(P)}function M(P,q,z){return q in P?Object.defineProperty(P,q,{value:z,enumerable:!0,configurable:!0,writable:!0}):P[q]=z,P}var v=function(q){return q.hasOwnProperty("key")},J=function(P){A(z,P);var q=O(z);function z(V){var F;return g(this,z),F=q.call(this,V),M(N(F),"itemsWrapperRef",void 0),M(N(F),"itemsListRef",void 0),M(N(F),"thumbsRef",void 0),M(N(F),"setItemsWrapperRef",function($){F.itemsWrapperRef=$}),M(N(F),"setItemsListRef",function($){F.itemsListRef=$}),M(N(F),"setThumbsRef",function($,Z){F.thumbsRef||(F.thumbsRef=[]),F.thumbsRef[Z]=$}),M(N(F),"updateSizes",function(){if(!(!F.props.children||!F.itemsWrapperRef||!F.thumbsRef)){var $=e.Children.count(F.props.children),Z=F.itemsWrapperRef.clientWidth,L=F.props.thumbWidth?F.props.thumbWidth:(0,n.outerWidth)(F.thumbsRef[0]),B=Math.floor(Z/L),K=B<$,Q=K?$-B:0;F.setState(function(_e,S){return{itemSize:L,visibleItems:B,firstItem:K?F.getFirstItem(S.selectedItem):0,lastPosition:Q,showArrows:K}})}}),M(N(F),"handleClickItem",function($,Z,L){if(!v(L)||L.key==="Enter"){var B=F.props.onSelectItem;typeof B=="function"&&B($,Z)}}),M(N(F),"onSwipeStart",function(){F.setState({swiping:!0})}),M(N(F),"onSwipeEnd",function(){F.setState({swiping:!1})}),M(N(F),"onSwipeMove",function($){var Z=$.x;if(!F.state.itemSize||!F.itemsWrapperRef||!F.state.visibleItems)return!1;var L=0,B=e.Children.count(F.props.children),K=-(F.state.firstItem*100)/F.state.visibleItems,Q=Math.max(B-F.state.visibleItems,0),_e=-Q*100/F.state.visibleItems;K===L&&Z>0&&(Z=0),K===_e&&Z<0&&(Z=0);var S=F.itemsWrapperRef.clientWidth,ne=K+100/(S/Z);return F.itemsListRef&&["WebkitTransform","MozTransform","MsTransform","OTransform","transform","msTransform"].forEach(function(ge){F.itemsListRef.style[ge]=(0,i.default)(ne,"%",F.props.axis)}),!0}),M(N(F),"slideRight",function($){F.moveTo(F.state.firstItem-(typeof $=="number"?$:1))}),M(N(F),"slideLeft",function($){F.moveTo(F.state.firstItem+(typeof $=="number"?$:1))}),M(N(F),"moveTo",function($){$=$<0?0:$,$=$>=F.state.lastPosition?F.state.lastPosition:$,F.setState({firstItem:$})}),F.state={selectedItem:V.selectedItem,swiping:!1,showArrows:!1,firstItem:0,visibleItems:0,lastPosition:0},F}return T(z,[{key:"componentDidMount",value:function(){this.setupThumbs()}},{key:"componentDidUpdate",value:function(F){this.props.selectedItem!==this.state.selectedItem&&this.setState({selectedItem:this.props.selectedItem,firstItem:this.getFirstItem(this.props.selectedItem)}),this.props.children!==F.children&&this.updateSizes()}},{key:"componentWillUnmount",value:function(){this.destroyThumbs()}},{key:"setupThumbs",value:function(){(0,o.default)().addEventListener("resize",this.updateSizes),(0,o.default)().addEventListener("DOMContentLoaded",this.updateSizes),this.updateSizes()}},{key:"destroyThumbs",value:function(){(0,o.default)().removeEventListener("resize",this.updateSizes),(0,o.default)().removeEventListener("DOMContentLoaded",this.updateSizes)}},{key:"getFirstItem",value:function(F){var $=F;return F>=this.state.lastPosition&&($=this.state.lastPosition),F<this.state.firstItem+this.state.visibleItems&&($=this.state.firstItem),F<this.state.firstItem&&($=F),$}},{key:"renderItems",value:function(){var F=this;return this.props.children.map(function($,Z){var L=t.default.ITEM(!1,Z===F.state.selectedItem),B={key:Z,ref:function(Q){return F.setThumbsRef(Q,Z)},className:L,onClick:F.handleClickItem.bind(F,Z,F.props.children[Z]),onKeyDown:F.handleClickItem.bind(F,Z,F.props.children[Z]),"aria-label":"".concat(F.props.labels.item," ").concat(Z+1),style:{width:F.props.thumbWidth}};return e.default.createElement("li",p({},B,{role:"button",tabIndex:0}),$)})}},{key:"render",value:function(){var F=this;if(!this.props.children)return null;var $=e.Children.count(this.props.children)>1,Z=this.state.showArrows&&this.state.firstItem>0,L=this.state.showArrows&&this.state.firstItem<this.state.lastPosition,B={},K=-this.state.firstItem*(this.state.itemSize||0),Q=(0,i.default)(K,"px",this.props.axis),_e=this.props.transitionTime+"ms";return B={WebkitTransform:Q,MozTransform:Q,MsTransform:Q,OTransform:Q,transform:Q,msTransform:Q,WebkitTransitionDuration:_e,MozTransitionDuration:_e,MsTransitionDuration:_e,OTransitionDuration:_e,transitionDuration:_e,msTransitionDuration:_e},e.default.createElement("div",{className:t.default.CAROUSEL(!1)},e.default.createElement("div",{className:t.default.WRAPPER(!1),ref:this.setItemsWrapperRef},e.default.createElement("button",{type:"button",className:t.default.ARROW_PREV(!Z),onClick:function(){return F.slideRight()},"aria-label":this.props.labels.leftArrow}),$?e.default.createElement(u.default,{tagName:"ul",className:t.default.SLIDER(!1,this.state.swiping),onSwipeLeft:this.slideLeft,onSwipeRight:this.slideRight,onSwipeMove:this.onSwipeMove,onSwipeStart:this.onSwipeStart,onSwipeEnd:this.onSwipeEnd,style:B,innerRef:this.setItemsListRef,allowMouseEvents:this.props.emulateTouch},this.renderItems()):e.default.createElement("ul",{className:t.default.SLIDER(!1,this.state.swiping),ref:function(ne){return F.setItemsListRef(ne)},style:B},this.renderItems()),e.default.createElement("button",{type:"button",className:t.default.ARROW_NEXT(!L),onClick:function(){return F.slideLeft()},"aria-label":this.props.labels.rightArrow})))}}]),z}(e.Component);return Lo.default=J,M(J,"displayName","Thumbs"),M(J,"defaultProps",{axis:"horizontal",labels:{leftArrow:"previous slide / item",rightArrow:"next slide / item",item:"slide item"},selectedItem:0,thumbWidth:80,transitionTime:350}),Lo}var Fo={},IA;function q4(){if(IA)return Fo;IA=1,Object.defineProperty(Fo,"__esModule",{value:!0}),Fo.default=void 0;var e=function(){return document};return Fo.default=e,Fo}var pr={},PA;function Yv(){if(PA)return pr;PA=1,Object.defineProperty(pr,"__esModule",{value:!0}),pr.setPosition=pr.getPosition=pr.isKeyboardEvent=pr.defaultStatusFormatter=pr.noop=void 0;var e=Ca(),t=n(Dg());function n(d){return d&&d.__esModule?d:{default:d}}var i=function(){};pr.noop=i;var u=function(h,p){return"".concat(h," of ").concat(p)};pr.defaultStatusFormatter=u;var o=function(h){return h?h.hasOwnProperty("key"):!1};pr.isKeyboardEvent=o;var l=function(h,p){if(p.infiniteLoop&&++h,h===0)return 0;var g=e.Children.count(p.children);if(p.centerMode&&p.axis==="horizontal"){var b=-h*p.centerSlidePercentage,T=g-1;return h&&(h!==T||p.infiniteLoop)?b+=(100-p.centerSlidePercentage)/2:h===T&&(b+=100-p.centerSlidePercentage),b}return-h*100};pr.getPosition=l;var f=function(h,p){var g={};return["WebkitTransform","MozTransform","MsTransform","OTransform","transform","msTransform"].forEach(function(b){g[b]=(0,t.default)(h,"%",p)}),g};return pr.setPosition=f,pr}var Kr={},FA;function Y4(){if(FA)return Kr;FA=1,Object.defineProperty(Kr,"__esModule",{value:!0}),Kr.fadeAnimationHandler=Kr.slideStopSwipingHandler=Kr.slideSwipeAnimationHandler=Kr.slideAnimationHandler=void 0;var e=Ca(),t=i(Dg()),n=Yv();function i(g){return g&&g.__esModule?g:{default:g}}function u(g,b){var T=Object.keys(g);if(Object.getOwnPropertySymbols){var A=Object.getOwnPropertySymbols(g);b&&(A=A.filter(function(_){return Object.getOwnPropertyDescriptor(g,_).enumerable})),T.push.apply(T,A)}return T}function o(g){for(var b=1;b<arguments.length;b++){var T=arguments[b]!=null?arguments[b]:{};b%2?u(Object(T),!0).forEach(function(A){l(g,A,T[A])}):Object.getOwnPropertyDescriptors?Object.defineProperties(g,Object.getOwnPropertyDescriptors(T)):u(Object(T)).forEach(function(A){Object.defineProperty(g,A,Object.getOwnPropertyDescriptor(T,A))})}return g}function l(g,b,T){return b in g?Object.defineProperty(g,b,{value:T,enumerable:!0,configurable:!0,writable:!0}):g[b]=T,g}var f=function(b,T){var A={},_=T.selectedItem,O=_,C=e.Children.count(b.children)-1,N=b.infiniteLoop&&(_<0||_>C);if(N)return O<0?b.centerMode&&b.centerSlidePercentage&&b.axis==="horizontal"?A.itemListStyle=(0,n.setPosition)(-(C+2)*b.centerSlidePercentage-(100-b.centerSlidePercentage)/2,b.axis):A.itemListStyle=(0,n.setPosition)(-(C+2)*100,b.axis):O>C&&(A.itemListStyle=(0,n.setPosition)(0,b.axis)),A;var R=(0,n.getPosition)(_,b),Y=(0,t.default)(R,"%",b.axis),M=b.transitionTime+"ms";return A.itemListStyle={WebkitTransform:Y,msTransform:Y,OTransform:Y,transform:Y},T.swiping||(A.itemListStyle=o(o({},A.itemListStyle),{},{WebkitTransitionDuration:M,MozTransitionDuration:M,OTransitionDuration:M,transitionDuration:M,msTransitionDuration:M})),A};Kr.slideAnimationHandler=f;var d=function(b,T,A,_){var O={},C=T.axis==="horizontal",N=e.Children.count(T.children),R=0,Y=(0,n.getPosition)(A.selectedItem,T),M=T.infiniteLoop?(0,n.getPosition)(N-1,T)-100:(0,n.getPosition)(N-1,T),v=C?b.x:b.y,J=v;Y===R&&v>0&&(J=0),Y===M&&v<0&&(J=0);var P=Y+100/(A.itemSize/J),q=Math.abs(v)>T.swipeScrollTolerance;return T.infiniteLoop&&q&&(A.selectedItem===0&&P>-100?P-=N*100:A.selectedItem===N-1&&P<-N*100&&(P+=N*100)),(!T.preventMovementUntilSwipeScrollTolerance||q||A.swipeMovementStarted)&&(A.swipeMovementStarted||_({swipeMovementStarted:!0}),O.itemListStyle=(0,n.setPosition)(P,T.axis)),q&&!A.cancelClick&&_({cancelClick:!0}),O};Kr.slideSwipeAnimationHandler=d;var h=function(b,T){var A=(0,n.getPosition)(T.selectedItem,b),_=(0,n.setPosition)(A,b.axis);return{itemListStyle:_}};Kr.slideStopSwipingHandler=h;var p=function(b,T){var A=b.transitionTime+"ms",_="ease-in-out",O={position:"absolute",display:"block",zIndex:-2,minHeight:"100%",opacity:0,top:0,right:0,left:0,bottom:0,transitionTimingFunction:_,msTransitionTimingFunction:_,MozTransitionTimingFunction:_,WebkitTransitionTimingFunction:_,OTransitionTimingFunction:_};return T.swiping||(O=o(o({},O),{},{WebkitTransitionDuration:A,MozTransitionDuration:A,OTransitionDuration:A,transitionDuration:A,msTransitionDuration:A})),{slideStyle:O,selectedStyle:o(o({},O),{},{opacity:1,position:"relative"}),prevStyle:o({},O)}};return Kr.fadeAnimationHandler=p,Kr}var BA;function G4(){if(BA)return No;BA=1,Object.defineProperty(No,"__esModule",{value:!0}),No.default=void 0;var e=p(Ca()),t=d(zv()),n=d(Vv()),i=d(qv()),u=d(q4()),o=d(jv()),l=Yv(),f=Y4();function d(V){return V&&V.__esModule?V:{default:V}}function h(){if(typeof WeakMap!="function")return null;var V=new WeakMap;return h=function(){return V},V}function p(V){if(V&&V.__esModule)return V;if(V===null||g(V)!=="object"&&typeof V!="function")return{default:V};var F=h();if(F&&F.has(V))return F.get(V);var $={},Z=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var L in V)if(Object.prototype.hasOwnProperty.call(V,L)){var B=Z?Object.getOwnPropertyDescriptor(V,L):null;B&&(B.get||B.set)?Object.defineProperty($,L,B):$[L]=V[L]}return $.default=V,F&&F.set(V,$),$}function g(V){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?g=function($){return typeof $}:g=function($){return $&&typeof Symbol=="function"&&$.constructor===Symbol&&$!==Symbol.prototype?"symbol":typeof $},g(V)}function b(){return b=Object.assign||function(V){for(var F=1;F<arguments.length;F++){var $=arguments[F];for(var Z in $)Object.prototype.hasOwnProperty.call($,Z)&&(V[Z]=$[Z])}return V},b.apply(this,arguments)}function T(V,F){var $=Object.keys(V);if(Object.getOwnPropertySymbols){var Z=Object.getOwnPropertySymbols(V);F&&(Z=Z.filter(function(L){return Object.getOwnPropertyDescriptor(V,L).enumerable})),$.push.apply($,Z)}return $}function A(V){for(var F=1;F<arguments.length;F++){var $=arguments[F]!=null?arguments[F]:{};F%2?T(Object($),!0).forEach(function(Z){q(V,Z,$[Z])}):Object.getOwnPropertyDescriptors?Object.defineProperties(V,Object.getOwnPropertyDescriptors($)):T(Object($)).forEach(function(Z){Object.defineProperty(V,Z,Object.getOwnPropertyDescriptor($,Z))})}return V}function _(V,F){if(!(V instanceof F))throw new TypeError("Cannot call a class as a function")}function O(V,F){for(var $=0;$<F.length;$++){var Z=F[$];Z.enumerable=Z.enumerable||!1,Z.configurable=!0,"value"in Z&&(Z.writable=!0),Object.defineProperty(V,Z.key,Z)}}function C(V,F,$){return F&&O(V.prototype,F),V}function N(V,F){if(typeof F!="function"&&F!==null)throw new TypeError("Super expression must either be null or a function");V.prototype=Object.create(F&&F.prototype,{constructor:{value:V,writable:!0,configurable:!0}}),F&&R(V,F)}function R(V,F){return R=Object.setPrototypeOf||function(Z,L){return Z.__proto__=L,Z},R(V,F)}function Y(V){var F=J();return function(){var Z=P(V),L;if(F){var B=P(this).constructor;L=Reflect.construct(Z,arguments,B)}else L=Z.apply(this,arguments);return M(this,L)}}function M(V,F){return F&&(g(F)==="object"||typeof F=="function")?F:v(V)}function v(V){if(V===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return V}function J(){if(typeof Reflect>"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch{return!1}}function P(V){return P=Object.setPrototypeOf?Object.getPrototypeOf:function($){return $.__proto__||Object.getPrototypeOf($)},P(V)}function q(V,F,$){return F in V?Object.defineProperty(V,F,{value:$,enumerable:!0,configurable:!0,writable:!0}):V[F]=$,V}var z=function(V){N($,V);var F=Y($);function $(Z){var L;_(this,$),L=F.call(this,Z),q(v(L),"thumbsRef",void 0),q(v(L),"carouselWrapperRef",void 0),q(v(L),"listRef",void 0),q(v(L),"itemsRef",void 0),q(v(L),"timer",void 0),q(v(L),"animationHandler",void 0),q(v(L),"setThumbsRef",function(K){L.thumbsRef=K}),q(v(L),"setCarouselWrapperRef",function(K){L.carouselWrapperRef=K}),q(v(L),"setListRef",function(K){L.listRef=K}),q(v(L),"setItemsRef",function(K,Q){L.itemsRef||(L.itemsRef=[]),L.itemsRef[Q]=K}),q(v(L),"autoPlay",function(){e.Children.count(L.props.children)<=1||(L.clearAutoPlay(),L.props.autoPlay&&(L.timer=setTimeout(function(){L.increment()},L.props.interval)))}),q(v(L),"clearAutoPlay",function(){L.timer&&clearTimeout(L.timer)}),q(v(L),"resetAutoPlay",function(){L.clearAutoPlay(),L.autoPlay()}),q(v(L),"stopOnHover",function(){L.setState({isMouseEntered:!0},L.clearAutoPlay)}),q(v(L),"startOnLeave",function(){L.setState({isMouseEntered:!1},L.autoPlay)}),q(v(L),"isFocusWithinTheCarousel",function(){return L.carouselWrapperRef?!!((0,u.default)().activeElement===L.carouselWrapperRef||L.carouselWrapperRef.contains((0,u.default)().activeElement)):!1}),q(v(L),"navigateWithKeyboard",function(K){if(L.isFocusWithinTheCarousel()){var Q=L.props.axis,_e=Q==="horizontal",S={ArrowUp:38,ArrowRight:39,ArrowDown:40,ArrowLeft:37},ne=_e?S.ArrowRight:S.ArrowDown,ge=_e?S.ArrowLeft:S.ArrowUp;ne===K.keyCode?L.increment():ge===K.keyCode&&L.decrement()}}),q(v(L),"updateSizes",function(){if(!(!L.state.initialized||!L.itemsRef||L.itemsRef.length===0)){var K=L.props.axis==="horizontal",Q=L.itemsRef[0];if(Q){var _e=K?Q.clientWidth:Q.clientHeight;L.setState({itemSize:_e}),L.thumbsRef&&L.thumbsRef.updateSizes()}}}),q(v(L),"setMountState",function(){L.setState({hasMount:!0}),L.updateSizes()}),q(v(L),"handleClickItem",function(K,Q){if(e.Children.count(L.props.children)!==0){if(L.state.cancelClick){L.setState({cancelClick:!1});return}L.props.onClickItem(K,Q),K!==L.state.selectedItem&&L.setState({selectedItem:K})}}),q(v(L),"handleOnChange",function(K,Q){e.Children.count(L.props.children)<=1||L.props.onChange(K,Q)}),q(v(L),"handleClickThumb",function(K,Q){L.props.onClickThumb(K,Q),L.moveTo(K)}),q(v(L),"onSwipeStart",function(K){L.setState({swiping:!0}),L.props.onSwipeStart(K)}),q(v(L),"onSwipeEnd",function(K){L.setState({swiping:!1,cancelClick:!1,swipeMovementStarted:!1}),L.props.onSwipeEnd(K),L.clearAutoPlay(),L.state.autoPlay&&L.autoPlay()}),q(v(L),"onSwipeMove",function(K,Q){L.props.onSwipeMove(Q);var _e=L.props.swipeAnimationHandler(K,L.props,L.state,L.setState.bind(v(L)));return L.setState(A({},_e)),!!Object.keys(_e).length}),q(v(L),"decrement",function(){var K=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1;L.moveTo(L.state.selectedItem-(typeof K=="number"?K:1))}),q(v(L),"increment",function(){var K=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1;L.moveTo(L.state.selectedItem+(typeof K=="number"?K:1))}),q(v(L),"moveTo",function(K){if(typeof K=="number"){var Q=e.Children.count(L.props.children)-1;K<0&&(K=L.props.infiniteLoop?Q:0),K>Q&&(K=L.props.infiniteLoop?0:Q),L.selectItem({selectedItem:K}),L.state.autoPlay&&L.state.isMouseEntered===!1&&L.resetAutoPlay()}}),q(v(L),"onClickNext",function(){L.increment(1)}),q(v(L),"onClickPrev",function(){L.decrement(1)}),q(v(L),"onSwipeForward",function(){L.increment(1),L.props.emulateTouch&&L.setState({cancelClick:!0})}),q(v(L),"onSwipeBackwards",function(){L.decrement(1),L.props.emulateTouch&&L.setState({cancelClick:!0})}),q(v(L),"changeItem",function(K){return function(Q){(!(0,l.isKeyboardEvent)(Q)||Q.key==="Enter")&&L.moveTo(K)}}),q(v(L),"selectItem",function(K){L.setState(A({previousItem:L.state.selectedItem},K),function(){L.setState(L.animationHandler(L.props,L.state))}),L.handleOnChange(K.selectedItem,e.Children.toArray(L.props.children)[K.selectedItem])}),q(v(L),"getInitialImage",function(){var K=L.props.selectedItem,Q=L.itemsRef&&L.itemsRef[K],_e=Q&&Q.getElementsByTagName("img")||[];return _e[0]}),q(v(L),"getVariableItemHeight",function(K){var Q=L.itemsRef&&L.itemsRef[K];if(L.state.hasMount&&Q&&Q.children.length){var _e=Q.children[0].getElementsByTagName("img")||[];if(_e.length>0){var S=_e[0];if(!S.complete){var ne=function Te(){L.forceUpdate(),S.removeEventListener("load",Te)};S.addEventListener("load",ne)}}var ge=_e[0]||Q.children[0],w=ge.clientHeight;return w>0?w:null}return null});var B={initialized:!1,previousItem:Z.selectedItem,selectedItem:Z.selectedItem,hasMount:!1,isMouseEntered:!1,autoPlay:Z.autoPlay,swiping:!1,swipeMovementStarted:!1,cancelClick:!1,itemSize:1,itemListStyle:{},slideStyle:{},selectedStyle:{},prevStyle:{}};return L.animationHandler=typeof Z.animationHandler=="function"&&Z.animationHandler||Z.animationHandler==="fade"&&f.fadeAnimationHandler||f.slideAnimationHandler,L.state=A(A({},B),L.animationHandler(Z,B)),L}return C($,[{key:"componentDidMount",value:function(){this.props.children&&this.setupCarousel()}},{key:"componentDidUpdate",value:function(L,B){!L.children&&this.props.children&&!this.state.initialized&&this.setupCarousel(),!L.autoFocus&&this.props.autoFocus&&this.forceFocus(),B.swiping&&!this.state.swiping&&this.setState(A({},this.props.stopSwipingHandler(this.props,this.state))),(L.selectedItem!==this.props.selectedItem||L.centerMode!==this.props.centerMode)&&(this.updateSizes(),this.moveTo(this.props.selectedItem)),L.autoPlay!==this.props.autoPlay&&(this.props.autoPlay?this.setupAutoPlay():this.destroyAutoPlay(),this.setState({autoPlay:this.props.autoPlay}))}},{key:"componentWillUnmount",value:function(){this.destroyCarousel()}},{key:"setupCarousel",value:function(){var L=this;this.bindEvents(),this.state.autoPlay&&e.Children.count(this.props.children)>1&&this.setupAutoPlay(),this.props.autoFocus&&this.forceFocus(),this.setState({initialized:!0},function(){var B=L.getInitialImage();B&&!B.complete?B.addEventListener("load",L.setMountState):L.setMountState()})}},{key:"destroyCarousel",value:function(){this.state.initialized&&(this.unbindEvents(),this.destroyAutoPlay())}},{key:"setupAutoPlay",value:function(){this.autoPlay();var L=this.carouselWrapperRef;this.props.stopOnHover&&L&&(L.addEventListener("mouseenter",this.stopOnHover),L.addEventListener("mouseleave",this.startOnLeave))}},{key:"destroyAutoPlay",value:function(){this.clearAutoPlay();var L=this.carouselWrapperRef;this.props.stopOnHover&&L&&(L.removeEventListener("mouseenter",this.stopOnHover),L.removeEventListener("mouseleave",this.startOnLeave))}},{key:"bindEvents",value:function(){(0,o.default)().addEventListener("resize",this.updateSizes),(0,o.default)().addEventListener("DOMContentLoaded",this.updateSizes),this.props.useKeyboardArrows&&(0,u.default)().addEventListener("keydown",this.navigateWithKeyboard)}},{key:"unbindEvents",value:function(){(0,o.default)().removeEventListener("resize",this.updateSizes),(0,o.default)().removeEventListener("DOMContentLoaded",this.updateSizes);var L=this.getInitialImage();L&&L.removeEventListener("load",this.setMountState),this.props.useKeyboardArrows&&(0,u.default)().removeEventListener("keydown",this.navigateWithKeyboard)}},{key:"forceFocus",value:function(){var L;(L=this.carouselWrapperRef)===null||L===void 0||L.focus()}},{key:"renderItems",value:function(L){var B=this;return this.props.children?e.Children.map(this.props.children,function(K,Q){var _e=Q===B.state.selectedItem,S=Q===B.state.previousItem,ne=_e&&B.state.selectedStyle||S&&B.state.prevStyle||B.state.slideStyle||{};B.props.centerMode&&B.props.axis==="horizontal"&&(ne=A(A({},ne),{},{minWidth:B.props.centerSlidePercentage+"%"})),B.state.swiping&&B.state.swipeMovementStarted&&(ne=A(A({},ne),{},{pointerEvents:"none"}));var ge={ref:function(Te){return B.setItemsRef(Te,Q)},key:"itemKey"+Q+(L?"clone":""),className:n.default.ITEM(!0,Q===B.state.selectedItem,Q===B.state.previousItem),onClick:B.handleClickItem.bind(B,Q,K),style:ne};return e.default.createElement("li",ge,B.props.renderItem(K,{isSelected:Q===B.state.selectedItem,isPrevious:Q===B.state.previousItem}))}):[]}},{key:"renderControls",value:function(){var L=this,B=this.props,K=B.showIndicators,Q=B.labels,_e=B.renderIndicator,S=B.children;return K?e.default.createElement("ul",{className:"control-dots"},e.Children.map(S,function(ne,ge){return _e&&_e(L.changeItem(ge),ge===L.state.selectedItem,ge,Q.item)})):null}},{key:"renderStatus",value:function(){return this.props.showStatus?e.default.createElement("p",{className:"carousel-status"},this.props.statusFormatter(this.state.selectedItem+1,e.Children.count(this.props.children))):null}},{key:"renderThumbs",value:function(){return!this.props.showThumbs||!this.props.children||e.Children.count(this.props.children)===0?null:e.default.createElement(i.default,{ref:this.setThumbsRef,onSelectItem:this.handleClickThumb,selectedItem:this.state.selectedItem,transitionTime:this.props.transitionTime,thumbWidth:this.props.thumbWidth,labels:this.props.labels,emulateTouch:this.props.emulateTouch},this.props.renderThumbs(this.props.children))}},{key:"render",value:function(){var L=this;if(!this.props.children||e.Children.count(this.props.children)===0)return null;var B=this.props.swipeable&&e.Children.count(this.props.children)>1,K=this.props.axis==="horizontal",Q=this.props.showArrows&&e.Children.count(this.props.children)>1,_e=Q&&(this.state.selectedItem>0||this.props.infiniteLoop)||!1,S=Q&&(this.state.selectedItem<e.Children.count(this.props.children)-1||this.props.infiniteLoop)||!1,ne=this.renderItems(!0),ge=ne.shift(),w=ne.pop(),Te={className:n.default.SLIDER(!0,this.state.swiping),onSwipeMove:this.onSwipeMove,onSwipeStart:this.onSwipeStart,onSwipeEnd:this.onSwipeEnd,style:this.state.itemListStyle,tolerance:this.props.swipeScrollTolerance},Re={};if(K){if(Te.onSwipeLeft=this.onSwipeForward,Te.onSwipeRight=this.onSwipeBackwards,this.props.dynamicHeight){var xe=this.getVariableItemHeight(this.state.selectedItem);Re.height=xe||"auto"}}else Te.onSwipeUp=this.props.verticalSwipe==="natural"?this.onSwipeBackwards:this.onSwipeForward,Te.onSwipeDown=this.props.verticalSwipe==="natural"?this.onSwipeForward:this.onSwipeBackwards,Te.style=A(A({},Te.style),{},{height:this.state.itemSize}),Re.height=this.state.itemSize;return e.default.createElement("div",{"aria-label":this.props.ariaLabel,className:n.default.ROOT(this.props.className),ref:this.setCarouselWrapperRef,tabIndex:this.props.useKeyboardArrows?0:void 0},e.default.createElement("div",{className:n.default.CAROUSEL(!0),style:{width:this.props.width}},this.renderControls(),this.props.renderArrowPrev(this.onClickPrev,_e,this.props.labels.leftArrow),e.default.createElement("div",{className:n.default.WRAPPER(!0,this.props.axis),style:Re},B?e.default.createElement(t.default,b({tagName:"ul",innerRef:this.setListRef},Te,{allowMouseEvents:this.props.emulateTouch}),this.props.infiniteLoop&&w,this.renderItems(),this.props.infiniteLoop&&ge):e.default.createElement("ul",{className:n.default.SLIDER(!0,this.state.swiping),ref:function(Qe){return L.setListRef(Qe)},style:this.state.itemListStyle||{}},this.props.infiniteLoop&&w,this.renderItems(),this.props.infiniteLoop&&ge)),this.props.renderArrowNext(this.onClickNext,S,this.props.labels.rightArrow),this.renderStatus()),this.renderThumbs())}}]),$}(e.default.Component);return No.default=z,q(z,"displayName","Carousel"),q(z,"defaultProps",{ariaLabel:void 0,axis:"horizontal",centerSlidePercentage:80,interval:3e3,labels:{leftArrow:"previous slide / item",rightArrow:"next slide / item",item:"slide item"},onClickItem:l.noop,onClickThumb:l.noop,onChange:l.noop,onSwipeStart:function(){},onSwipeEnd:function(){},onSwipeMove:function(){return!1},preventMovementUntilSwipeScrollTolerance:!1,renderArrowPrev:function(F,$,Z){return e.default.createElement("button",{type:"button","aria-label":Z,className:n.default.ARROW_PREV(!$),onClick:F})},renderArrowNext:function(F,$,Z){return e.default.createElement("button",{type:"button","aria-label":Z,className:n.default.ARROW_NEXT(!$),onClick:F})},renderIndicator:function(F,$,Z,L){return e.default.createElement("li",{className:n.default.DOT($),onClick:F,onKeyDown:F,value:Z,key:Z,role:"button",tabIndex:0,"aria-label":"".concat(L," ").concat(Z+1)})},renderItem:function(F){return F},renderThumbs:function(F){var $=e.Children.map(F,function(Z){var L=Z;if(Z.type!=="img"&&(L=e.Children.toArray(Z.props.children).find(function(B){return B.type==="img"})),!!L)return L});return $.filter(function(Z){return Z}).length===0?(console.warn("No images found! Can't build the thumb list without images. If you don't need thumbs, set showThumbs={false} in the Carousel. Note that it's not possible to get images rendered inside custom components. More info at https://github.com/leandrowd/react-responsive-carousel/blob/master/TROUBLESHOOTING.md"),[]):$},statusFormatter:l.defaultStatusFormatter,selectedItem:0,showArrows:!0,showIndicators:!0,showStatus:!0,showThumbs:!0,stopOnHover:!0,swipeScrollTolerance:5,swipeable:!0,transitionTime:350,verticalSwipe:"standard",width:"100%",animationHandler:"slide",swipeAnimationHandler:f.slideSwipeAnimationHandler,stopSwipingHandler:f.slideStopSwipingHandler}),No}var UA={},HA;function X4(){return HA||(HA=1),UA}var zA;function K4(){return zA||(zA=1,function(e){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"Carousel",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"CarouselProps",{enumerable:!0,get:function(){return n.CarouselProps}}),Object.defineProperty(e,"Thumbs",{enumerable:!0,get:function(){return i.default}});var t=u(G4()),n=X4(),i=u(qv());function u(o){return o&&o.__esModule?o:{default:o}}}($m)),$m}var Bj=K4();function Gv(e){var t,n,i="";if(typeof e=="string"||typeof e=="number")i+=e;else if(typeof e=="object")if(Array.isArray(e)){var u=e.length;for(t=0;t<u;t++)e[t]&&(n=Gv(e[t]))&&(i&&(i+=" "),i+=n)}else for(n in e)e[n]&&(i&&(i+=" "),i+=n);return i}function Uj(){for(var e,t,n=0,i="",u=arguments.length;n<u;n++)(e=arguments[n])&&(t=Gv(e))&&(i&&(i+=" "),i+=t);return i}const vg="-",W4=e=>{const t=$4(e),{conflictingClassGroups:n,conflictingClassGroupModifiers:i}=e;return{getClassGroupId:l=>{const f=l.split(vg);return f[0]===""&&f.length!==1&&f.shift(),Xv(f,t)||Q4(l)},getConflictingClassGroupIds:(l,f)=>{const d=n[l]||[];return f&&i[l]?[...d,...i[l]]:d}}},Xv=(e,t)=>{if(e.length===0)return t.classGroupId;const n=e[0],i=t.nextPart.get(n),u=i?Xv(e.slice(1),i):void 0;if(u)return u;if(t.validators.length===0)return;const o=e.join(vg);return t.validators.find(({validator:l})=>l(o))?.classGroupId},VA=/^\[(.+)\]$/,Q4=e=>{if(VA.test(e)){const t=VA.exec(e)[1],n=t?.substring(0,t.indexOf(":"));if(n)return"arbitrary.."+n}},$4=e=>{const{theme:t,classGroups:n}=e,i={nextPart:new Map,validators:[]};for(const u in n)i0(n[u],i,u,t);return i},i0=(e,t,n,i)=>{e.forEach(u=>{if(typeof u=="string"){const o=u===""?t:jA(t,u);o.classGroupId=n;return}if(typeof u=="function"){if(Z4(u)){i0(u(i),t,n,i);return}t.validators.push({validator:u,classGroupId:n});return}Object.entries(u).forEach(([o,l])=>{i0(l,jA(t,o),n,i)})})},jA=(e,t)=>{let n=e;return t.split(vg).forEach(i=>{n.nextPart.has(i)||n.nextPart.set(i,{nextPart:new Map,validators:[]}),n=n.nextPart.get(i)}),n},Z4=e=>e.isThemeGetter,J4=e=>{if(e<1)return{get:()=>{},set:()=>{}};let t=0,n=new Map,i=new Map;const u=(o,l)=>{n.set(o,l),t++,t>e&&(t=0,i=n,n=new Map)};return{get(o){let l=n.get(o);if(l!==void 0)return l;if((l=i.get(o))!==void 0)return u(o,l),l},set(o,l){n.has(o)?n.set(o,l):u(o,l)}}},a0="!",u0=":",eM=u0.length,tM=e=>{const{prefix:t,experimentalParseClassName:n}=e;let i=u=>{const o=[];let l=0,f=0,d=0,h;for(let A=0;A<u.length;A++){let _=u[A];if(l===0&&f===0){if(_===u0){o.push(u.slice(d,A)),d=A+eM;continue}if(_==="/"){h=A;continue}}_==="["?l++:_==="]"?l--:_==="("?f++:_===")"&&f--}const p=o.length===0?u:u.substring(d),g=nM(p),b=g!==p,T=h&&h>d?h-d:void 0;return{modifiers:o,hasImportantModifier:b,baseClassName:g,maybePostfixModifierPosition:T}};if(t){const u=t+u0,o=i;i=l=>l.startsWith(u)?o(l.substring(u.length)):{isExternal:!0,modifiers:[],hasImportantModifier:!1,baseClassName:l,maybePostfixModifierPosition:void 0}}if(n){const u=i;i=o=>n({className:o,parseClassName:u})}return i},nM=e=>e.endsWith(a0)?e.substring(0,e.length-1):e.startsWith(a0)?e.substring(1):e,rM=e=>{const t=Object.fromEntries(e.orderSensitiveModifiers.map(i=>[i,!0]));return i=>{if(i.length<=1)return i;const u=[];let o=[];return i.forEach(l=>{l[0]==="["||t[l]?(u.push(...o.sort(),l),o=[]):o.push(l)}),u.push(...o.sort()),u}},iM=e=>({cache:J4(e.cacheSize),parseClassName:tM(e),sortModifiers:rM(e),...W4(e)}),aM=/\s+/,uM=(e,t)=>{const{parseClassName:n,getClassGroupId:i,getConflictingClassGroupIds:u,sortModifiers:o}=t,l=[],f=e.trim().split(aM);let d="";for(let h=f.length-1;h>=0;h-=1){const p=f[h],{isExternal:g,modifiers:b,hasImportantModifier:T,baseClassName:A,maybePostfixModifierPosition:_}=n(p);if(g){d=p+(d.length>0?" "+d:d);continue}let O=!!_,C=i(O?A.substring(0,_):A);if(!C){if(!O){d=p+(d.length>0?" "+d:d);continue}if(C=i(A),!C){d=p+(d.length>0?" "+d:d);continue}O=!1}const N=o(b).join(":"),R=T?N+a0:N,Y=R+C;if(l.includes(Y))continue;l.push(Y);const M=u(C,O);for(let v=0;v<M.length;++v){const J=M[v];l.push(R+J)}d=p+(d.length>0?" "+d:d)}return d};function sM(){let e=0,t,n,i="";for(;e<arguments.length;)(t=arguments[e++])&&(n=Kv(t))&&(i&&(i+=" "),i+=n);return i}const Kv=e=>{if(typeof e=="string")return e;let t,n="";for(let i=0;i<e.length;i++)e[i]&&(t=Kv(e[i]))&&(n&&(n+=" "),n+=t);return n};function oM(e,...t){let n,i,u,o=l;function l(d){const h=t.reduce((p,g)=>g(p),e());return n=iM(h),i=n.cache.get,u=n.cache.set,o=f,f(d)}function f(d){const h=i(d);if(h)return h;const p=uM(d,n);return u(d,p),p}return function(){return o(sM.apply(null,arguments))}}const bn=e=>{const t=n=>n[e]||[];return t.isThemeGetter=!0,t},Wv=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Qv=/^\((?:(\w[\w-]*):)?(.+)\)$/i,lM=/^\d+\/\d+$/,cM=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,fM=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,dM=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,hM=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,mM=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,Qu=e=>lM.test(e),at=e=>!!e&&!Number.isNaN(Number(e)),da=e=>!!e&&Number.isInteger(Number(e)),np=e=>e.endsWith("%")&&at(e.slice(0,-1)),Pi=e=>cM.test(e),pM=()=>!0,gM=e=>fM.test(e)&&!dM.test(e),$v=()=>!1,EM=e=>hM.test(e),yM=e=>mM.test(e),bM=e=>!Me(e)&&!Ie(e),TM=e=>ys(e,eC,$v),Me=e=>Wv.test(e),Wa=e=>ys(e,tC,gM),rp=e=>ys(e,CM,at),qA=e=>ys(e,Zv,$v),AM=e=>ys(e,Jv,yM),sf=e=>ys(e,nC,EM),Ie=e=>Qv.test(e),Bo=e=>bs(e,tC),SM=e=>bs(e,_M),YA=e=>bs(e,Zv),DM=e=>bs(e,eC),vM=e=>bs(e,Jv),of=e=>bs(e,nC,!0),ys=(e,t,n)=>{const i=Wv.exec(e);return i?i[1]?t(i[1]):n(i[2]):!1},bs=(e,t,n=!1)=>{const i=Qv.exec(e);return i?i[1]?t(i[1]):n:!1},Zv=e=>e==="position"||e==="percentage",Jv=e=>e==="image"||e==="url",eC=e=>e==="length"||e==="size"||e==="bg-size",tC=e=>e==="length",CM=e=>e==="number",_M=e=>e==="family-name",nC=e=>e==="shadow",xM=()=>{const e=bn("color"),t=bn("font"),n=bn("text"),i=bn("font-weight"),u=bn("tracking"),o=bn("leading"),l=bn("breakpoint"),f=bn("container"),d=bn("spacing"),h=bn("radius"),p=bn("shadow"),g=bn("inset-shadow"),b=bn("text-shadow"),T=bn("drop-shadow"),A=bn("blur"),_=bn("perspective"),O=bn("aspect"),C=bn("ease"),N=bn("animate"),R=()=>["auto","avoid","all","avoid-page","page","left","right","column"],Y=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],M=()=>[...Y(),Ie,Me],v=()=>["auto","hidden","clip","visible","scroll"],J=()=>["auto","contain","none"],P=()=>[Ie,Me,d],q=()=>[Qu,"full","auto",...P()],z=()=>[da,"none","subgrid",Ie,Me],V=()=>["auto",{span:["full",da,Ie,Me]},da,Ie,Me],F=()=>[da,"auto",Ie,Me],$=()=>["auto","min","max","fr",Ie,Me],Z=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],L=()=>["start","end","center","stretch","center-safe","end-safe"],B=()=>["auto",...P()],K=()=>[Qu,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...P()],Q=()=>[e,Ie,Me],_e=()=>[...Y(),YA,qA,{position:[Ie,Me]}],S=()=>["no-repeat",{repeat:["","x","y","space","round"]}],ne=()=>["auto","cover","contain",DM,TM,{size:[Ie,Me]}],ge=()=>[np,Bo,Wa],w=()=>["","none","full",h,Ie,Me],Te=()=>["",at,Bo,Wa],Re=()=>["solid","dashed","dotted","double"],xe=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],We=()=>[at,np,YA,qA],Qe=()=>["","none",A,Ie,Me],Nt=()=>["none",at,Ie,Me],mt=()=>["none",at,Ie,Me],qt=()=>[at,Ie,Me],ln=()=>[Qu,"full",...P()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[Pi],breakpoint:[Pi],color:[pM],container:[Pi],"drop-shadow":[Pi],ease:["in","out","in-out"],font:[bM],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[Pi],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[Pi],shadow:[Pi],spacing:["px",at],text:[Pi],"text-shadow":[Pi],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",Qu,Me,Ie,O]}],container:["container"],columns:[{columns:[at,Me,Ie,f]}],"break-after":[{"break-after":R()}],"break-before":[{"break-before":R()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:M()}],overflow:[{overflow:v()}],"overflow-x":[{"overflow-x":v()}],"overflow-y":[{"overflow-y":v()}],overscroll:[{overscroll:J()}],"overscroll-x":[{"overscroll-x":J()}],"overscroll-y":[{"overscroll-y":J()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:q()}],"inset-x":[{"inset-x":q()}],"inset-y":[{"inset-y":q()}],start:[{start:q()}],end:[{end:q()}],top:[{top:q()}],right:[{right:q()}],bottom:[{bottom:q()}],left:[{left:q()}],visibility:["visible","invisible","collapse"],z:[{z:[da,"auto",Ie,Me]}],basis:[{basis:[Qu,"full","auto",f,...P()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[at,Qu,"auto","initial","none",Me]}],grow:[{grow:["",at,Ie,Me]}],shrink:[{shrink:["",at,Ie,Me]}],order:[{order:[da,"first","last","none",Ie,Me]}],"grid-cols":[{"grid-cols":z()}],"col-start-end":[{col:V()}],"col-start":[{"col-start":F()}],"col-end":[{"col-end":F()}],"grid-rows":[{"grid-rows":z()}],"row-start-end":[{row:V()}],"row-start":[{"row-start":F()}],"row-end":[{"row-end":F()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":$()}],"auto-rows":[{"auto-rows":$()}],gap:[{gap:P()}],"gap-x":[{"gap-x":P()}],"gap-y":[{"gap-y":P()}],"justify-content":[{justify:[...Z(),"normal"]}],"justify-items":[{"justify-items":[...L(),"normal"]}],"justify-self":[{"justify-self":["auto",...L()]}],"align-content":[{content:["normal",...Z()]}],"align-items":[{items:[...L(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...L(),{baseline:["","last"]}]}],"place-content":[{"place-content":Z()}],"place-items":[{"place-items":[...L(),"baseline"]}],"place-self":[{"place-self":["auto",...L()]}],p:[{p:P()}],px:[{px:P()}],py:[{py:P()}],ps:[{ps:P()}],pe:[{pe:P()}],pt:[{pt:P()}],pr:[{pr:P()}],pb:[{pb:P()}],pl:[{pl:P()}],m:[{m:B()}],mx:[{mx:B()}],my:[{my:B()}],ms:[{ms:B()}],me:[{me:B()}],mt:[{mt:B()}],mr:[{mr:B()}],mb:[{mb:B()}],ml:[{ml:B()}],"space-x":[{"space-x":P()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":P()}],"space-y-reverse":["space-y-reverse"],size:[{size:K()}],w:[{w:[f,"screen",...K()]}],"min-w":[{"min-w":[f,"screen","none",...K()]}],"max-w":[{"max-w":[f,"screen","none","prose",{screen:[l]},...K()]}],h:[{h:["screen","lh",...K()]}],"min-h":[{"min-h":["screen","lh","none",...K()]}],"max-h":[{"max-h":["screen","lh",...K()]}],"font-size":[{text:["base",n,Bo,Wa]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[i,Ie,rp]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",np,Me]}],"font-family":[{font:[SM,Me,t]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[u,Ie,Me]}],"line-clamp":[{"line-clamp":[at,"none",Ie,rp]}],leading:[{leading:[o,...P()]}],"list-image":[{"list-image":["none",Ie,Me]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",Ie,Me]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:Q()}],"text-color":[{text:Q()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...Re(),"wavy"]}],"text-decoration-thickness":[{decoration:[at,"from-font","auto",Ie,Wa]}],"text-decoration-color":[{decoration:Q()}],"underline-offset":[{"underline-offset":[at,"auto",Ie,Me]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:P()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",Ie,Me]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",Ie,Me]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:_e()}],"bg-repeat":[{bg:S()}],"bg-size":[{bg:ne()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},da,Ie,Me],radial:["",Ie,Me],conic:[da,Ie,Me]},vM,AM]}],"bg-color":[{bg:Q()}],"gradient-from-pos":[{from:ge()}],"gradient-via-pos":[{via:ge()}],"gradient-to-pos":[{to:ge()}],"gradient-from":[{from:Q()}],"gradient-via":[{via:Q()}],"gradient-to":[{to:Q()}],rounded:[{rounded:w()}],"rounded-s":[{"rounded-s":w()}],"rounded-e":[{"rounded-e":w()}],"rounded-t":[{"rounded-t":w()}],"rounded-r":[{"rounded-r":w()}],"rounded-b":[{"rounded-b":w()}],"rounded-l":[{"rounded-l":w()}],"rounded-ss":[{"rounded-ss":w()}],"rounded-se":[{"rounded-se":w()}],"rounded-ee":[{"rounded-ee":w()}],"rounded-es":[{"rounded-es":w()}],"rounded-tl":[{"rounded-tl":w()}],"rounded-tr":[{"rounded-tr":w()}],"rounded-br":[{"rounded-br":w()}],"rounded-bl":[{"rounded-bl":w()}],"border-w":[{border:Te()}],"border-w-x":[{"border-x":Te()}],"border-w-y":[{"border-y":Te()}],"border-w-s":[{"border-s":Te()}],"border-w-e":[{"border-e":Te()}],"border-w-t":[{"border-t":Te()}],"border-w-r":[{"border-r":Te()}],"border-w-b":[{"border-b":Te()}],"border-w-l":[{"border-l":Te()}],"divide-x":[{"divide-x":Te()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":Te()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...Re(),"hidden","none"]}],"divide-style":[{divide:[...Re(),"hidden","none"]}],"border-color":[{border:Q()}],"border-color-x":[{"border-x":Q()}],"border-color-y":[{"border-y":Q()}],"border-color-s":[{"border-s":Q()}],"border-color-e":[{"border-e":Q()}],"border-color-t":[{"border-t":Q()}],"border-color-r":[{"border-r":Q()}],"border-color-b":[{"border-b":Q()}],"border-color-l":[{"border-l":Q()}],"divide-color":[{divide:Q()}],"outline-style":[{outline:[...Re(),"none","hidden"]}],"outline-offset":[{"outline-offset":[at,Ie,Me]}],"outline-w":[{outline:["",at,Bo,Wa]}],"outline-color":[{outline:Q()}],shadow:[{shadow:["","none",p,of,sf]}],"shadow-color":[{shadow:Q()}],"inset-shadow":[{"inset-shadow":["none",g,of,sf]}],"inset-shadow-color":[{"inset-shadow":Q()}],"ring-w":[{ring:Te()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:Q()}],"ring-offset-w":[{"ring-offset":[at,Wa]}],"ring-offset-color":[{"ring-offset":Q()}],"inset-ring-w":[{"inset-ring":Te()}],"inset-ring-color":[{"inset-ring":Q()}],"text-shadow":[{"text-shadow":["none",b,of,sf]}],"text-shadow-color":[{"text-shadow":Q()}],opacity:[{opacity:[at,Ie,Me]}],"mix-blend":[{"mix-blend":[...xe(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":xe()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[at]}],"mask-image-linear-from-pos":[{"mask-linear-from":We()}],"mask-image-linear-to-pos":[{"mask-linear-to":We()}],"mask-image-linear-from-color":[{"mask-linear-from":Q()}],"mask-image-linear-to-color":[{"mask-linear-to":Q()}],"mask-image-t-from-pos":[{"mask-t-from":We()}],"mask-image-t-to-pos":[{"mask-t-to":We()}],"mask-image-t-from-color":[{"mask-t-from":Q()}],"mask-image-t-to-color":[{"mask-t-to":Q()}],"mask-image-r-from-pos":[{"mask-r-from":We()}],"mask-image-r-to-pos":[{"mask-r-to":We()}],"mask-image-r-from-color":[{"mask-r-from":Q()}],"mask-image-r-to-color":[{"mask-r-to":Q()}],"mask-image-b-from-pos":[{"mask-b-from":We()}],"mask-image-b-to-pos":[{"mask-b-to":We()}],"mask-image-b-from-color":[{"mask-b-from":Q()}],"mask-image-b-to-color":[{"mask-b-to":Q()}],"mask-image-l-from-pos":[{"mask-l-from":We()}],"mask-image-l-to-pos":[{"mask-l-to":We()}],"mask-image-l-from-color":[{"mask-l-from":Q()}],"mask-image-l-to-color":[{"mask-l-to":Q()}],"mask-image-x-from-pos":[{"mask-x-from":We()}],"mask-image-x-to-pos":[{"mask-x-to":We()}],"mask-image-x-from-color":[{"mask-x-from":Q()}],"mask-image-x-to-color":[{"mask-x-to":Q()}],"mask-image-y-from-pos":[{"mask-y-from":We()}],"mask-image-y-to-pos":[{"mask-y-to":We()}],"mask-image-y-from-color":[{"mask-y-from":Q()}],"mask-image-y-to-color":[{"mask-y-to":Q()}],"mask-image-radial":[{"mask-radial":[Ie,Me]}],"mask-image-radial-from-pos":[{"mask-radial-from":We()}],"mask-image-radial-to-pos":[{"mask-radial-to":We()}],"mask-image-radial-from-color":[{"mask-radial-from":Q()}],"mask-image-radial-to-color":[{"mask-radial-to":Q()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":Y()}],"mask-image-conic-pos":[{"mask-conic":[at]}],"mask-image-conic-from-pos":[{"mask-conic-from":We()}],"mask-image-conic-to-pos":[{"mask-conic-to":We()}],"mask-image-conic-from-color":[{"mask-conic-from":Q()}],"mask-image-conic-to-color":[{"mask-conic-to":Q()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:_e()}],"mask-repeat":[{mask:S()}],"mask-size":[{mask:ne()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",Ie,Me]}],filter:[{filter:["","none",Ie,Me]}],blur:[{blur:Qe()}],brightness:[{brightness:[at,Ie,Me]}],contrast:[{contrast:[at,Ie,Me]}],"drop-shadow":[{"drop-shadow":["","none",T,of,sf]}],"drop-shadow-color":[{"drop-shadow":Q()}],grayscale:[{grayscale:["",at,Ie,Me]}],"hue-rotate":[{"hue-rotate":[at,Ie,Me]}],invert:[{invert:["",at,Ie,Me]}],saturate:[{saturate:[at,Ie,Me]}],sepia:[{sepia:["",at,Ie,Me]}],"backdrop-filter":[{"backdrop-filter":["","none",Ie,Me]}],"backdrop-blur":[{"backdrop-blur":Qe()}],"backdrop-brightness":[{"backdrop-brightness":[at,Ie,Me]}],"backdrop-contrast":[{"backdrop-contrast":[at,Ie,Me]}],"backdrop-grayscale":[{"backdrop-grayscale":["",at,Ie,Me]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[at,Ie,Me]}],"backdrop-invert":[{"backdrop-invert":["",at,Ie,Me]}],"backdrop-opacity":[{"backdrop-opacity":[at,Ie,Me]}],"backdrop-saturate":[{"backdrop-saturate":[at,Ie,Me]}],"backdrop-sepia":[{"backdrop-sepia":["",at,Ie,Me]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":P()}],"border-spacing-x":[{"border-spacing-x":P()}],"border-spacing-y":[{"border-spacing-y":P()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",Ie,Me]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[at,"initial",Ie,Me]}],ease:[{ease:["linear","initial",C,Ie,Me]}],delay:[{delay:[at,Ie,Me]}],animate:[{animate:["none",N,Ie,Me]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[_,Ie,Me]}],"perspective-origin":[{"perspective-origin":M()}],rotate:[{rotate:Nt()}],"rotate-x":[{"rotate-x":Nt()}],"rotate-y":[{"rotate-y":Nt()}],"rotate-z":[{"rotate-z":Nt()}],scale:[{scale:mt()}],"scale-x":[{"scale-x":mt()}],"scale-y":[{"scale-y":mt()}],"scale-z":[{"scale-z":mt()}],"scale-3d":["scale-3d"],skew:[{skew:qt()}],"skew-x":[{"skew-x":qt()}],"skew-y":[{"skew-y":qt()}],transform:[{transform:[Ie,Me,"","none","gpu","cpu"]}],"transform-origin":[{origin:M()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:ln()}],"translate-x":[{"translate-x":ln()}],"translate-y":[{"translate-y":ln()}],"translate-z":[{"translate-z":ln()}],"translate-none":["translate-none"],accent:[{accent:Q()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:Q()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",Ie,Me]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":P()}],"scroll-mx":[{"scroll-mx":P()}],"scroll-my":[{"scroll-my":P()}],"scroll-ms":[{"scroll-ms":P()}],"scroll-me":[{"scroll-me":P()}],"scroll-mt":[{"scroll-mt":P()}],"scroll-mr":[{"scroll-mr":P()}],"scroll-mb":[{"scroll-mb":P()}],"scroll-ml":[{"scroll-ml":P()}],"scroll-p":[{"scroll-p":P()}],"scroll-px":[{"scroll-px":P()}],"scroll-py":[{"scroll-py":P()}],"scroll-ps":[{"scroll-ps":P()}],"scroll-pe":[{"scroll-pe":P()}],"scroll-pt":[{"scroll-pt":P()}],"scroll-pr":[{"scroll-pr":P()}],"scroll-pb":[{"scroll-pb":P()}],"scroll-pl":[{"scroll-pl":P()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",Ie,Me]}],fill:[{fill:["none",...Q()]}],"stroke-w":[{stroke:[at,Bo,Wa,rp]}],stroke:[{stroke:["none",...Q()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}},Hj=oM(xM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const RM=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),wM=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(t,n,i)=>i?i.toUpperCase():n.toLowerCase()),GA=e=>{const t=wM(e);return t.charAt(0).toUpperCase()+t.slice(1)},rC=(...e)=>e.filter((t,n,i)=>!!t&&t.trim()!==""&&i.indexOf(t)===n).join(" ").trim(),OM=e=>{for(const t in e)if(t.startsWith("aria-")||t==="role"||t==="title")return!0};/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */var NM={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const kM=W.forwardRef(({color:e="currentColor",size:t=24,strokeWidth:n=2,absoluteStrokeWidth:i,className:u="",children:o,iconNode:l,...f},d)=>W.createElement("svg",{ref:d,...NM,width:t,height:t,stroke:e,strokeWidth:i?Number(n)*24/Number(t):n,className:rC("lucide",u),...!o&&!OM(f)&&{"aria-hidden":"true"},...f},[...l.map(([h,p])=>W.createElement(h,p)),...Array.isArray(o)?o:[o]]));/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Ot=(e,t)=>{const n=W.forwardRef(({className:i,...u},o)=>W.createElement(kM,{ref:o,iconNode:t,className:rC(`lucide-${RM(GA(e))}`,`lucide-${e}`,i),...u}));return n.displayName=GA(e),n};/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const LM=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],zj=Ot("arrow-left",LM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const MM=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]],Vj=Ot("arrow-right",MM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const IM=[["path",{d:"M12 7v14",key:"1akyts"}],["path",{d:"M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z",key:"ruj8y"}]],jj=Ot("book-open",IM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const PM=[["rect",{width:"16",height:"20",x:"4",y:"2",rx:"2",ry:"2",key:"76otgf"}],["path",{d:"M9 22v-4h6v4",key:"r93iot"}],["path",{d:"M8 6h.01",key:"1dz90k"}],["path",{d:"M16 6h.01",key:"1x0f13"}],["path",{d:"M12 6h.01",key:"1vi96p"}],["path",{d:"M12 10h.01",key:"1nrarc"}],["path",{d:"M12 14h.01",key:"1etili"}],["path",{d:"M16 10h.01",key:"1m94wz"}],["path",{d:"M16 14h.01",key:"1gbofw"}],["path",{d:"M8 10h.01",key:"19clt8"}],["path",{d:"M8 14h.01",key:"6423bh"}]],qj=Ot("building",PM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const FM=[["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M16 2v4",key:"4m81vk"}],["path",{d:"M3 10h18",key:"8toen8"}],["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M17 14h-6",key:"bkmgh3"}],["path",{d:"M13 18H7",key:"bb0bb7"}],["path",{d:"M7 14h.01",key:"1qa3f1"}],["path",{d:"M17 18h.01",key:"1bdyru"}]],Yj=Ot("calendar-range",FM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const BM=[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}]],Gj=Ot("calendar",BM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const UM=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],Xj=Ot("chevron-down",UM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const HM=[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]],Kj=Ot("chevron-right",HM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const zM=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]],Wj=Ot("circle-alert",zM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const VM=[["path",{d:"m16 18 6-6-6-6",key:"eg8j8"}],["path",{d:"m8 6-6 6 6 6",key:"ppft3o"}]],Qj=Ot("code",VM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const jM=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]],$j=Ot("external-link",jM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const qM=[["path",{d:"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z",key:"sc7q7i"}]],Zj=Ot("funnel",qM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const YM=[["circle",{cx:"12",cy:"18",r:"3",key:"1mpf1b"}],["circle",{cx:"6",cy:"6",r:"3",key:"1lh9wr"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["path",{d:"M18 9v2c0 .6-.4 1-1 1H7c-.6 0-1-.4-1-1V9",key:"1uq4wg"}],["path",{d:"M12 12v3",key:"158kv8"}]],Jj=Ot("git-fork",YM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const GM=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M3 9h18",key:"1pudct"}],["path",{d:"M3 15h18",key:"5xshup"}],["path",{d:"M9 3v18",key:"fh3hqa"}],["path",{d:"M15 3v18",key:"14nvp0"}]],eq=Ot("grid-3x3",GM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const XM=[["path",{d:"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8",key:"5wwlr5"}],["path",{d:"M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",key:"1d0kgt"}]],tq=Ot("house",XM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const KM=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],nq=Ot("info",KM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const WM=[["path",{d:"M3 12h.01",key:"nlz23k"}],["path",{d:"M3 18h.01",key:"1tta3j"}],["path",{d:"M3 6h.01",key:"1rqtza"}],["path",{d:"M8 12h13",key:"1za7za"}],["path",{d:"M8 18h13",key:"1lx6n3"}],["path",{d:"M8 6h13",key:"ik3vkj"}]],rq=Ot("list",WM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const QM=[["path",{d:"M7.9 20A9 9 0 1 0 4 16.1L2 22Z",key:"vv11sd"}]],iq=Ot("message-circle",QM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const $M=[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]],aq=Ot("search",$M);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const ZM=[["circle",{cx:"18",cy:"5",r:"3",key:"gq8acd"}],["circle",{cx:"6",cy:"12",r:"3",key:"w7nqdw"}],["circle",{cx:"18",cy:"19",r:"3",key:"1xt0gg"}],["line",{x1:"8.59",x2:"15.42",y1:"13.51",y2:"17.49",key:"47mynk"}],["line",{x1:"15.41",x2:"8.59",y1:"6.51",y2:"10.49",key:"1n3mei"}]],uq=Ot("share-2",ZM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const JM=[["path",{d:"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z",key:"4pj2yx"}],["path",{d:"M20 3v4",key:"1olli1"}],["path",{d:"M22 5h-4",key:"1gvqau"}],["path",{d:"M4 17v2",key:"vumght"}],["path",{d:"M5 18H3",key:"zchphs"}]],sq=Ot("sparkles",JM);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const eI=[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]],oq=Ot("star",eI);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const tI=[["path",{d:"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z",key:"vktsd0"}],["circle",{cx:"7.5",cy:"7.5",r:".5",fill:"currentColor",key:"kqv944"}]],lq=Ot("tag",tI);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const nI=[["path",{d:"M12 19h8",key:"baeox8"}],["path",{d:"m4 17 6-6-6-6",key:"1yngyt"}]],cq=Ot("terminal",nI);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const rI=[["path",{d:"M16 7h6v6",key:"box55l"}],["path",{d:"m22 7-8.5 8.5-5-5L2 17",key:"1t1m79"}]],fq=Ot("trending-up",rI);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const iI=[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]],dq=Ot("user",iI);/** + * @license lucide-react v0.525.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const aI=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744",key:"16gr8j"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}]],hq=Ot("users",aI);function XA(e){const t=[],n=String(e||"");let i=n.indexOf(","),u=0,o=!1;for(;!o;){i===-1&&(i=n.length,o=!0);const l=n.slice(u,i).trim();(l||!o)&&t.push(l),u=i+1,i=n.indexOf(",",u)}return t}function iC(e,t){const n={};return(e[e.length-1]===""?[...e,""]:e).join((n.padRight?" ":"")+","+(n.padLeft===!1?"":" ")).trim()}const uI=/^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,sI=/^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,oI={};function KA(e,t){return(oI.jsx?sI:uI).test(e)}const lI=/[ \t\n\f\r]/g;function cI(e){return typeof e=="object"?e.type==="text"?WA(e.value):!1:WA(e)}function WA(e){return e.replace(lI,"")===""}let Il=class{constructor(t,n,i){this.normal=n,this.property=t,i&&(this.space=i)}};Il.prototype.normal={};Il.prototype.property={};Il.prototype.space=void 0;function aC(e,t){const n={},i={};for(const u of e)Object.assign(n,u.property),Object.assign(i,u.normal);return new Il(n,i,t)}function Dl(e){return e.toLowerCase()}let ar=class{constructor(t,n){this.attribute=n,this.property=t}};ar.prototype.attribute="";ar.prototype.booleanish=!1;ar.prototype.boolean=!1;ar.prototype.commaOrSpaceSeparated=!1;ar.prototype.commaSeparated=!1;ar.prototype.defined=!1;ar.prototype.mustUseProperty=!1;ar.prototype.number=!1;ar.prototype.overloadedBoolean=!1;ar.prototype.property="";ar.prototype.spaceSeparated=!1;ar.prototype.space=void 0;let fI=0;const tt=hu(),hn=hu(),s0=hu(),De=hu(),It=hu(),os=hu(),gr=hu();function hu(){return 2**++fI}const o0=Object.freeze(Object.defineProperty({__proto__:null,boolean:tt,booleanish:hn,commaOrSpaceSeparated:gr,commaSeparated:os,number:De,overloadedBoolean:s0,spaceSeparated:It},Symbol.toStringTag,{value:"Module"})),ip=Object.keys(o0);let Cg=class extends ar{constructor(t,n,i,u){let o=-1;if(super(t,n),QA(this,"space",u),typeof i=="number")for(;++o<ip.length;){const l=ip[o];QA(this,ip[o],(i&o0[l])===o0[l])}}};Cg.prototype.defined=!0;function QA(e,t,n){n&&(e[t]=n)}function Ts(e){const t={},n={};for(const[i,u]of Object.entries(e.properties)){const o=new Cg(i,e.transform(e.attributes||{},i),u,e.space);e.mustUseProperty&&e.mustUseProperty.includes(i)&&(o.mustUseProperty=!0),t[i]=o,n[Dl(i)]=i,n[Dl(o.attribute)]=i}return new Il(t,n,e.space)}const uC=Ts({properties:{ariaActiveDescendant:null,ariaAtomic:hn,ariaAutoComplete:null,ariaBusy:hn,ariaChecked:hn,ariaColCount:De,ariaColIndex:De,ariaColSpan:De,ariaControls:It,ariaCurrent:null,ariaDescribedBy:It,ariaDetails:null,ariaDisabled:hn,ariaDropEffect:It,ariaErrorMessage:null,ariaExpanded:hn,ariaFlowTo:It,ariaGrabbed:hn,ariaHasPopup:null,ariaHidden:hn,ariaInvalid:null,ariaKeyShortcuts:null,ariaLabel:null,ariaLabelledBy:It,ariaLevel:De,ariaLive:null,ariaModal:hn,ariaMultiLine:hn,ariaMultiSelectable:hn,ariaOrientation:null,ariaOwns:It,ariaPlaceholder:null,ariaPosInSet:De,ariaPressed:hn,ariaReadOnly:hn,ariaRelevant:null,ariaRequired:hn,ariaRoleDescription:It,ariaRowCount:De,ariaRowIndex:De,ariaRowSpan:De,ariaSelected:hn,ariaSetSize:De,ariaSort:null,ariaValueMax:De,ariaValueMin:De,ariaValueNow:De,ariaValueText:null,role:null},transform(e,t){return t==="role"?t:"aria-"+t.slice(4).toLowerCase()}});function sC(e,t){return t in e?e[t]:t}function oC(e,t){return sC(e,t.toLowerCase())}const dI=Ts({attributes:{acceptcharset:"accept-charset",classname:"class",htmlfor:"for",httpequiv:"http-equiv"},mustUseProperty:["checked","multiple","muted","selected"],properties:{abbr:null,accept:os,acceptCharset:It,accessKey:It,action:null,allow:null,allowFullScreen:tt,allowPaymentRequest:tt,allowUserMedia:tt,alt:null,as:null,async:tt,autoCapitalize:null,autoComplete:It,autoFocus:tt,autoPlay:tt,blocking:It,capture:null,charSet:null,checked:tt,cite:null,className:It,cols:De,colSpan:null,content:null,contentEditable:hn,controls:tt,controlsList:It,coords:De|os,crossOrigin:null,data:null,dateTime:null,decoding:null,default:tt,defer:tt,dir:null,dirName:null,disabled:tt,download:s0,draggable:hn,encType:null,enterKeyHint:null,fetchPriority:null,form:null,formAction:null,formEncType:null,formMethod:null,formNoValidate:tt,formTarget:null,headers:It,height:De,hidden:s0,high:De,href:null,hrefLang:null,htmlFor:It,httpEquiv:It,id:null,imageSizes:null,imageSrcSet:null,inert:tt,inputMode:null,integrity:null,is:null,isMap:tt,itemId:null,itemProp:It,itemRef:It,itemScope:tt,itemType:It,kind:null,label:null,lang:null,language:null,list:null,loading:null,loop:tt,low:De,manifest:null,max:null,maxLength:De,media:null,method:null,min:null,minLength:De,multiple:tt,muted:tt,name:null,nonce:null,noModule:tt,noValidate:tt,onAbort:null,onAfterPrint:null,onAuxClick:null,onBeforeMatch:null,onBeforePrint:null,onBeforeToggle:null,onBeforeUnload:null,onBlur:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onContextLost:null,onContextMenu:null,onContextRestored:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnded:null,onError:null,onFocus:null,onFormData:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLanguageChange:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadEnd:null,onLoadStart:null,onMessage:null,onMessageError:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRejectionHandled:null,onReset:null,onResize:null,onScroll:null,onScrollEnd:null,onSecurityPolicyViolation:null,onSeeked:null,onSeeking:null,onSelect:null,onSlotChange:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnhandledRejection:null,onUnload:null,onVolumeChange:null,onWaiting:null,onWheel:null,open:tt,optimum:De,pattern:null,ping:It,placeholder:null,playsInline:tt,popover:null,popoverTarget:null,popoverTargetAction:null,poster:null,preload:null,readOnly:tt,referrerPolicy:null,rel:It,required:tt,reversed:tt,rows:De,rowSpan:De,sandbox:It,scope:null,scoped:tt,seamless:tt,selected:tt,shadowRootClonable:tt,shadowRootDelegatesFocus:tt,shadowRootMode:null,shape:null,size:De,sizes:null,slot:null,span:De,spellCheck:hn,src:null,srcDoc:null,srcLang:null,srcSet:null,start:De,step:null,style:null,tabIndex:De,target:null,title:null,translate:null,type:null,typeMustMatch:tt,useMap:null,value:hn,width:De,wrap:null,writingSuggestions:null,align:null,aLink:null,archive:It,axis:null,background:null,bgColor:null,border:De,borderColor:null,bottomMargin:De,cellPadding:null,cellSpacing:null,char:null,charOff:null,classId:null,clear:null,code:null,codeBase:null,codeType:null,color:null,compact:tt,declare:tt,event:null,face:null,frame:null,frameBorder:null,hSpace:De,leftMargin:De,link:null,longDesc:null,lowSrc:null,marginHeight:De,marginWidth:De,noResize:tt,noHref:tt,noShade:tt,noWrap:tt,object:null,profile:null,prompt:null,rev:null,rightMargin:De,rules:null,scheme:null,scrolling:hn,standby:null,summary:null,text:null,topMargin:De,valueType:null,version:null,vAlign:null,vLink:null,vSpace:De,allowTransparency:null,autoCorrect:null,autoSave:null,disablePictureInPicture:tt,disableRemotePlayback:tt,prefix:null,property:null,results:De,security:null,unselectable:null},space:"html",transform:oC}),hI=Ts({attributes:{accentHeight:"accent-height",alignmentBaseline:"alignment-baseline",arabicForm:"arabic-form",baselineShift:"baseline-shift",capHeight:"cap-height",className:"class",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorProfile:"color-profile",colorRendering:"color-rendering",crossOrigin:"crossorigin",dataType:"datatype",dominantBaseline:"dominant-baseline",enableBackground:"enable-background",fillOpacity:"fill-opacity",fillRule:"fill-rule",floodColor:"flood-color",floodOpacity:"flood-opacity",fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",glyphName:"glyph-name",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",hrefLang:"hreflang",horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",horizOriginY:"horiz-origin-y",imageRendering:"image-rendering",letterSpacing:"letter-spacing",lightingColor:"lighting-color",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",navDown:"nav-down",navDownLeft:"nav-down-left",navDownRight:"nav-down-right",navLeft:"nav-left",navNext:"nav-next",navPrev:"nav-prev",navRight:"nav-right",navUp:"nav-up",navUpLeft:"nav-up-left",navUpRight:"nav-up-right",onAbort:"onabort",onActivate:"onactivate",onAfterPrint:"onafterprint",onBeforePrint:"onbeforeprint",onBegin:"onbegin",onCancel:"oncancel",onCanPlay:"oncanplay",onCanPlayThrough:"oncanplaythrough",onChange:"onchange",onClick:"onclick",onClose:"onclose",onCopy:"oncopy",onCueChange:"oncuechange",onCut:"oncut",onDblClick:"ondblclick",onDrag:"ondrag",onDragEnd:"ondragend",onDragEnter:"ondragenter",onDragExit:"ondragexit",onDragLeave:"ondragleave",onDragOver:"ondragover",onDragStart:"ondragstart",onDrop:"ondrop",onDurationChange:"ondurationchange",onEmptied:"onemptied",onEnd:"onend",onEnded:"onended",onError:"onerror",onFocus:"onfocus",onFocusIn:"onfocusin",onFocusOut:"onfocusout",onHashChange:"onhashchange",onInput:"oninput",onInvalid:"oninvalid",onKeyDown:"onkeydown",onKeyPress:"onkeypress",onKeyUp:"onkeyup",onLoad:"onload",onLoadedData:"onloadeddata",onLoadedMetadata:"onloadedmetadata",onLoadStart:"onloadstart",onMessage:"onmessage",onMouseDown:"onmousedown",onMouseEnter:"onmouseenter",onMouseLeave:"onmouseleave",onMouseMove:"onmousemove",onMouseOut:"onmouseout",onMouseOver:"onmouseover",onMouseUp:"onmouseup",onMouseWheel:"onmousewheel",onOffline:"onoffline",onOnline:"ononline",onPageHide:"onpagehide",onPageShow:"onpageshow",onPaste:"onpaste",onPause:"onpause",onPlay:"onplay",onPlaying:"onplaying",onPopState:"onpopstate",onProgress:"onprogress",onRateChange:"onratechange",onRepeat:"onrepeat",onReset:"onreset",onResize:"onresize",onScroll:"onscroll",onSeeked:"onseeked",onSeeking:"onseeking",onSelect:"onselect",onShow:"onshow",onStalled:"onstalled",onStorage:"onstorage",onSubmit:"onsubmit",onSuspend:"onsuspend",onTimeUpdate:"ontimeupdate",onToggle:"ontoggle",onUnload:"onunload",onVolumeChange:"onvolumechange",onWaiting:"onwaiting",onZoom:"onzoom",overlinePosition:"overline-position",overlineThickness:"overline-thickness",paintOrder:"paint-order",panose1:"panose-1",pointerEvents:"pointer-events",referrerPolicy:"referrerpolicy",renderingIntent:"rendering-intent",shapeRendering:"shape-rendering",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",strokeDashArray:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeLineCap:"stroke-linecap",strokeLineJoin:"stroke-linejoin",strokeMiterLimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",tabIndex:"tabindex",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",transformOrigin:"transform-origin",typeOf:"typeof",underlinePosition:"underline-position",underlineThickness:"underline-thickness",unicodeBidi:"unicode-bidi",unicodeRange:"unicode-range",unitsPerEm:"units-per-em",vAlphabetic:"v-alphabetic",vHanging:"v-hanging",vIdeographic:"v-ideographic",vMathematical:"v-mathematical",vectorEffect:"vector-effect",vertAdvY:"vert-adv-y",vertOriginX:"vert-origin-x",vertOriginY:"vert-origin-y",wordSpacing:"word-spacing",writingMode:"writing-mode",xHeight:"x-height",playbackOrder:"playbackorder",timelineBegin:"timelinebegin"},properties:{about:gr,accentHeight:De,accumulate:null,additive:null,alignmentBaseline:null,alphabetic:De,amplitude:De,arabicForm:null,ascent:De,attributeName:null,attributeType:null,azimuth:De,bandwidth:null,baselineShift:null,baseFrequency:null,baseProfile:null,bbox:null,begin:null,bias:De,by:null,calcMode:null,capHeight:De,className:It,clip:null,clipPath:null,clipPathUnits:null,clipRule:null,color:null,colorInterpolation:null,colorInterpolationFilters:null,colorProfile:null,colorRendering:null,content:null,contentScriptType:null,contentStyleType:null,crossOrigin:null,cursor:null,cx:null,cy:null,d:null,dataType:null,defaultAction:null,descent:De,diffuseConstant:De,direction:null,display:null,dur:null,divisor:De,dominantBaseline:null,download:tt,dx:null,dy:null,edgeMode:null,editable:null,elevation:De,enableBackground:null,end:null,event:null,exponent:De,externalResourcesRequired:null,fill:null,fillOpacity:De,fillRule:null,filter:null,filterRes:null,filterUnits:null,floodColor:null,floodOpacity:null,focusable:null,focusHighlight:null,fontFamily:null,fontSize:null,fontSizeAdjust:null,fontStretch:null,fontStyle:null,fontVariant:null,fontWeight:null,format:null,fr:null,from:null,fx:null,fy:null,g1:os,g2:os,glyphName:os,glyphOrientationHorizontal:null,glyphOrientationVertical:null,glyphRef:null,gradientTransform:null,gradientUnits:null,handler:null,hanging:De,hatchContentUnits:null,hatchUnits:null,height:null,href:null,hrefLang:null,horizAdvX:De,horizOriginX:De,horizOriginY:De,id:null,ideographic:De,imageRendering:null,initialVisibility:null,in:null,in2:null,intercept:De,k:De,k1:De,k2:De,k3:De,k4:De,kernelMatrix:gr,kernelUnitLength:null,keyPoints:null,keySplines:null,keyTimes:null,kerning:null,lang:null,lengthAdjust:null,letterSpacing:null,lightingColor:null,limitingConeAngle:De,local:null,markerEnd:null,markerMid:null,markerStart:null,markerHeight:null,markerUnits:null,markerWidth:null,mask:null,maskContentUnits:null,maskUnits:null,mathematical:null,max:null,media:null,mediaCharacterEncoding:null,mediaContentEncodings:null,mediaSize:De,mediaTime:null,method:null,min:null,mode:null,name:null,navDown:null,navDownLeft:null,navDownRight:null,navLeft:null,navNext:null,navPrev:null,navRight:null,navUp:null,navUpLeft:null,navUpRight:null,numOctaves:null,observer:null,offset:null,onAbort:null,onActivate:null,onAfterPrint:null,onBeforePrint:null,onBegin:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnd:null,onEnded:null,onError:null,onFocus:null,onFocusIn:null,onFocusOut:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadStart:null,onMessage:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onMouseWheel:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRepeat:null,onReset:null,onResize:null,onScroll:null,onSeeked:null,onSeeking:null,onSelect:null,onShow:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnload:null,onVolumeChange:null,onWaiting:null,onZoom:null,opacity:null,operator:null,order:null,orient:null,orientation:null,origin:null,overflow:null,overlay:null,overlinePosition:De,overlineThickness:De,paintOrder:null,panose1:null,path:null,pathLength:De,patternContentUnits:null,patternTransform:null,patternUnits:null,phase:null,ping:It,pitch:null,playbackOrder:null,pointerEvents:null,points:null,pointsAtX:De,pointsAtY:De,pointsAtZ:De,preserveAlpha:null,preserveAspectRatio:null,primitiveUnits:null,propagate:null,property:gr,r:null,radius:null,referrerPolicy:null,refX:null,refY:null,rel:gr,rev:gr,renderingIntent:null,repeatCount:null,repeatDur:null,requiredExtensions:gr,requiredFeatures:gr,requiredFonts:gr,requiredFormats:gr,resource:null,restart:null,result:null,rotate:null,rx:null,ry:null,scale:null,seed:null,shapeRendering:null,side:null,slope:null,snapshotTime:null,specularConstant:De,specularExponent:De,spreadMethod:null,spacing:null,startOffset:null,stdDeviation:null,stemh:null,stemv:null,stitchTiles:null,stopColor:null,stopOpacity:null,strikethroughPosition:De,strikethroughThickness:De,string:null,stroke:null,strokeDashArray:gr,strokeDashOffset:null,strokeLineCap:null,strokeLineJoin:null,strokeMiterLimit:De,strokeOpacity:De,strokeWidth:null,style:null,surfaceScale:De,syncBehavior:null,syncBehaviorDefault:null,syncMaster:null,syncTolerance:null,syncToleranceDefault:null,systemLanguage:gr,tabIndex:De,tableValues:null,target:null,targetX:De,targetY:De,textAnchor:null,textDecoration:null,textRendering:null,textLength:null,timelineBegin:null,title:null,transformBehavior:null,type:null,typeOf:gr,to:null,transform:null,transformOrigin:null,u1:null,u2:null,underlinePosition:De,underlineThickness:De,unicode:null,unicodeBidi:null,unicodeRange:null,unitsPerEm:De,values:null,vAlphabetic:De,vMathematical:De,vectorEffect:null,vHanging:De,vIdeographic:De,version:null,vertAdvY:De,vertOriginX:De,vertOriginY:De,viewBox:null,viewTarget:null,visibility:null,width:null,widths:null,wordSpacing:null,writingMode:null,x:null,x1:null,x2:null,xChannelSelector:null,xHeight:De,y:null,y1:null,y2:null,yChannelSelector:null,z:null,zoomAndPan:null},space:"svg",transform:sC}),lC=Ts({properties:{xLinkActuate:null,xLinkArcRole:null,xLinkHref:null,xLinkRole:null,xLinkShow:null,xLinkTitle:null,xLinkType:null},space:"xlink",transform(e,t){return"xlink:"+t.slice(5).toLowerCase()}}),cC=Ts({attributes:{xmlnsxlink:"xmlns:xlink"},properties:{xmlnsXLink:null,xmlns:null},space:"xmlns",transform:oC}),fC=Ts({properties:{xmlBase:null,xmlLang:null,xmlSpace:null},space:"xml",transform(e,t){return"xml:"+t.slice(3).toLowerCase()}}),mI={classId:"classID",dataType:"datatype",itemId:"itemID",strokeDashArray:"strokeDasharray",strokeDashOffset:"strokeDashoffset",strokeLineCap:"strokeLinecap",strokeLineJoin:"strokeLinejoin",strokeMiterLimit:"strokeMiterlimit",typeOf:"typeof",xLinkActuate:"xlinkActuate",xLinkArcRole:"xlinkArcrole",xLinkHref:"xlinkHref",xLinkRole:"xlinkRole",xLinkShow:"xlinkShow",xLinkTitle:"xlinkTitle",xLinkType:"xlinkType",xmlnsXLink:"xmlnsXlink"},pI=/[A-Z]/g,$A=/-[a-z]/g,gI=/^data[-\w.:]+$/i;function _g(e,t){const n=Dl(t);let i=t,u=ar;if(n in e.normal)return e.property[e.normal[n]];if(n.length>4&&n.slice(0,4)==="data"&&gI.test(t)){if(t.charAt(4)==="-"){const o=t.slice(5).replace($A,yI);i="data"+o.charAt(0).toUpperCase()+o.slice(1)}else{const o=t.slice(4);if(!$A.test(o)){let l=o.replace(pI,EI);l.charAt(0)!=="-"&&(l="-"+l),t="data"+l}}u=Cg}return new u(i,t)}function EI(e){return"-"+e.toLowerCase()}function yI(e){return e.charAt(1).toUpperCase()}const ad=aC([uC,dI,lC,cC,fC],"html"),As=aC([uC,hI,lC,cC,fC],"svg");function ZA(e){const t=String(e||"").trim();return t?t.split(/[ \t\n\r\f]+/g):[]}function dC(e){return e.join(" ").trim()}var $u={},ap,JA;function bI(){if(JA)return ap;JA=1;var e=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,t=/\n/g,n=/^\s*/,i=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,u=/^:\s*/,o=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,l=/^[;\s]*/,f=/^\s+|\s+$/g,d=` +`,h="/",p="*",g="",b="comment",T="declaration";ap=function(_,O){if(typeof _!="string")throw new TypeError("First argument must be a string");if(!_)return[];O=O||{};var C=1,N=1;function R($){var Z=$.match(t);Z&&(C+=Z.length);var L=$.lastIndexOf(d);N=~L?$.length-L:N+$.length}function Y(){var $={line:C,column:N};return function(Z){return Z.position=new M($),P(),Z}}function M($){this.start=$,this.end={line:C,column:N},this.source=O.source}M.prototype.content=_;function v($){var Z=new Error(O.source+":"+C+":"+N+": "+$);if(Z.reason=$,Z.filename=O.source,Z.line=C,Z.column=N,Z.source=_,!O.silent)throw Z}function J($){var Z=$.exec(_);if(Z){var L=Z[0];return R(L),_=_.slice(L.length),Z}}function P(){J(n)}function q($){var Z;for($=$||[];Z=z();)Z!==!1&&$.push(Z);return $}function z(){var $=Y();if(!(h!=_.charAt(0)||p!=_.charAt(1))){for(var Z=2;g!=_.charAt(Z)&&(p!=_.charAt(Z)||h!=_.charAt(Z+1));)++Z;if(Z+=2,g===_.charAt(Z-1))return v("End of comment missing");var L=_.slice(2,Z-2);return N+=2,R(L),_=_.slice(Z),N+=2,$({type:b,comment:L})}}function V(){var $=Y(),Z=J(i);if(Z){if(z(),!J(u))return v("property missing ':'");var L=J(o),B=$({type:T,property:A(Z[0].replace(e,g)),value:L?A(L[0].replace(e,g)):g});return J(l),B}}function F(){var $=[];q($);for(var Z;Z=V();)Z!==!1&&($.push(Z),q($));return $}return P(),F()};function A(_){return _?_.replace(f,g):g}return ap}var eS;function TI(){if(eS)return $u;eS=1;var e=$u&&$u.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty($u,"__esModule",{value:!0}),$u.default=n;var t=e(bI());function n(i,u){var o=null;if(!i||typeof i!="string")return o;var l=(0,t.default)(i),f=typeof u=="function";return l.forEach(function(d){if(d.type==="declaration"){var h=d.property,p=d.value;f?u(h,p,d):p&&(o=o||{},o[h]=p)}}),o}return $u}var Uo={},tS;function AI(){if(tS)return Uo;tS=1,Object.defineProperty(Uo,"__esModule",{value:!0}),Uo.camelCase=void 0;var e=/^--[a-zA-Z0-9_-]+$/,t=/-([a-z])/g,n=/^[^-]+$/,i=/^-(webkit|moz|ms|o|khtml)-/,u=/^-(ms)-/,o=function(h){return!h||n.test(h)||e.test(h)},l=function(h,p){return p.toUpperCase()},f=function(h,p){return"".concat(p,"-")},d=function(h,p){return p===void 0&&(p={}),o(h)?h:(h=h.toLowerCase(),p.reactCompat?h=h.replace(u,f):h=h.replace(i,f),h.replace(t,l))};return Uo.camelCase=d,Uo}var Ho,nS;function SI(){if(nS)return Ho;nS=1;var e=Ho&&Ho.__importDefault||function(u){return u&&u.__esModule?u:{default:u}},t=e(TI()),n=AI();function i(u,o){var l={};return!u||typeof u!="string"||(0,t.default)(u,function(f,d){f&&d&&(l[(0,n.camelCase)(f,o)]=d)}),l}return i.default=i,Ho=i,Ho}var DI=SI();const vI=Rl(DI),ud=hC("end"),yi=hC("start");function hC(e){return t;function t(n){const i=n&&n.position&&n.position[e]||{};if(typeof i.line=="number"&&i.line>0&&typeof i.column=="number"&&i.column>0)return{line:i.line,column:i.column,offset:typeof i.offset=="number"&&i.offset>-1?i.offset:void 0}}}function mC(e){const t=yi(e),n=ud(e);if(t&&n)return{start:t,end:n}}function ul(e){return!e||typeof e!="object"?"":"position"in e||"type"in e?rS(e.position):"start"in e||"end"in e?rS(e):"line"in e||"column"in e?l0(e):""}function l0(e){return iS(e&&e.line)+":"+iS(e&&e.column)}function rS(e){return l0(e&&e.start)+"-"+l0(e&&e.end)}function iS(e){return e&&typeof e=="number"?e:1}class Pn extends Error{constructor(t,n,i){super(),typeof n=="string"&&(i=n,n=void 0);let u="",o={},l=!1;if(n&&("line"in n&&"column"in n?o={place:n}:"start"in n&&"end"in n?o={place:n}:"type"in n?o={ancestors:[n],place:n.position}:o={...n}),typeof t=="string"?u=t:!o.cause&&t&&(l=!0,u=t.message,o.cause=t),!o.ruleId&&!o.source&&typeof i=="string"){const d=i.indexOf(":");d===-1?o.ruleId=i:(o.source=i.slice(0,d),o.ruleId=i.slice(d+1))}if(!o.place&&o.ancestors&&o.ancestors){const d=o.ancestors[o.ancestors.length-1];d&&(o.place=d.position)}const f=o.place&&"start"in o.place?o.place.start:o.place;this.ancestors=o.ancestors||void 0,this.cause=o.cause||void 0,this.column=f?f.column:void 0,this.fatal=void 0,this.file,this.message=u,this.line=f?f.line:void 0,this.name=ul(o.place)||"1:1",this.place=o.place||void 0,this.reason=this.message,this.ruleId=o.ruleId||void 0,this.source=o.source||void 0,this.stack=l&&o.cause&&typeof o.cause.stack=="string"?o.cause.stack:"",this.actual,this.expected,this.note,this.url}}Pn.prototype.file="";Pn.prototype.name="";Pn.prototype.reason="";Pn.prototype.message="";Pn.prototype.stack="";Pn.prototype.column=void 0;Pn.prototype.line=void 0;Pn.prototype.ancestors=void 0;Pn.prototype.cause=void 0;Pn.prototype.fatal=void 0;Pn.prototype.place=void 0;Pn.prototype.ruleId=void 0;Pn.prototype.source=void 0;const xg={}.hasOwnProperty,CI=new Map,_I=/[A-Z]/g,xI=new Set(["table","tbody","thead","tfoot","tr"]),RI=new Set(["td","th"]),pC="https://github.com/syntax-tree/hast-util-to-jsx-runtime";function wI(e,t){if(!t||t.Fragment===void 0)throw new TypeError("Expected `Fragment` in options");const n=t.filePath||void 0;let i;if(t.development){if(typeof t.jsxDEV!="function")throw new TypeError("Expected `jsxDEV` in options when `development: true`");i=FI(n,t.jsxDEV)}else{if(typeof t.jsx!="function")throw new TypeError("Expected `jsx` in production options");if(typeof t.jsxs!="function")throw new TypeError("Expected `jsxs` in production options");i=PI(n,t.jsx,t.jsxs)}const u={Fragment:t.Fragment,ancestors:[],components:t.components||{},create:i,elementAttributeNameCase:t.elementAttributeNameCase||"react",evaluater:t.createEvaluater?t.createEvaluater():void 0,filePath:n,ignoreInvalidStyle:t.ignoreInvalidStyle||!1,passKeys:t.passKeys!==!1,passNode:t.passNode||!1,schema:t.space==="svg"?As:ad,stylePropertyNameCase:t.stylePropertyNameCase||"dom",tableCellAlignToStyle:t.tableCellAlignToStyle!==!1},o=gC(u,e,void 0);return o&&typeof o!="string"?o:u.create(e,u.Fragment,{children:o||void 0},void 0)}function gC(e,t,n){if(t.type==="element")return OI(e,t,n);if(t.type==="mdxFlowExpression"||t.type==="mdxTextExpression")return NI(e,t);if(t.type==="mdxJsxFlowElement"||t.type==="mdxJsxTextElement")return LI(e,t,n);if(t.type==="mdxjsEsm")return kI(e,t);if(t.type==="root")return MI(e,t,n);if(t.type==="text")return II(e,t)}function OI(e,t,n){const i=e.schema;let u=i;t.tagName.toLowerCase()==="svg"&&i.space==="html"&&(u=As,e.schema=u),e.ancestors.push(t);const o=yC(e,t.tagName,!1),l=BI(e,t);let f=wg(e,t);return xI.has(t.tagName)&&(f=f.filter(function(d){return typeof d=="string"?!cI(d):!0})),EC(e,l,o,t),Rg(l,f),e.ancestors.pop(),e.schema=i,e.create(t,o,l,n)}function NI(e,t){if(t.data&&t.data.estree&&e.evaluater){const i=t.data.estree.body[0];return i.type,e.evaluater.evaluateExpression(i.expression)}vl(e,t.position)}function kI(e,t){if(t.data&&t.data.estree&&e.evaluater)return e.evaluater.evaluateProgram(t.data.estree);vl(e,t.position)}function LI(e,t,n){const i=e.schema;let u=i;t.name==="svg"&&i.space==="html"&&(u=As,e.schema=u),e.ancestors.push(t);const o=t.name===null?e.Fragment:yC(e,t.name,!0),l=UI(e,t),f=wg(e,t);return EC(e,l,o,t),Rg(l,f),e.ancestors.pop(),e.schema=i,e.create(t,o,l,n)}function MI(e,t,n){const i={};return Rg(i,wg(e,t)),e.create(t,e.Fragment,i,n)}function II(e,t){return t.value}function EC(e,t,n,i){typeof n!="string"&&n!==e.Fragment&&e.passNode&&(t.node=i)}function Rg(e,t){if(t.length>0){const n=t.length>1?t:t[0];n&&(e.children=n)}}function PI(e,t,n){return i;function i(u,o,l,f){const h=Array.isArray(l.children)?n:t;return f?h(o,l,f):h(o,l)}}function FI(e,t){return n;function n(i,u,o,l){const f=Array.isArray(o.children),d=yi(i);return t(u,o,l,f,{columnNumber:d?d.column-1:void 0,fileName:e,lineNumber:d?d.line:void 0},void 0)}}function BI(e,t){const n={};let i,u;for(u in t.properties)if(u!=="children"&&xg.call(t.properties,u)){const o=HI(e,u,t.properties[u]);if(o){const[l,f]=o;e.tableCellAlignToStyle&&l==="align"&&typeof f=="string"&&RI.has(t.tagName)?i=f:n[l]=f}}if(i){const o=n.style||(n.style={});o[e.stylePropertyNameCase==="css"?"text-align":"textAlign"]=i}return n}function UI(e,t){const n={};for(const i of t.attributes)if(i.type==="mdxJsxExpressionAttribute")if(i.data&&i.data.estree&&e.evaluater){const o=i.data.estree.body[0];o.type;const l=o.expression;l.type;const f=l.properties[0];f.type,Object.assign(n,e.evaluater.evaluateExpression(f.argument))}else vl(e,t.position);else{const u=i.name;let o;if(i.value&&typeof i.value=="object")if(i.value.data&&i.value.data.estree&&e.evaluater){const f=i.value.data.estree.body[0];f.type,o=e.evaluater.evaluateExpression(f.expression)}else vl(e,t.position);else o=i.value===null?!0:i.value;n[u]=o}return n}function wg(e,t){const n=[];let i=-1;const u=e.passKeys?new Map:CI;for(;++i<t.children.length;){const o=t.children[i];let l;if(e.passKeys){const d=o.type==="element"?o.tagName:o.type==="mdxJsxFlowElement"||o.type==="mdxJsxTextElement"?o.name:void 0;if(d){const h=u.get(d)||0;l=d+"-"+h,u.set(d,h+1)}}const f=gC(e,o,l);f!==void 0&&n.push(f)}return n}function HI(e,t,n){const i=_g(e.schema,t);if(!(n==null||typeof n=="number"&&Number.isNaN(n))){if(Array.isArray(n)&&(n=i.commaSeparated?iC(n):dC(n)),i.property==="style"){let u=typeof n=="object"?n:zI(e,String(n));return e.stylePropertyNameCase==="css"&&(u=VI(u)),["style",u]}return[e.elementAttributeNameCase==="react"&&i.space?mI[i.property]||i.property:i.attribute,n]}}function zI(e,t){try{return vI(t,{reactCompat:!0})}catch(n){if(e.ignoreInvalidStyle)return{};const i=n,u=new Pn("Cannot parse `style` attribute",{ancestors:e.ancestors,cause:i,ruleId:"style",source:"hast-util-to-jsx-runtime"});throw u.file=e.filePath||void 0,u.url=pC+"#cannot-parse-style-attribute",u}}function yC(e,t,n){let i;if(!n)i={type:"Literal",value:t};else if(t.includes(".")){const u=t.split(".");let o=-1,l;for(;++o<u.length;){const f=KA(u[o])?{type:"Identifier",name:u[o]}:{type:"Literal",value:u[o]};l=l?{type:"MemberExpression",object:l,property:f,computed:!!(o&&f.type==="Literal"),optional:!1}:f}i=l}else i=KA(t)&&!/^[a-z]/.test(t)?{type:"Identifier",name:t}:{type:"Literal",value:t};if(i.type==="Literal"){const u=i.value;return xg.call(e.components,u)?e.components[u]:u}if(e.evaluater)return e.evaluater.evaluateExpression(i);vl(e)}function vl(e,t){const n=new Pn("Cannot handle MDX estrees without `createEvaluater`",{ancestors:e.ancestors,place:t,ruleId:"mdx-estree",source:"hast-util-to-jsx-runtime"});throw n.file=e.filePath||void 0,n.url=pC+"#cannot-handle-mdx-estrees-without-createevaluater",n}function VI(e){const t={};let n;for(n in e)xg.call(e,n)&&(t[jI(n)]=e[n]);return t}function jI(e){let t=e.replace(_I,qI);return t.slice(0,3)==="ms-"&&(t="-"+t),t}function qI(e){return"-"+e.toLowerCase()}const up={action:["form"],cite:["blockquote","del","ins","q"],data:["object"],formAction:["button","input"],href:["a","area","base","link"],icon:["menuitem"],itemId:null,manifest:["html"],ping:["a","area"],poster:["video"],src:["audio","embed","iframe","img","input","script","source","track","video"]},YI={};function Og(e,t){const n=YI,i=typeof n.includeImageAlt=="boolean"?n.includeImageAlt:!0,u=typeof n.includeHtml=="boolean"?n.includeHtml:!0;return bC(e,i,u)}function bC(e,t,n){if(GI(e)){if("value"in e)return e.type==="html"&&!n?"":e.value;if(t&&"alt"in e&&e.alt)return e.alt;if("children"in e)return aS(e.children,t,n)}return Array.isArray(e)?aS(e,t,n):""}function aS(e,t,n){const i=[];let u=-1;for(;++u<e.length;)i[u]=bC(e[u],t,n);return i.join("")}function GI(e){return!!(e&&typeof e=="object")}const uS=document.createElement("i");function Ng(e){const t="&"+e+";";uS.innerHTML=t;const n=uS.textContent;return n.charCodeAt(n.length-1)===59&&e!=="semi"||n===t?!1:n}function Tr(e,t,n,i){const u=e.length;let o=0,l;if(t<0?t=-t>u?0:u+t:t=t>u?u:t,n=n>0?n:0,i.length<1e4)l=Array.from(i),l.unshift(t,n),e.splice(...l);else for(n&&e.splice(t,n);o<i.length;)l=i.slice(o,o+1e4),l.unshift(t,0),e.splice(...l),o+=1e4,t+=1e4}function Pr(e,t){return e.length>0?(Tr(e,e.length,0,t),e):t}const sS={}.hasOwnProperty;function TC(e){const t={};let n=-1;for(;++n<e.length;)XI(t,e[n]);return t}function XI(e,t){let n;for(n in t){const u=(sS.call(e,n)?e[n]:void 0)||(e[n]={}),o=t[n];let l;if(o)for(l in o){sS.call(u,l)||(u[l]=[]);const f=o[l];KI(u[l],Array.isArray(f)?f:f?[f]:[])}}}function KI(e,t){let n=-1;const i=[];for(;++n<t.length;)(t[n].add==="after"?e:i).push(t[n]);Tr(e,0,0,i)}function AC(e,t){const n=Number.parseInt(e,t);return n<9||n===11||n>13&&n<32||n>126&&n<160||n>55295&&n<57344||n>64975&&n<65008||(n&65535)===65535||(n&65535)===65534||n>1114111?"�":String.fromCodePoint(n)}function $r(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const zn=wa(/[A-Za-z]/),In=wa(/[\dA-Za-z]/),WI=wa(/[#-'*+\--9=?A-Z^-~]/);function jf(e){return e!==null&&(e<32||e===127)}const c0=wa(/\d/),QI=wa(/[\dA-Fa-f]/),$I=wa(/[!-/:-@[-`{-~]/);function Ve(e){return e!==null&&e<-2}function wt(e){return e!==null&&(e<0||e===32)}function nt(e){return e===-2||e===-1||e===32}const sd=wa(new RegExp("\\p{P}|\\p{S}","u")),cu=wa(/\s/);function wa(e){return t;function t(n){return n!==null&&n>-1&&e.test(String.fromCharCode(n))}}function Ss(e){const t=[];let n=-1,i=0,u=0;for(;++n<e.length;){const o=e.charCodeAt(n);let l="";if(o===37&&In(e.charCodeAt(n+1))&&In(e.charCodeAt(n+2)))u=2;else if(o<128)/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(o))||(l=String.fromCharCode(o));else if(o>55295&&o<57344){const f=e.charCodeAt(n+1);o<56320&&f>56319&&f<57344?(l=String.fromCharCode(o,f),u=1):l="�"}else l=String.fromCharCode(o);l&&(t.push(e.slice(i,n),encodeURIComponent(l)),i=n+u+1,l=""),u&&(n+=u,u=0)}return t.join("")+e.slice(i)}function Et(e,t,n,i){const u=i?i-1:Number.POSITIVE_INFINITY;let o=0;return l;function l(d){return nt(d)?(e.enter(n),f(d)):t(d)}function f(d){return nt(d)&&o++<u?(e.consume(d),f):(e.exit(n),t(d))}}const ZI={tokenize:JI};function JI(e){const t=e.attempt(this.parser.constructs.contentInitial,i,u);let n;return t;function i(f){if(f===null){e.consume(f);return}return e.enter("lineEnding"),e.consume(f),e.exit("lineEnding"),Et(e,t,"linePrefix")}function u(f){return e.enter("paragraph"),o(f)}function o(f){const d=e.enter("chunkText",{contentType:"text",previous:n});return n&&(n.next=d),n=d,l(f)}function l(f){if(f===null){e.exit("chunkText"),e.exit("paragraph"),e.consume(f);return}return Ve(f)?(e.consume(f),e.exit("chunkText"),o):(e.consume(f),l)}}const e8={tokenize:t8},oS={tokenize:n8};function t8(e){const t=this,n=[];let i=0,u,o,l;return f;function f(R){if(i<n.length){const Y=n[i];return t.containerState=Y[1],e.attempt(Y[0].continuation,d,h)(R)}return h(R)}function d(R){if(i++,t.containerState._closeFlow){t.containerState._closeFlow=void 0,u&&N();const Y=t.events.length;let M=Y,v;for(;M--;)if(t.events[M][0]==="exit"&&t.events[M][1].type==="chunkFlow"){v=t.events[M][1].end;break}C(i);let J=Y;for(;J<t.events.length;)t.events[J][1].end={...v},J++;return Tr(t.events,M+1,0,t.events.slice(Y)),t.events.length=J,h(R)}return f(R)}function h(R){if(i===n.length){if(!u)return b(R);if(u.currentConstruct&&u.currentConstruct.concrete)return A(R);t.interrupt=!!(u.currentConstruct&&!u._gfmTableDynamicInterruptHack)}return t.containerState={},e.check(oS,p,g)(R)}function p(R){return u&&N(),C(i),b(R)}function g(R){return t.parser.lazy[t.now().line]=i!==n.length,l=t.now().offset,A(R)}function b(R){return t.containerState={},e.attempt(oS,T,A)(R)}function T(R){return i++,n.push([t.currentConstruct,t.containerState]),b(R)}function A(R){if(R===null){u&&N(),C(0),e.consume(R);return}return u=u||t.parser.flow(t.now()),e.enter("chunkFlow",{_tokenizer:u,contentType:"flow",previous:o}),_(R)}function _(R){if(R===null){O(e.exit("chunkFlow"),!0),C(0),e.consume(R);return}return Ve(R)?(e.consume(R),O(e.exit("chunkFlow")),i=0,t.interrupt=void 0,f):(e.consume(R),_)}function O(R,Y){const M=t.sliceStream(R);if(Y&&M.push(null),R.previous=o,o&&(o.next=R),o=R,u.defineSkip(R.start),u.write(M),t.parser.lazy[R.start.line]){let v=u.events.length;for(;v--;)if(u.events[v][1].start.offset<l&&(!u.events[v][1].end||u.events[v][1].end.offset>l))return;const J=t.events.length;let P=J,q,z;for(;P--;)if(t.events[P][0]==="exit"&&t.events[P][1].type==="chunkFlow"){if(q){z=t.events[P][1].end;break}q=!0}for(C(i),v=J;v<t.events.length;)t.events[v][1].end={...z},v++;Tr(t.events,P+1,0,t.events.slice(J)),t.events.length=v}}function C(R){let Y=n.length;for(;Y-- >R;){const M=n[Y];t.containerState=M[1],M[0].exit.call(t,e)}n.length=R}function N(){u.write([null]),o=void 0,u=void 0,t.containerState._closeFlow=void 0}}function n8(e,t,n){return Et(e,e.attempt(this.parser.constructs.document,t,n),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}function ds(e){if(e===null||wt(e)||cu(e))return 1;if(sd(e))return 2}function od(e,t,n){const i=[];let u=-1;for(;++u<e.length;){const o=e[u].resolveAll;o&&!i.includes(o)&&(t=o(t,n),i.push(o))}return t}const f0={name:"attention",resolveAll:r8,tokenize:i8};function r8(e,t){let n=-1,i,u,o,l,f,d,h,p;for(;++n<e.length;)if(e[n][0]==="enter"&&e[n][1].type==="attentionSequence"&&e[n][1]._close){for(i=n;i--;)if(e[i][0]==="exit"&&e[i][1].type==="attentionSequence"&&e[i][1]._open&&t.sliceSerialize(e[i][1]).charCodeAt(0)===t.sliceSerialize(e[n][1]).charCodeAt(0)){if((e[i][1]._close||e[n][1]._open)&&(e[n][1].end.offset-e[n][1].start.offset)%3&&!((e[i][1].end.offset-e[i][1].start.offset+e[n][1].end.offset-e[n][1].start.offset)%3))continue;d=e[i][1].end.offset-e[i][1].start.offset>1&&e[n][1].end.offset-e[n][1].start.offset>1?2:1;const g={...e[i][1].end},b={...e[n][1].start};lS(g,-d),lS(b,d),l={type:d>1?"strongSequence":"emphasisSequence",start:g,end:{...e[i][1].end}},f={type:d>1?"strongSequence":"emphasisSequence",start:{...e[n][1].start},end:b},o={type:d>1?"strongText":"emphasisText",start:{...e[i][1].end},end:{...e[n][1].start}},u={type:d>1?"strong":"emphasis",start:{...l.start},end:{...f.end}},e[i][1].end={...l.start},e[n][1].start={...f.end},h=[],e[i][1].end.offset-e[i][1].start.offset&&(h=Pr(h,[["enter",e[i][1],t],["exit",e[i][1],t]])),h=Pr(h,[["enter",u,t],["enter",l,t],["exit",l,t],["enter",o,t]]),h=Pr(h,od(t.parser.constructs.insideSpan.null,e.slice(i+1,n),t)),h=Pr(h,[["exit",o,t],["enter",f,t],["exit",f,t],["exit",u,t]]),e[n][1].end.offset-e[n][1].start.offset?(p=2,h=Pr(h,[["enter",e[n][1],t],["exit",e[n][1],t]])):p=0,Tr(e,i-1,n-i+3,h),n=i+h.length-p-2;break}}for(n=-1;++n<e.length;)e[n][1].type==="attentionSequence"&&(e[n][1].type="data");return e}function i8(e,t){const n=this.parser.constructs.attentionMarkers.null,i=this.previous,u=ds(i);let o;return l;function l(d){return o=d,e.enter("attentionSequence"),f(d)}function f(d){if(d===o)return e.consume(d),f;const h=e.exit("attentionSequence"),p=ds(d),g=!p||p===2&&u||n.includes(d),b=!u||u===2&&p||n.includes(i);return h._open=!!(o===42?g:g&&(u||!b)),h._close=!!(o===42?b:b&&(p||!g)),t(d)}}function lS(e,t){e.column+=t,e.offset+=t,e._bufferIndex+=t}const a8={name:"autolink",tokenize:u8};function u8(e,t,n){let i=0;return u;function u(T){return e.enter("autolink"),e.enter("autolinkMarker"),e.consume(T),e.exit("autolinkMarker"),e.enter("autolinkProtocol"),o}function o(T){return zn(T)?(e.consume(T),l):T===64?n(T):h(T)}function l(T){return T===43||T===45||T===46||In(T)?(i=1,f(T)):h(T)}function f(T){return T===58?(e.consume(T),i=0,d):(T===43||T===45||T===46||In(T))&&i++<32?(e.consume(T),f):(i=0,h(T))}function d(T){return T===62?(e.exit("autolinkProtocol"),e.enter("autolinkMarker"),e.consume(T),e.exit("autolinkMarker"),e.exit("autolink"),t):T===null||T===32||T===60||jf(T)?n(T):(e.consume(T),d)}function h(T){return T===64?(e.consume(T),p):WI(T)?(e.consume(T),h):n(T)}function p(T){return In(T)?g(T):n(T)}function g(T){return T===46?(e.consume(T),i=0,p):T===62?(e.exit("autolinkProtocol").type="autolinkEmail",e.enter("autolinkMarker"),e.consume(T),e.exit("autolinkMarker"),e.exit("autolink"),t):b(T)}function b(T){if((T===45||In(T))&&i++<63){const A=T===45?b:g;return e.consume(T),A}return n(T)}}const Pl={partial:!0,tokenize:s8};function s8(e,t,n){return i;function i(o){return nt(o)?Et(e,u,"linePrefix")(o):u(o)}function u(o){return o===null||Ve(o)?t(o):n(o)}}const SC={continuation:{tokenize:l8},exit:c8,name:"blockQuote",tokenize:o8};function o8(e,t,n){const i=this;return u;function u(l){if(l===62){const f=i.containerState;return f.open||(e.enter("blockQuote",{_container:!0}),f.open=!0),e.enter("blockQuotePrefix"),e.enter("blockQuoteMarker"),e.consume(l),e.exit("blockQuoteMarker"),o}return n(l)}function o(l){return nt(l)?(e.enter("blockQuotePrefixWhitespace"),e.consume(l),e.exit("blockQuotePrefixWhitespace"),e.exit("blockQuotePrefix"),t):(e.exit("blockQuotePrefix"),t(l))}}function l8(e,t,n){const i=this;return u;function u(l){return nt(l)?Et(e,o,"linePrefix",i.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(l):o(l)}function o(l){return e.attempt(SC,t,n)(l)}}function c8(e){e.exit("blockQuote")}const DC={name:"characterEscape",tokenize:f8};function f8(e,t,n){return i;function i(o){return e.enter("characterEscape"),e.enter("escapeMarker"),e.consume(o),e.exit("escapeMarker"),u}function u(o){return $I(o)?(e.enter("characterEscapeValue"),e.consume(o),e.exit("characterEscapeValue"),e.exit("characterEscape"),t):n(o)}}const vC={name:"characterReference",tokenize:d8};function d8(e,t,n){const i=this;let u=0,o,l;return f;function f(g){return e.enter("characterReference"),e.enter("characterReferenceMarker"),e.consume(g),e.exit("characterReferenceMarker"),d}function d(g){return g===35?(e.enter("characterReferenceMarkerNumeric"),e.consume(g),e.exit("characterReferenceMarkerNumeric"),h):(e.enter("characterReferenceValue"),o=31,l=In,p(g))}function h(g){return g===88||g===120?(e.enter("characterReferenceMarkerHexadecimal"),e.consume(g),e.exit("characterReferenceMarkerHexadecimal"),e.enter("characterReferenceValue"),o=6,l=QI,p):(e.enter("characterReferenceValue"),o=7,l=c0,p(g))}function p(g){if(g===59&&u){const b=e.exit("characterReferenceValue");return l===In&&!Ng(i.sliceSerialize(b))?n(g):(e.enter("characterReferenceMarker"),e.consume(g),e.exit("characterReferenceMarker"),e.exit("characterReference"),t)}return l(g)&&u++<o?(e.consume(g),p):n(g)}}const cS={partial:!0,tokenize:m8},fS={concrete:!0,name:"codeFenced",tokenize:h8};function h8(e,t,n){const i=this,u={partial:!0,tokenize:M};let o=0,l=0,f;return d;function d(v){return h(v)}function h(v){const J=i.events[i.events.length-1];return o=J&&J[1].type==="linePrefix"?J[2].sliceSerialize(J[1],!0).length:0,f=v,e.enter("codeFenced"),e.enter("codeFencedFence"),e.enter("codeFencedFenceSequence"),p(v)}function p(v){return v===f?(l++,e.consume(v),p):l<3?n(v):(e.exit("codeFencedFenceSequence"),nt(v)?Et(e,g,"whitespace")(v):g(v))}function g(v){return v===null||Ve(v)?(e.exit("codeFencedFence"),i.interrupt?t(v):e.check(cS,_,Y)(v)):(e.enter("codeFencedFenceInfo"),e.enter("chunkString",{contentType:"string"}),b(v))}function b(v){return v===null||Ve(v)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),g(v)):nt(v)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),Et(e,T,"whitespace")(v)):v===96&&v===f?n(v):(e.consume(v),b)}function T(v){return v===null||Ve(v)?g(v):(e.enter("codeFencedFenceMeta"),e.enter("chunkString",{contentType:"string"}),A(v))}function A(v){return v===null||Ve(v)?(e.exit("chunkString"),e.exit("codeFencedFenceMeta"),g(v)):v===96&&v===f?n(v):(e.consume(v),A)}function _(v){return e.attempt(u,Y,O)(v)}function O(v){return e.enter("lineEnding"),e.consume(v),e.exit("lineEnding"),C}function C(v){return o>0&&nt(v)?Et(e,N,"linePrefix",o+1)(v):N(v)}function N(v){return v===null||Ve(v)?e.check(cS,_,Y)(v):(e.enter("codeFlowValue"),R(v))}function R(v){return v===null||Ve(v)?(e.exit("codeFlowValue"),N(v)):(e.consume(v),R)}function Y(v){return e.exit("codeFenced"),t(v)}function M(v,J,P){let q=0;return z;function z(L){return v.enter("lineEnding"),v.consume(L),v.exit("lineEnding"),V}function V(L){return v.enter("codeFencedFence"),nt(L)?Et(v,F,"linePrefix",i.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(L):F(L)}function F(L){return L===f?(v.enter("codeFencedFenceSequence"),$(L)):P(L)}function $(L){return L===f?(q++,v.consume(L),$):q>=l?(v.exit("codeFencedFenceSequence"),nt(L)?Et(v,Z,"whitespace")(L):Z(L)):P(L)}function Z(L){return L===null||Ve(L)?(v.exit("codeFencedFence"),J(L)):P(L)}}}function m8(e,t,n){const i=this;return u;function u(l){return l===null?n(l):(e.enter("lineEnding"),e.consume(l),e.exit("lineEnding"),o)}function o(l){return i.parser.lazy[i.now().line]?n(l):t(l)}}const sp={name:"codeIndented",tokenize:g8},p8={partial:!0,tokenize:E8};function g8(e,t,n){const i=this;return u;function u(h){return e.enter("codeIndented"),Et(e,o,"linePrefix",5)(h)}function o(h){const p=i.events[i.events.length-1];return p&&p[1].type==="linePrefix"&&p[2].sliceSerialize(p[1],!0).length>=4?l(h):n(h)}function l(h){return h===null?d(h):Ve(h)?e.attempt(p8,l,d)(h):(e.enter("codeFlowValue"),f(h))}function f(h){return h===null||Ve(h)?(e.exit("codeFlowValue"),l(h)):(e.consume(h),f)}function d(h){return e.exit("codeIndented"),t(h)}}function E8(e,t,n){const i=this;return u;function u(l){return i.parser.lazy[i.now().line]?n(l):Ve(l)?(e.enter("lineEnding"),e.consume(l),e.exit("lineEnding"),u):Et(e,o,"linePrefix",5)(l)}function o(l){const f=i.events[i.events.length-1];return f&&f[1].type==="linePrefix"&&f[2].sliceSerialize(f[1],!0).length>=4?t(l):Ve(l)?u(l):n(l)}}const y8={name:"codeText",previous:T8,resolve:b8,tokenize:A8};function b8(e){let t=e.length-4,n=3,i,u;if((e[n][1].type==="lineEnding"||e[n][1].type==="space")&&(e[t][1].type==="lineEnding"||e[t][1].type==="space")){for(i=n;++i<t;)if(e[i][1].type==="codeTextData"){e[n][1].type="codeTextPadding",e[t][1].type="codeTextPadding",n+=2,t-=2;break}}for(i=n-1,t++;++i<=t;)u===void 0?i!==t&&e[i][1].type!=="lineEnding"&&(u=i):(i===t||e[i][1].type==="lineEnding")&&(e[u][1].type="codeTextData",i!==u+2&&(e[u][1].end=e[i-1][1].end,e.splice(u+2,i-u-2),t-=i-u-2,i=u+2),u=void 0);return e}function T8(e){return e!==96||this.events[this.events.length-1][1].type==="characterEscape"}function A8(e,t,n){let i=0,u,o;return l;function l(g){return e.enter("codeText"),e.enter("codeTextSequence"),f(g)}function f(g){return g===96?(e.consume(g),i++,f):(e.exit("codeTextSequence"),d(g))}function d(g){return g===null?n(g):g===32?(e.enter("space"),e.consume(g),e.exit("space"),d):g===96?(o=e.enter("codeTextSequence"),u=0,p(g)):Ve(g)?(e.enter("lineEnding"),e.consume(g),e.exit("lineEnding"),d):(e.enter("codeTextData"),h(g))}function h(g){return g===null||g===32||g===96||Ve(g)?(e.exit("codeTextData"),d(g)):(e.consume(g),h)}function p(g){return g===96?(e.consume(g),u++,p):u===i?(e.exit("codeTextSequence"),e.exit("codeText"),t(g)):(o.type="codeTextData",h(g))}}class S8{constructor(t){this.left=t?[...t]:[],this.right=[]}get(t){if(t<0||t>=this.left.length+this.right.length)throw new RangeError("Cannot access index `"+t+"` in a splice buffer of size `"+(this.left.length+this.right.length)+"`");return t<this.left.length?this.left[t]:this.right[this.right.length-t+this.left.length-1]}get length(){return this.left.length+this.right.length}shift(){return this.setCursor(0),this.right.pop()}slice(t,n){const i=n??Number.POSITIVE_INFINITY;return i<this.left.length?this.left.slice(t,i):t>this.left.length?this.right.slice(this.right.length-i+this.left.length,this.right.length-t+this.left.length).reverse():this.left.slice(t).concat(this.right.slice(this.right.length-i+this.left.length).reverse())}splice(t,n,i){const u=n||0;this.setCursor(Math.trunc(t));const o=this.right.splice(this.right.length-u,Number.POSITIVE_INFINITY);return i&&zo(this.left,i),o.reverse()}pop(){return this.setCursor(Number.POSITIVE_INFINITY),this.left.pop()}push(t){this.setCursor(Number.POSITIVE_INFINITY),this.left.push(t)}pushMany(t){this.setCursor(Number.POSITIVE_INFINITY),zo(this.left,t)}unshift(t){this.setCursor(0),this.right.push(t)}unshiftMany(t){this.setCursor(0),zo(this.right,t.reverse())}setCursor(t){if(!(t===this.left.length||t>this.left.length&&this.right.length===0||t<0&&this.left.length===0))if(t<this.left.length){const n=this.left.splice(t,Number.POSITIVE_INFINITY);zo(this.right,n.reverse())}else{const n=this.right.splice(this.left.length+this.right.length-t,Number.POSITIVE_INFINITY);zo(this.left,n.reverse())}}}function zo(e,t){let n=0;if(t.length<1e4)e.push(...t);else for(;n<t.length;)e.push(...t.slice(n,n+1e4)),n+=1e4}function CC(e){const t={};let n=-1,i,u,o,l,f,d,h;const p=new S8(e);for(;++n<p.length;){for(;n in t;)n=t[n];if(i=p.get(n),n&&i[1].type==="chunkFlow"&&p.get(n-1)[1].type==="listItemPrefix"&&(d=i[1]._tokenizer.events,o=0,o<d.length&&d[o][1].type==="lineEndingBlank"&&(o+=2),o<d.length&&d[o][1].type==="content"))for(;++o<d.length&&d[o][1].type!=="content";)d[o][1].type==="chunkText"&&(d[o][1]._isInFirstContentOfListItem=!0,o++);if(i[0]==="enter")i[1].contentType&&(Object.assign(t,D8(p,n)),n=t[n],h=!0);else if(i[1]._container){for(o=n,u=void 0;o--;)if(l=p.get(o),l[1].type==="lineEnding"||l[1].type==="lineEndingBlank")l[0]==="enter"&&(u&&(p.get(u)[1].type="lineEndingBlank"),l[1].type="lineEnding",u=o);else if(!(l[1].type==="linePrefix"||l[1].type==="listItemIndent"))break;u&&(i[1].end={...p.get(u)[1].start},f=p.slice(u,n),f.unshift(i),p.splice(u,n-u+1,f))}}return Tr(e,0,Number.POSITIVE_INFINITY,p.slice(0)),!h}function D8(e,t){const n=e.get(t)[1],i=e.get(t)[2];let u=t-1;const o=[];let l=n._tokenizer;l||(l=i.parser[n.contentType](n.start),n._contentTypeTextTrailing&&(l._contentTypeTextTrailing=!0));const f=l.events,d=[],h={};let p,g,b=-1,T=n,A=0,_=0;const O=[_];for(;T;){for(;e.get(++u)[1]!==T;);o.push(u),T._tokenizer||(p=i.sliceStream(T),T.next||p.push(null),g&&l.defineSkip(T.start),T._isInFirstContentOfListItem&&(l._gfmTasklistFirstContentOfListItem=!0),l.write(p),T._isInFirstContentOfListItem&&(l._gfmTasklistFirstContentOfListItem=void 0)),g=T,T=T.next}for(T=n;++b<f.length;)f[b][0]==="exit"&&f[b-1][0]==="enter"&&f[b][1].type===f[b-1][1].type&&f[b][1].start.line!==f[b][1].end.line&&(_=b+1,O.push(_),T._tokenizer=void 0,T.previous=void 0,T=T.next);for(l.events=[],T?(T._tokenizer=void 0,T.previous=void 0):O.pop(),b=O.length;b--;){const C=f.slice(O[b],O[b+1]),N=o.pop();d.push([N,N+C.length-1]),e.splice(N,2,C)}for(d.reverse(),b=-1;++b<d.length;)h[A+d[b][0]]=A+d[b][1],A+=d[b][1]-d[b][0]-1;return h}const v8={resolve:_8,tokenize:x8},C8={partial:!0,tokenize:R8};function _8(e){return CC(e),e}function x8(e,t){let n;return i;function i(f){return e.enter("content"),n=e.enter("chunkContent",{contentType:"content"}),u(f)}function u(f){return f===null?o(f):Ve(f)?e.check(C8,l,o)(f):(e.consume(f),u)}function o(f){return e.exit("chunkContent"),e.exit("content"),t(f)}function l(f){return e.consume(f),e.exit("chunkContent"),n.next=e.enter("chunkContent",{contentType:"content",previous:n}),n=n.next,u}}function R8(e,t,n){const i=this;return u;function u(l){return e.exit("chunkContent"),e.enter("lineEnding"),e.consume(l),e.exit("lineEnding"),Et(e,o,"linePrefix")}function o(l){if(l===null||Ve(l))return n(l);const f=i.events[i.events.length-1];return!i.parser.constructs.disable.null.includes("codeIndented")&&f&&f[1].type==="linePrefix"&&f[2].sliceSerialize(f[1],!0).length>=4?t(l):e.interrupt(i.parser.constructs.flow,n,t)(l)}}function _C(e,t,n,i,u,o,l,f,d){const h=d||Number.POSITIVE_INFINITY;let p=0;return g;function g(C){return C===60?(e.enter(i),e.enter(u),e.enter(o),e.consume(C),e.exit(o),b):C===null||C===32||C===41||jf(C)?n(C):(e.enter(i),e.enter(l),e.enter(f),e.enter("chunkString",{contentType:"string"}),_(C))}function b(C){return C===62?(e.enter(o),e.consume(C),e.exit(o),e.exit(u),e.exit(i),t):(e.enter(f),e.enter("chunkString",{contentType:"string"}),T(C))}function T(C){return C===62?(e.exit("chunkString"),e.exit(f),b(C)):C===null||C===60||Ve(C)?n(C):(e.consume(C),C===92?A:T)}function A(C){return C===60||C===62||C===92?(e.consume(C),T):T(C)}function _(C){return!p&&(C===null||C===41||wt(C))?(e.exit("chunkString"),e.exit(f),e.exit(l),e.exit(i),t(C)):p<h&&C===40?(e.consume(C),p++,_):C===41?(e.consume(C),p--,_):C===null||C===32||C===40||jf(C)?n(C):(e.consume(C),C===92?O:_)}function O(C){return C===40||C===41||C===92?(e.consume(C),_):_(C)}}function xC(e,t,n,i,u,o){const l=this;let f=0,d;return h;function h(T){return e.enter(i),e.enter(u),e.consume(T),e.exit(u),e.enter(o),p}function p(T){return f>999||T===null||T===91||T===93&&!d||T===94&&!f&&"_hiddenFootnoteSupport"in l.parser.constructs?n(T):T===93?(e.exit(o),e.enter(u),e.consume(T),e.exit(u),e.exit(i),t):Ve(T)?(e.enter("lineEnding"),e.consume(T),e.exit("lineEnding"),p):(e.enter("chunkString",{contentType:"string"}),g(T))}function g(T){return T===null||T===91||T===93||Ve(T)||f++>999?(e.exit("chunkString"),p(T)):(e.consume(T),d||(d=!nt(T)),T===92?b:g)}function b(T){return T===91||T===92||T===93?(e.consume(T),f++,g):g(T)}}function RC(e,t,n,i,u,o){let l;return f;function f(b){return b===34||b===39||b===40?(e.enter(i),e.enter(u),e.consume(b),e.exit(u),l=b===40?41:b,d):n(b)}function d(b){return b===l?(e.enter(u),e.consume(b),e.exit(u),e.exit(i),t):(e.enter(o),h(b))}function h(b){return b===l?(e.exit(o),d(l)):b===null?n(b):Ve(b)?(e.enter("lineEnding"),e.consume(b),e.exit("lineEnding"),Et(e,h,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),p(b))}function p(b){return b===l||b===null||Ve(b)?(e.exit("chunkString"),h(b)):(e.consume(b),b===92?g:p)}function g(b){return b===l||b===92?(e.consume(b),p):p(b)}}function sl(e,t){let n;return i;function i(u){return Ve(u)?(e.enter("lineEnding"),e.consume(u),e.exit("lineEnding"),n=!0,i):nt(u)?Et(e,i,n?"linePrefix":"lineSuffix")(u):t(u)}}const w8={name:"definition",tokenize:N8},O8={partial:!0,tokenize:k8};function N8(e,t,n){const i=this;let u;return o;function o(T){return e.enter("definition"),l(T)}function l(T){return xC.call(i,e,f,n,"definitionLabel","definitionLabelMarker","definitionLabelString")(T)}function f(T){return u=$r(i.sliceSerialize(i.events[i.events.length-1][1]).slice(1,-1)),T===58?(e.enter("definitionMarker"),e.consume(T),e.exit("definitionMarker"),d):n(T)}function d(T){return wt(T)?sl(e,h)(T):h(T)}function h(T){return _C(e,p,n,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(T)}function p(T){return e.attempt(O8,g,g)(T)}function g(T){return nt(T)?Et(e,b,"whitespace")(T):b(T)}function b(T){return T===null||Ve(T)?(e.exit("definition"),i.parser.defined.push(u),t(T)):n(T)}}function k8(e,t,n){return i;function i(f){return wt(f)?sl(e,u)(f):n(f)}function u(f){return RC(e,o,n,"definitionTitle","definitionTitleMarker","definitionTitleString")(f)}function o(f){return nt(f)?Et(e,l,"whitespace")(f):l(f)}function l(f){return f===null||Ve(f)?t(f):n(f)}}const L8={name:"hardBreakEscape",tokenize:M8};function M8(e,t,n){return i;function i(o){return e.enter("hardBreakEscape"),e.consume(o),u}function u(o){return Ve(o)?(e.exit("hardBreakEscape"),t(o)):n(o)}}const I8={name:"headingAtx",resolve:P8,tokenize:F8};function P8(e,t){let n=e.length-2,i=3,u,o;return e[i][1].type==="whitespace"&&(i+=2),n-2>i&&e[n][1].type==="whitespace"&&(n-=2),e[n][1].type==="atxHeadingSequence"&&(i===n-1||n-4>i&&e[n-2][1].type==="whitespace")&&(n-=i+1===n?2:4),n>i&&(u={type:"atxHeadingText",start:e[i][1].start,end:e[n][1].end},o={type:"chunkText",start:e[i][1].start,end:e[n][1].end,contentType:"text"},Tr(e,i,n-i+1,[["enter",u,t],["enter",o,t],["exit",o,t],["exit",u,t]])),e}function F8(e,t,n){let i=0;return u;function u(p){return e.enter("atxHeading"),o(p)}function o(p){return e.enter("atxHeadingSequence"),l(p)}function l(p){return p===35&&i++<6?(e.consume(p),l):p===null||wt(p)?(e.exit("atxHeadingSequence"),f(p)):n(p)}function f(p){return p===35?(e.enter("atxHeadingSequence"),d(p)):p===null||Ve(p)?(e.exit("atxHeading"),t(p)):nt(p)?Et(e,f,"whitespace")(p):(e.enter("atxHeadingText"),h(p))}function d(p){return p===35?(e.consume(p),d):(e.exit("atxHeadingSequence"),f(p))}function h(p){return p===null||p===35||wt(p)?(e.exit("atxHeadingText"),f(p)):(e.consume(p),h)}}const B8=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],dS=["pre","script","style","textarea"],U8={concrete:!0,name:"htmlFlow",resolveTo:V8,tokenize:j8},H8={partial:!0,tokenize:Y8},z8={partial:!0,tokenize:q8};function V8(e){let t=e.length;for(;t--&&!(e[t][0]==="enter"&&e[t][1].type==="htmlFlow"););return t>1&&e[t-2][1].type==="linePrefix"&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2)),e}function j8(e,t,n){const i=this;let u,o,l,f,d;return h;function h(w){return p(w)}function p(w){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(w),g}function g(w){return w===33?(e.consume(w),b):w===47?(e.consume(w),o=!0,_):w===63?(e.consume(w),u=3,i.interrupt?t:S):zn(w)?(e.consume(w),l=String.fromCharCode(w),O):n(w)}function b(w){return w===45?(e.consume(w),u=2,T):w===91?(e.consume(w),u=5,f=0,A):zn(w)?(e.consume(w),u=4,i.interrupt?t:S):n(w)}function T(w){return w===45?(e.consume(w),i.interrupt?t:S):n(w)}function A(w){const Te="CDATA[";return w===Te.charCodeAt(f++)?(e.consume(w),f===Te.length?i.interrupt?t:F:A):n(w)}function _(w){return zn(w)?(e.consume(w),l=String.fromCharCode(w),O):n(w)}function O(w){if(w===null||w===47||w===62||wt(w)){const Te=w===47,Re=l.toLowerCase();return!Te&&!o&&dS.includes(Re)?(u=1,i.interrupt?t(w):F(w)):B8.includes(l.toLowerCase())?(u=6,Te?(e.consume(w),C):i.interrupt?t(w):F(w)):(u=7,i.interrupt&&!i.parser.lazy[i.now().line]?n(w):o?N(w):R(w))}return w===45||In(w)?(e.consume(w),l+=String.fromCharCode(w),O):n(w)}function C(w){return w===62?(e.consume(w),i.interrupt?t:F):n(w)}function N(w){return nt(w)?(e.consume(w),N):z(w)}function R(w){return w===47?(e.consume(w),z):w===58||w===95||zn(w)?(e.consume(w),Y):nt(w)?(e.consume(w),R):z(w)}function Y(w){return w===45||w===46||w===58||w===95||In(w)?(e.consume(w),Y):M(w)}function M(w){return w===61?(e.consume(w),v):nt(w)?(e.consume(w),M):R(w)}function v(w){return w===null||w===60||w===61||w===62||w===96?n(w):w===34||w===39?(e.consume(w),d=w,J):nt(w)?(e.consume(w),v):P(w)}function J(w){return w===d?(e.consume(w),d=null,q):w===null||Ve(w)?n(w):(e.consume(w),J)}function P(w){return w===null||w===34||w===39||w===47||w===60||w===61||w===62||w===96||wt(w)?M(w):(e.consume(w),P)}function q(w){return w===47||w===62||nt(w)?R(w):n(w)}function z(w){return w===62?(e.consume(w),V):n(w)}function V(w){return w===null||Ve(w)?F(w):nt(w)?(e.consume(w),V):n(w)}function F(w){return w===45&&u===2?(e.consume(w),B):w===60&&u===1?(e.consume(w),K):w===62&&u===4?(e.consume(w),ne):w===63&&u===3?(e.consume(w),S):w===93&&u===5?(e.consume(w),_e):Ve(w)&&(u===6||u===7)?(e.exit("htmlFlowData"),e.check(H8,ge,$)(w)):w===null||Ve(w)?(e.exit("htmlFlowData"),$(w)):(e.consume(w),F)}function $(w){return e.check(z8,Z,ge)(w)}function Z(w){return e.enter("lineEnding"),e.consume(w),e.exit("lineEnding"),L}function L(w){return w===null||Ve(w)?$(w):(e.enter("htmlFlowData"),F(w))}function B(w){return w===45?(e.consume(w),S):F(w)}function K(w){return w===47?(e.consume(w),l="",Q):F(w)}function Q(w){if(w===62){const Te=l.toLowerCase();return dS.includes(Te)?(e.consume(w),ne):F(w)}return zn(w)&&l.length<8?(e.consume(w),l+=String.fromCharCode(w),Q):F(w)}function _e(w){return w===93?(e.consume(w),S):F(w)}function S(w){return w===62?(e.consume(w),ne):w===45&&u===2?(e.consume(w),S):F(w)}function ne(w){return w===null||Ve(w)?(e.exit("htmlFlowData"),ge(w)):(e.consume(w),ne)}function ge(w){return e.exit("htmlFlow"),t(w)}}function q8(e,t,n){const i=this;return u;function u(l){return Ve(l)?(e.enter("lineEnding"),e.consume(l),e.exit("lineEnding"),o):n(l)}function o(l){return i.parser.lazy[i.now().line]?n(l):t(l)}}function Y8(e,t,n){return i;function i(u){return e.enter("lineEnding"),e.consume(u),e.exit("lineEnding"),e.attempt(Pl,t,n)}}const G8={name:"htmlText",tokenize:X8};function X8(e,t,n){const i=this;let u,o,l;return f;function f(S){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(S),d}function d(S){return S===33?(e.consume(S),h):S===47?(e.consume(S),M):S===63?(e.consume(S),R):zn(S)?(e.consume(S),P):n(S)}function h(S){return S===45?(e.consume(S),p):S===91?(e.consume(S),o=0,A):zn(S)?(e.consume(S),N):n(S)}function p(S){return S===45?(e.consume(S),T):n(S)}function g(S){return S===null?n(S):S===45?(e.consume(S),b):Ve(S)?(l=g,K(S)):(e.consume(S),g)}function b(S){return S===45?(e.consume(S),T):g(S)}function T(S){return S===62?B(S):S===45?b(S):g(S)}function A(S){const ne="CDATA[";return S===ne.charCodeAt(o++)?(e.consume(S),o===ne.length?_:A):n(S)}function _(S){return S===null?n(S):S===93?(e.consume(S),O):Ve(S)?(l=_,K(S)):(e.consume(S),_)}function O(S){return S===93?(e.consume(S),C):_(S)}function C(S){return S===62?B(S):S===93?(e.consume(S),C):_(S)}function N(S){return S===null||S===62?B(S):Ve(S)?(l=N,K(S)):(e.consume(S),N)}function R(S){return S===null?n(S):S===63?(e.consume(S),Y):Ve(S)?(l=R,K(S)):(e.consume(S),R)}function Y(S){return S===62?B(S):R(S)}function M(S){return zn(S)?(e.consume(S),v):n(S)}function v(S){return S===45||In(S)?(e.consume(S),v):J(S)}function J(S){return Ve(S)?(l=J,K(S)):nt(S)?(e.consume(S),J):B(S)}function P(S){return S===45||In(S)?(e.consume(S),P):S===47||S===62||wt(S)?q(S):n(S)}function q(S){return S===47?(e.consume(S),B):S===58||S===95||zn(S)?(e.consume(S),z):Ve(S)?(l=q,K(S)):nt(S)?(e.consume(S),q):B(S)}function z(S){return S===45||S===46||S===58||S===95||In(S)?(e.consume(S),z):V(S)}function V(S){return S===61?(e.consume(S),F):Ve(S)?(l=V,K(S)):nt(S)?(e.consume(S),V):q(S)}function F(S){return S===null||S===60||S===61||S===62||S===96?n(S):S===34||S===39?(e.consume(S),u=S,$):Ve(S)?(l=F,K(S)):nt(S)?(e.consume(S),F):(e.consume(S),Z)}function $(S){return S===u?(e.consume(S),u=void 0,L):S===null?n(S):Ve(S)?(l=$,K(S)):(e.consume(S),$)}function Z(S){return S===null||S===34||S===39||S===60||S===61||S===96?n(S):S===47||S===62||wt(S)?q(S):(e.consume(S),Z)}function L(S){return S===47||S===62||wt(S)?q(S):n(S)}function B(S){return S===62?(e.consume(S),e.exit("htmlTextData"),e.exit("htmlText"),t):n(S)}function K(S){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(S),e.exit("lineEnding"),Q}function Q(S){return nt(S)?Et(e,_e,"linePrefix",i.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(S):_e(S)}function _e(S){return e.enter("htmlTextData"),l(S)}}const kg={name:"labelEnd",resolveAll:$8,resolveTo:Z8,tokenize:J8},K8={tokenize:eP},W8={tokenize:tP},Q8={tokenize:nP};function $8(e){let t=-1;const n=[];for(;++t<e.length;){const i=e[t][1];if(n.push(e[t]),i.type==="labelImage"||i.type==="labelLink"||i.type==="labelEnd"){const u=i.type==="labelImage"?4:2;i.type="data",t+=u}}return e.length!==n.length&&Tr(e,0,e.length,n),e}function Z8(e,t){let n=e.length,i=0,u,o,l,f;for(;n--;)if(u=e[n][1],o){if(u.type==="link"||u.type==="labelLink"&&u._inactive)break;e[n][0]==="enter"&&u.type==="labelLink"&&(u._inactive=!0)}else if(l){if(e[n][0]==="enter"&&(u.type==="labelImage"||u.type==="labelLink")&&!u._balanced&&(o=n,u.type!=="labelLink")){i=2;break}}else u.type==="labelEnd"&&(l=n);const d={type:e[o][1].type==="labelLink"?"link":"image",start:{...e[o][1].start},end:{...e[e.length-1][1].end}},h={type:"label",start:{...e[o][1].start},end:{...e[l][1].end}},p={type:"labelText",start:{...e[o+i+2][1].end},end:{...e[l-2][1].start}};return f=[["enter",d,t],["enter",h,t]],f=Pr(f,e.slice(o+1,o+i+3)),f=Pr(f,[["enter",p,t]]),f=Pr(f,od(t.parser.constructs.insideSpan.null,e.slice(o+i+4,l-3),t)),f=Pr(f,[["exit",p,t],e[l-2],e[l-1],["exit",h,t]]),f=Pr(f,e.slice(l+1)),f=Pr(f,[["exit",d,t]]),Tr(e,o,e.length,f),e}function J8(e,t,n){const i=this;let u=i.events.length,o,l;for(;u--;)if((i.events[u][1].type==="labelImage"||i.events[u][1].type==="labelLink")&&!i.events[u][1]._balanced){o=i.events[u][1];break}return f;function f(b){return o?o._inactive?g(b):(l=i.parser.defined.includes($r(i.sliceSerialize({start:o.end,end:i.now()}))),e.enter("labelEnd"),e.enter("labelMarker"),e.consume(b),e.exit("labelMarker"),e.exit("labelEnd"),d):n(b)}function d(b){return b===40?e.attempt(K8,p,l?p:g)(b):b===91?e.attempt(W8,p,l?h:g)(b):l?p(b):g(b)}function h(b){return e.attempt(Q8,p,g)(b)}function p(b){return t(b)}function g(b){return o._balanced=!0,n(b)}}function eP(e,t,n){return i;function i(g){return e.enter("resource"),e.enter("resourceMarker"),e.consume(g),e.exit("resourceMarker"),u}function u(g){return wt(g)?sl(e,o)(g):o(g)}function o(g){return g===41?p(g):_C(e,l,f,"resourceDestination","resourceDestinationLiteral","resourceDestinationLiteralMarker","resourceDestinationRaw","resourceDestinationString",32)(g)}function l(g){return wt(g)?sl(e,d)(g):p(g)}function f(g){return n(g)}function d(g){return g===34||g===39||g===40?RC(e,h,n,"resourceTitle","resourceTitleMarker","resourceTitleString")(g):p(g)}function h(g){return wt(g)?sl(e,p)(g):p(g)}function p(g){return g===41?(e.enter("resourceMarker"),e.consume(g),e.exit("resourceMarker"),e.exit("resource"),t):n(g)}}function tP(e,t,n){const i=this;return u;function u(f){return xC.call(i,e,o,l,"reference","referenceMarker","referenceString")(f)}function o(f){return i.parser.defined.includes($r(i.sliceSerialize(i.events[i.events.length-1][1]).slice(1,-1)))?t(f):n(f)}function l(f){return n(f)}}function nP(e,t,n){return i;function i(o){return e.enter("reference"),e.enter("referenceMarker"),e.consume(o),e.exit("referenceMarker"),u}function u(o){return o===93?(e.enter("referenceMarker"),e.consume(o),e.exit("referenceMarker"),e.exit("reference"),t):n(o)}}const rP={name:"labelStartImage",resolveAll:kg.resolveAll,tokenize:iP};function iP(e,t,n){const i=this;return u;function u(f){return e.enter("labelImage"),e.enter("labelImageMarker"),e.consume(f),e.exit("labelImageMarker"),o}function o(f){return f===91?(e.enter("labelMarker"),e.consume(f),e.exit("labelMarker"),e.exit("labelImage"),l):n(f)}function l(f){return f===94&&"_hiddenFootnoteSupport"in i.parser.constructs?n(f):t(f)}}const aP={name:"labelStartLink",resolveAll:kg.resolveAll,tokenize:uP};function uP(e,t,n){const i=this;return u;function u(l){return e.enter("labelLink"),e.enter("labelMarker"),e.consume(l),e.exit("labelMarker"),e.exit("labelLink"),o}function o(l){return l===94&&"_hiddenFootnoteSupport"in i.parser.constructs?n(l):t(l)}}const op={name:"lineEnding",tokenize:sP};function sP(e,t){return n;function n(i){return e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),Et(e,t,"linePrefix")}}const _f={name:"thematicBreak",tokenize:oP};function oP(e,t,n){let i=0,u;return o;function o(h){return e.enter("thematicBreak"),l(h)}function l(h){return u=h,f(h)}function f(h){return h===u?(e.enter("thematicBreakSequence"),d(h)):i>=3&&(h===null||Ve(h))?(e.exit("thematicBreak"),t(h)):n(h)}function d(h){return h===u?(e.consume(h),i++,d):(e.exit("thematicBreakSequence"),nt(h)?Et(e,f,"whitespace")(h):f(h))}}const tr={continuation:{tokenize:dP},exit:mP,name:"list",tokenize:fP},lP={partial:!0,tokenize:pP},cP={partial:!0,tokenize:hP};function fP(e,t,n){const i=this,u=i.events[i.events.length-1];let o=u&&u[1].type==="linePrefix"?u[2].sliceSerialize(u[1],!0).length:0,l=0;return f;function f(T){const A=i.containerState.type||(T===42||T===43||T===45?"listUnordered":"listOrdered");if(A==="listUnordered"?!i.containerState.marker||T===i.containerState.marker:c0(T)){if(i.containerState.type||(i.containerState.type=A,e.enter(A,{_container:!0})),A==="listUnordered")return e.enter("listItemPrefix"),T===42||T===45?e.check(_f,n,h)(T):h(T);if(!i.interrupt||T===49)return e.enter("listItemPrefix"),e.enter("listItemValue"),d(T)}return n(T)}function d(T){return c0(T)&&++l<10?(e.consume(T),d):(!i.interrupt||l<2)&&(i.containerState.marker?T===i.containerState.marker:T===41||T===46)?(e.exit("listItemValue"),h(T)):n(T)}function h(T){return e.enter("listItemMarker"),e.consume(T),e.exit("listItemMarker"),i.containerState.marker=i.containerState.marker||T,e.check(Pl,i.interrupt?n:p,e.attempt(lP,b,g))}function p(T){return i.containerState.initialBlankLine=!0,o++,b(T)}function g(T){return nt(T)?(e.enter("listItemPrefixWhitespace"),e.consume(T),e.exit("listItemPrefixWhitespace"),b):n(T)}function b(T){return i.containerState.size=o+i.sliceSerialize(e.exit("listItemPrefix"),!0).length,t(T)}}function dP(e,t,n){const i=this;return i.containerState._closeFlow=void 0,e.check(Pl,u,o);function u(f){return i.containerState.furtherBlankLines=i.containerState.furtherBlankLines||i.containerState.initialBlankLine,Et(e,t,"listItemIndent",i.containerState.size+1)(f)}function o(f){return i.containerState.furtherBlankLines||!nt(f)?(i.containerState.furtherBlankLines=void 0,i.containerState.initialBlankLine=void 0,l(f)):(i.containerState.furtherBlankLines=void 0,i.containerState.initialBlankLine=void 0,e.attempt(cP,t,l)(f))}function l(f){return i.containerState._closeFlow=!0,i.interrupt=void 0,Et(e,e.attempt(tr,t,n),"linePrefix",i.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(f)}}function hP(e,t,n){const i=this;return Et(e,u,"listItemIndent",i.containerState.size+1);function u(o){const l=i.events[i.events.length-1];return l&&l[1].type==="listItemIndent"&&l[2].sliceSerialize(l[1],!0).length===i.containerState.size?t(o):n(o)}}function mP(e){e.exit(this.containerState.type)}function pP(e,t,n){const i=this;return Et(e,u,"listItemPrefixWhitespace",i.parser.constructs.disable.null.includes("codeIndented")?void 0:5);function u(o){const l=i.events[i.events.length-1];return!nt(o)&&l&&l[1].type==="listItemPrefixWhitespace"?t(o):n(o)}}const hS={name:"setextUnderline",resolveTo:gP,tokenize:EP};function gP(e,t){let n=e.length,i,u,o;for(;n--;)if(e[n][0]==="enter"){if(e[n][1].type==="content"){i=n;break}e[n][1].type==="paragraph"&&(u=n)}else e[n][1].type==="content"&&e.splice(n,1),!o&&e[n][1].type==="definition"&&(o=n);const l={type:"setextHeading",start:{...e[i][1].start},end:{...e[e.length-1][1].end}};return e[u][1].type="setextHeadingText",o?(e.splice(u,0,["enter",l,t]),e.splice(o+1,0,["exit",e[i][1],t]),e[i][1].end={...e[o][1].end}):e[i][1]=l,e.push(["exit",l,t]),e}function EP(e,t,n){const i=this;let u;return o;function o(h){let p=i.events.length,g;for(;p--;)if(i.events[p][1].type!=="lineEnding"&&i.events[p][1].type!=="linePrefix"&&i.events[p][1].type!=="content"){g=i.events[p][1].type==="paragraph";break}return!i.parser.lazy[i.now().line]&&(i.interrupt||g)?(e.enter("setextHeadingLine"),u=h,l(h)):n(h)}function l(h){return e.enter("setextHeadingLineSequence"),f(h)}function f(h){return h===u?(e.consume(h),f):(e.exit("setextHeadingLineSequence"),nt(h)?Et(e,d,"lineSuffix")(h):d(h))}function d(h){return h===null||Ve(h)?(e.exit("setextHeadingLine"),t(h)):n(h)}}const yP={tokenize:bP};function bP(e){const t=this,n=e.attempt(Pl,i,e.attempt(this.parser.constructs.flowInitial,u,Et(e,e.attempt(this.parser.constructs.flow,u,e.attempt(v8,u)),"linePrefix")));return n;function i(o){if(o===null){e.consume(o);return}return e.enter("lineEndingBlank"),e.consume(o),e.exit("lineEndingBlank"),t.currentConstruct=void 0,n}function u(o){if(o===null){e.consume(o);return}return e.enter("lineEnding"),e.consume(o),e.exit("lineEnding"),t.currentConstruct=void 0,n}}const TP={resolveAll:OC()},AP=wC("string"),SP=wC("text");function wC(e){return{resolveAll:OC(e==="text"?DP:void 0),tokenize:t};function t(n){const i=this,u=this.parser.constructs[e],o=n.attempt(u,l,f);return l;function l(p){return h(p)?o(p):f(p)}function f(p){if(p===null){n.consume(p);return}return n.enter("data"),n.consume(p),d}function d(p){return h(p)?(n.exit("data"),o(p)):(n.consume(p),d)}function h(p){if(p===null)return!0;const g=u[p];let b=-1;if(g)for(;++b<g.length;){const T=g[b];if(!T.previous||T.previous.call(i,i.previous))return!0}return!1}}}function OC(e){return t;function t(n,i){let u=-1,o;for(;++u<=n.length;)o===void 0?n[u]&&n[u][1].type==="data"&&(o=u,u++):(!n[u]||n[u][1].type!=="data")&&(u!==o+2&&(n[o][1].end=n[u-1][1].end,n.splice(o+2,u-o-2),u=o+2),o=void 0);return e?e(n,i):n}}function DP(e,t){let n=0;for(;++n<=e.length;)if((n===e.length||e[n][1].type==="lineEnding")&&e[n-1][1].type==="data"){const i=e[n-1][1],u=t.sliceStream(i);let o=u.length,l=-1,f=0,d;for(;o--;){const h=u[o];if(typeof h=="string"){for(l=h.length;h.charCodeAt(l-1)===32;)f++,l--;if(l)break;l=-1}else if(h===-2)d=!0,f++;else if(h!==-1){o++;break}}if(t._contentTypeTextTrailing&&n===e.length&&(f=0),f){const h={type:n===e.length||d||f<2?"lineSuffix":"hardBreakTrailing",start:{_bufferIndex:o?l:i.start._bufferIndex+l,_index:i.start._index+o,line:i.end.line,column:i.end.column-f,offset:i.end.offset-f},end:{...i.end}};i.end={...h.start},i.start.offset===i.end.offset?Object.assign(i,h):(e.splice(n,0,["enter",h,t],["exit",h,t]),n+=2)}n++}return e}const vP={42:tr,43:tr,45:tr,48:tr,49:tr,50:tr,51:tr,52:tr,53:tr,54:tr,55:tr,56:tr,57:tr,62:SC},CP={91:w8},_P={[-2]:sp,[-1]:sp,32:sp},xP={35:I8,42:_f,45:[hS,_f],60:U8,61:hS,95:_f,96:fS,126:fS},RP={38:vC,92:DC},wP={[-5]:op,[-4]:op,[-3]:op,33:rP,38:vC,42:f0,60:[a8,G8],91:aP,92:[L8,DC],93:kg,95:f0,96:y8},OP={null:[f0,TP]},NP={null:[42,95]},kP={null:[]},LP=Object.freeze(Object.defineProperty({__proto__:null,attentionMarkers:NP,contentInitial:CP,disable:kP,document:vP,flow:xP,flowInitial:_P,insideSpan:OP,string:RP,text:wP},Symbol.toStringTag,{value:"Module"}));function MP(e,t,n){let i={_bufferIndex:-1,_index:0,line:n&&n.line||1,column:n&&n.column||1,offset:n&&n.offset||0};const u={},o=[];let l=[],f=[];const d={attempt:J(M),check:J(v),consume:N,enter:R,exit:Y,interrupt:J(v,{interrupt:!0})},h={code:null,containerState:{},defineSkip:_,events:[],now:A,parser:e,previous:null,sliceSerialize:b,sliceStream:T,write:g};let p=t.tokenize.call(h,d);return t.resolveAll&&o.push(t),h;function g(V){return l=Pr(l,V),O(),l[l.length-1]!==null?[]:(P(t,0),h.events=od(o,h.events,h),h.events)}function b(V,F){return PP(T(V),F)}function T(V){return IP(l,V)}function A(){const{_bufferIndex:V,_index:F,line:$,column:Z,offset:L}=i;return{_bufferIndex:V,_index:F,line:$,column:Z,offset:L}}function _(V){u[V.line]=V.column,z()}function O(){let V;for(;i._index<l.length;){const F=l[i._index];if(typeof F=="string")for(V=i._index,i._bufferIndex<0&&(i._bufferIndex=0);i._index===V&&i._bufferIndex<F.length;)C(F.charCodeAt(i._bufferIndex));else C(F)}}function C(V){p=p(V)}function N(V){Ve(V)?(i.line++,i.column=1,i.offset+=V===-3?2:1,z()):V!==-1&&(i.column++,i.offset++),i._bufferIndex<0?i._index++:(i._bufferIndex++,i._bufferIndex===l[i._index].length&&(i._bufferIndex=-1,i._index++)),h.previous=V}function R(V,F){const $=F||{};return $.type=V,$.start=A(),h.events.push(["enter",$,h]),f.push($),$}function Y(V){const F=f.pop();return F.end=A(),h.events.push(["exit",F,h]),F}function M(V,F){P(V,F.from)}function v(V,F){F.restore()}function J(V,F){return $;function $(Z,L,B){let K,Q,_e,S;return Array.isArray(Z)?ge(Z):"tokenize"in Z?ge([Z]):ne(Z);function ne(xe){return We;function We(Qe){const Nt=Qe!==null&&xe[Qe],mt=Qe!==null&&xe.null,qt=[...Array.isArray(Nt)?Nt:Nt?[Nt]:[],...Array.isArray(mt)?mt:mt?[mt]:[]];return ge(qt)(Qe)}}function ge(xe){return K=xe,Q=0,xe.length===0?B:w(xe[Q])}function w(xe){return We;function We(Qe){return S=q(),_e=xe,xe.partial||(h.currentConstruct=xe),xe.name&&h.parser.constructs.disable.null.includes(xe.name)?Re():xe.tokenize.call(F?Object.assign(Object.create(h),F):h,d,Te,Re)(Qe)}}function Te(xe){return V(_e,S),L}function Re(xe){return S.restore(),++Q<K.length?w(K[Q]):B}}}function P(V,F){V.resolveAll&&!o.includes(V)&&o.push(V),V.resolve&&Tr(h.events,F,h.events.length-F,V.resolve(h.events.slice(F),h)),V.resolveTo&&(h.events=V.resolveTo(h.events,h))}function q(){const V=A(),F=h.previous,$=h.currentConstruct,Z=h.events.length,L=Array.from(f);return{from:Z,restore:B};function B(){i=V,h.previous=F,h.currentConstruct=$,h.events.length=Z,f=L,z()}}function z(){i.line in u&&i.column<2&&(i.column=u[i.line],i.offset+=u[i.line]-1)}}function IP(e,t){const n=t.start._index,i=t.start._bufferIndex,u=t.end._index,o=t.end._bufferIndex;let l;if(n===u)l=[e[n].slice(i,o)];else{if(l=e.slice(n,u),i>-1){const f=l[0];typeof f=="string"?l[0]=f.slice(i):l.shift()}o>0&&l.push(e[u].slice(0,o))}return l}function PP(e,t){let n=-1;const i=[];let u;for(;++n<e.length;){const o=e[n];let l;if(typeof o=="string")l=o;else switch(o){case-5:{l="\r";break}case-4:{l=` +`;break}case-3:{l=`\r +`;break}case-2:{l=t?" ":" ";break}case-1:{if(!t&&u)continue;l=" ";break}default:l=String.fromCharCode(o)}u=o===-2,i.push(l)}return i.join("")}function FP(e){const i={constructs:TC([LP,...(e||{}).extensions||[]]),content:u(ZI),defined:[],document:u(e8),flow:u(yP),lazy:{},string:u(AP),text:u(SP)};return i;function u(o){return l;function l(f){return MP(i,o,f)}}}function BP(e){for(;!CC(e););return e}const mS=/[\0\t\n\r]/g;function UP(){let e=1,t="",n=!0,i;return u;function u(o,l,f){const d=[];let h,p,g,b,T;for(o=t+(typeof o=="string"?o.toString():new TextDecoder(l||void 0).decode(o)),g=0,t="",n&&(o.charCodeAt(0)===65279&&g++,n=void 0);g<o.length;){if(mS.lastIndex=g,h=mS.exec(o),b=h&&h.index!==void 0?h.index:o.length,T=o.charCodeAt(b),!h){t=o.slice(g);break}if(T===10&&g===b&&i)d.push(-3),i=void 0;else switch(i&&(d.push(-5),i=void 0),g<b&&(d.push(o.slice(g,b)),e+=b-g),T){case 0:{d.push(65533),e++;break}case 9:{for(p=Math.ceil(e/4)*4,d.push(-2);e++<p;)d.push(-1);break}case 10:{d.push(-4),e=1;break}default:i=!0,e=1}g=b+1}return f&&(i&&d.push(-5),t&&d.push(t),d.push(null)),d}}const HP=/\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi;function zP(e){return e.replace(HP,VP)}function VP(e,t,n){if(t)return t;if(n.charCodeAt(0)===35){const u=n.charCodeAt(1),o=u===120||u===88;return AC(n.slice(o?2:1),o?16:10)}return Ng(n)||e}const NC={}.hasOwnProperty;function jP(e,t,n){return typeof t!="string"&&(n=t,t=void 0),qP(n)(BP(FP(n).document().write(UP()(e,t,!0))))}function qP(e){const t={transforms:[],canContainEols:["emphasis","fragment","heading","paragraph","strong"],enter:{autolink:o(Sr),autolinkProtocol:q,autolinkEmail:q,atxHeading:o(ni),blockQuote:o(mt),characterEscape:q,characterReference:q,codeFenced:o(qt),codeFencedFenceInfo:l,codeFencedFenceMeta:l,codeIndented:o(qt,l),codeText:o(ln,l),codeTextData:q,data:q,codeFlowValue:q,definition:o(Ar),definitionDestinationString:l,definitionLabelString:l,definitionTitleString:l,emphasis:o(tn),hardBreakEscape:o(ri),hardBreakTrailing:o(ri),htmlFlow:o(Yt,l),htmlFlowData:q,htmlText:o(Yt,l),htmlTextData:q,image:o(ii),label:l,link:o(Sr),listItem:o(jr),listItemValue:b,listOrdered:o(ai,g),listUnordered:o(ai),paragraph:o(ur),reference:w,referenceString:l,resourceDestinationString:l,resourceTitleString:l,setextHeading:o(ni),strong:o(Yn),thematicBreak:o(Gn)},exit:{atxHeading:d(),atxHeadingSequence:M,autolink:d(),autolinkEmail:Nt,autolinkProtocol:Qe,blockQuote:d(),characterEscapeValue:z,characterReferenceMarkerHexadecimal:Re,characterReferenceMarkerNumeric:Re,characterReferenceValue:xe,characterReference:We,codeFenced:d(O),codeFencedFence:_,codeFencedFenceInfo:T,codeFencedFenceMeta:A,codeFlowValue:z,codeIndented:d(C),codeText:d(L),codeTextData:z,data:z,definition:d(),definitionDestinationString:Y,definitionLabelString:N,definitionTitleString:R,emphasis:d(),hardBreakEscape:d(F),hardBreakTrailing:d(F),htmlFlow:d($),htmlFlowData:z,htmlText:d(Z),htmlTextData:z,image:d(K),label:_e,labelText:Q,lineEnding:V,link:d(B),listItem:d(),listOrdered:d(),listUnordered:d(),paragraph:d(),referenceString:Te,resourceDestinationString:S,resourceTitleString:ne,resource:ge,setextHeading:d(P),setextHeadingLineSequence:J,setextHeadingText:v,strong:d(),thematicBreak:d()}};kC(t,(e||{}).mdastExtensions||[]);const n={};return i;function i(le){let Ee={type:"root",children:[]};const Pe={stack:[Ee],tokenStack:[],config:t,enter:f,exit:h,buffer:l,resume:p,data:n},ze=[];let ht=-1;for(;++ht<le.length;)if(le[ht][1].type==="listOrdered"||le[ht][1].type==="listUnordered")if(le[ht][0]==="enter")ze.push(ht);else{const Ft=ze.pop();ht=u(le,Ft,ht)}for(ht=-1;++ht<le.length;){const Ft=t[le[ht][0]];NC.call(Ft,le[ht][1].type)&&Ft[le[ht][1].type].call(Object.assign({sliceSerialize:le[ht][2].sliceSerialize},Pe),le[ht][1])}if(Pe.tokenStack.length>0){const Ft=Pe.tokenStack[Pe.tokenStack.length-1];(Ft[1]||pS).call(Pe,void 0,Ft[0])}for(Ee.position={start:ha(le.length>0?le[0][1].start:{line:1,column:1,offset:0}),end:ha(le.length>0?le[le.length-2][1].end:{line:1,column:1,offset:0})},ht=-1;++ht<t.transforms.length;)Ee=t.transforms[ht](Ee)||Ee;return Ee}function u(le,Ee,Pe){let ze=Ee-1,ht=-1,Ft=!1,Cn,Wt,Gt,Qt;for(;++ze<=Pe;){const Bt=le[ze];switch(Bt[1].type){case"listUnordered":case"listOrdered":case"blockQuote":{Bt[0]==="enter"?ht++:ht--,Qt=void 0;break}case"lineEndingBlank":{Bt[0]==="enter"&&(Cn&&!Qt&&!ht&&!Gt&&(Gt=ze),Qt=void 0);break}case"linePrefix":case"listItemValue":case"listItemMarker":case"listItemPrefix":case"listItemPrefixWhitespace":break;default:Qt=void 0}if(!ht&&Bt[0]==="enter"&&Bt[1].type==="listItemPrefix"||ht===-1&&Bt[0]==="exit"&&(Bt[1].type==="listUnordered"||Bt[1].type==="listOrdered")){if(Cn){let nn=ze;for(Wt=void 0;nn--;){const On=le[nn];if(On[1].type==="lineEnding"||On[1].type==="lineEndingBlank"){if(On[0]==="exit")continue;Wt&&(le[Wt][1].type="lineEndingBlank",Ft=!0),On[1].type="lineEnding",Wt=nn}else if(!(On[1].type==="linePrefix"||On[1].type==="blockQuotePrefix"||On[1].type==="blockQuotePrefixWhitespace"||On[1].type==="blockQuoteMarker"||On[1].type==="listItemIndent"))break}Gt&&(!Wt||Gt<Wt)&&(Cn._spread=!0),Cn.end=Object.assign({},Wt?le[Wt][1].start:Bt[1].end),le.splice(Wt||ze,0,["exit",Cn,Bt[2]]),ze++,Pe++}if(Bt[1].type==="listItemPrefix"){const nn={type:"listItem",_spread:!1,start:Object.assign({},Bt[1].start),end:void 0};Cn=nn,le.splice(ze,0,["enter",nn,Bt[2]]),ze++,Pe++,Gt=void 0,Qt=!0}}}return le[Ee][1]._spread=Ft,Pe}function o(le,Ee){return Pe;function Pe(ze){f.call(this,le(ze),ze),Ee&&Ee.call(this,ze)}}function l(){this.stack.push({type:"fragment",children:[]})}function f(le,Ee,Pe){this.stack[this.stack.length-1].children.push(le),this.stack.push(le),this.tokenStack.push([Ee,Pe||void 0]),le.position={start:ha(Ee.start),end:void 0}}function d(le){return Ee;function Ee(Pe){le&&le.call(this,Pe),h.call(this,Pe)}}function h(le,Ee){const Pe=this.stack.pop(),ze=this.tokenStack.pop();if(ze)ze[0].type!==le.type&&(Ee?Ee.call(this,le,ze[0]):(ze[1]||pS).call(this,le,ze[0]));else throw new Error("Cannot close `"+le.type+"` ("+ul({start:le.start,end:le.end})+"): it’s not open");Pe.position.end=ha(le.end)}function p(){return Og(this.stack.pop())}function g(){this.data.expectingFirstListItemValue=!0}function b(le){if(this.data.expectingFirstListItemValue){const Ee=this.stack[this.stack.length-2];Ee.start=Number.parseInt(this.sliceSerialize(le),10),this.data.expectingFirstListItemValue=void 0}}function T(){const le=this.resume(),Ee=this.stack[this.stack.length-1];Ee.lang=le}function A(){const le=this.resume(),Ee=this.stack[this.stack.length-1];Ee.meta=le}function _(){this.data.flowCodeInside||(this.buffer(),this.data.flowCodeInside=!0)}function O(){const le=this.resume(),Ee=this.stack[this.stack.length-1];Ee.value=le.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g,""),this.data.flowCodeInside=void 0}function C(){const le=this.resume(),Ee=this.stack[this.stack.length-1];Ee.value=le.replace(/(\r?\n|\r)$/g,"")}function N(le){const Ee=this.resume(),Pe=this.stack[this.stack.length-1];Pe.label=Ee,Pe.identifier=$r(this.sliceSerialize(le)).toLowerCase()}function R(){const le=this.resume(),Ee=this.stack[this.stack.length-1];Ee.title=le}function Y(){const le=this.resume(),Ee=this.stack[this.stack.length-1];Ee.url=le}function M(le){const Ee=this.stack[this.stack.length-1];if(!Ee.depth){const Pe=this.sliceSerialize(le).length;Ee.depth=Pe}}function v(){this.data.setextHeadingSlurpLineEnding=!0}function J(le){const Ee=this.stack[this.stack.length-1];Ee.depth=this.sliceSerialize(le).codePointAt(0)===61?1:2}function P(){this.data.setextHeadingSlurpLineEnding=void 0}function q(le){const Pe=this.stack[this.stack.length-1].children;let ze=Pe[Pe.length-1];(!ze||ze.type!=="text")&&(ze=Dr(),ze.position={start:ha(le.start),end:void 0},Pe.push(ze)),this.stack.push(ze)}function z(le){const Ee=this.stack.pop();Ee.value+=this.sliceSerialize(le),Ee.position.end=ha(le.end)}function V(le){const Ee=this.stack[this.stack.length-1];if(this.data.atHardBreak){const Pe=Ee.children[Ee.children.length-1];Pe.position.end=ha(le.end),this.data.atHardBreak=void 0;return}!this.data.setextHeadingSlurpLineEnding&&t.canContainEols.includes(Ee.type)&&(q.call(this,le),z.call(this,le))}function F(){this.data.atHardBreak=!0}function $(){const le=this.resume(),Ee=this.stack[this.stack.length-1];Ee.value=le}function Z(){const le=this.resume(),Ee=this.stack[this.stack.length-1];Ee.value=le}function L(){const le=this.resume(),Ee=this.stack[this.stack.length-1];Ee.value=le}function B(){const le=this.stack[this.stack.length-1];if(this.data.inReference){const Ee=this.data.referenceType||"shortcut";le.type+="Reference",le.referenceType=Ee,delete le.url,delete le.title}else delete le.identifier,delete le.label;this.data.referenceType=void 0}function K(){const le=this.stack[this.stack.length-1];if(this.data.inReference){const Ee=this.data.referenceType||"shortcut";le.type+="Reference",le.referenceType=Ee,delete le.url,delete le.title}else delete le.identifier,delete le.label;this.data.referenceType=void 0}function Q(le){const Ee=this.sliceSerialize(le),Pe=this.stack[this.stack.length-2];Pe.label=zP(Ee),Pe.identifier=$r(Ee).toLowerCase()}function _e(){const le=this.stack[this.stack.length-1],Ee=this.resume(),Pe=this.stack[this.stack.length-1];if(this.data.inReference=!0,Pe.type==="link"){const ze=le.children;Pe.children=ze}else Pe.alt=Ee}function S(){const le=this.resume(),Ee=this.stack[this.stack.length-1];Ee.url=le}function ne(){const le=this.resume(),Ee=this.stack[this.stack.length-1];Ee.title=le}function ge(){this.data.inReference=void 0}function w(){this.data.referenceType="collapsed"}function Te(le){const Ee=this.resume(),Pe=this.stack[this.stack.length-1];Pe.label=Ee,Pe.identifier=$r(this.sliceSerialize(le)).toLowerCase(),this.data.referenceType="full"}function Re(le){this.data.characterReferenceType=le.type}function xe(le){const Ee=this.sliceSerialize(le),Pe=this.data.characterReferenceType;let ze;Pe?(ze=AC(Ee,Pe==="characterReferenceMarkerNumeric"?10:16),this.data.characterReferenceType=void 0):ze=Ng(Ee);const ht=this.stack[this.stack.length-1];ht.value+=ze}function We(le){const Ee=this.stack.pop();Ee.position.end=ha(le.end)}function Qe(le){z.call(this,le);const Ee=this.stack[this.stack.length-1];Ee.url=this.sliceSerialize(le)}function Nt(le){z.call(this,le);const Ee=this.stack[this.stack.length-1];Ee.url="mailto:"+this.sliceSerialize(le)}function mt(){return{type:"blockquote",children:[]}}function qt(){return{type:"code",lang:null,meta:null,value:""}}function ln(){return{type:"inlineCode",value:""}}function Ar(){return{type:"definition",identifier:"",label:null,title:null,url:""}}function tn(){return{type:"emphasis",children:[]}}function ni(){return{type:"heading",depth:0,children:[]}}function ri(){return{type:"break"}}function Yt(){return{type:"html",value:""}}function ii(){return{type:"image",title:null,url:"",alt:null}}function Sr(){return{type:"link",title:null,url:"",children:[]}}function ai(le){return{type:"list",ordered:le.type==="listOrdered",start:null,spread:le._spread,children:[]}}function jr(le){return{type:"listItem",spread:le._spread,checked:null,children:[]}}function ur(){return{type:"paragraph",children:[]}}function Yn(){return{type:"strong",children:[]}}function Dr(){return{type:"text",value:""}}function Gn(){return{type:"thematicBreak"}}}function ha(e){return{line:e.line,column:e.column,offset:e.offset}}function kC(e,t){let n=-1;for(;++n<t.length;){const i=t[n];Array.isArray(i)?kC(e,i):YP(e,i)}}function YP(e,t){let n;for(n in t)if(NC.call(t,n))switch(n){case"canContainEols":{const i=t[n];i&&e[n].push(...i);break}case"transforms":{const i=t[n];i&&e[n].push(...i);break}case"enter":case"exit":{const i=t[n];i&&Object.assign(e[n],i);break}}}function pS(e,t){throw e?new Error("Cannot close `"+e.type+"` ("+ul({start:e.start,end:e.end})+"): a different token (`"+t.type+"`, "+ul({start:t.start,end:t.end})+") is open"):new Error("Cannot close document, a token (`"+t.type+"`, "+ul({start:t.start,end:t.end})+") is still open")}function GP(e){const t=this;t.parser=n;function n(i){return jP(i,{...t.data("settings"),...e,extensions:t.data("micromarkExtensions")||[],mdastExtensions:t.data("fromMarkdownExtensions")||[]})}}function XP(e,t){const n={type:"element",tagName:"blockquote",properties:{},children:e.wrap(e.all(t),!0)};return e.patch(t,n),e.applyData(t,n)}function KP(e,t){const n={type:"element",tagName:"br",properties:{},children:[]};return e.patch(t,n),[e.applyData(t,n),{type:"text",value:` +`}]}function WP(e,t){const n=t.value?t.value+` +`:"",i={};t.lang&&(i.className=["language-"+t.lang]);let u={type:"element",tagName:"code",properties:i,children:[{type:"text",value:n}]};return t.meta&&(u.data={meta:t.meta}),e.patch(t,u),u=e.applyData(t,u),u={type:"element",tagName:"pre",properties:{},children:[u]},e.patch(t,u),u}function QP(e,t){const n={type:"element",tagName:"del",properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function $P(e,t){const n={type:"element",tagName:"em",properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function ZP(e,t){const n=typeof e.options.clobberPrefix=="string"?e.options.clobberPrefix:"user-content-",i=String(t.identifier).toUpperCase(),u=Ss(i.toLowerCase()),o=e.footnoteOrder.indexOf(i);let l,f=e.footnoteCounts.get(i);f===void 0?(f=0,e.footnoteOrder.push(i),l=e.footnoteOrder.length):l=o+1,f+=1,e.footnoteCounts.set(i,f);const d={type:"element",tagName:"a",properties:{href:"#"+n+"fn-"+u,id:n+"fnref-"+u+(f>1?"-"+f:""),dataFootnoteRef:!0,ariaDescribedBy:["footnote-label"]},children:[{type:"text",value:String(l)}]};e.patch(t,d);const h={type:"element",tagName:"sup",properties:{},children:[d]};return e.patch(t,h),e.applyData(t,h)}function JP(e,t){const n={type:"element",tagName:"h"+t.depth,properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function e5(e,t){if(e.options.allowDangerousHtml){const n={type:"raw",value:t.value};return e.patch(t,n),e.applyData(t,n)}}function LC(e,t){const n=t.referenceType;let i="]";if(n==="collapsed"?i+="[]":n==="full"&&(i+="["+(t.label||t.identifier)+"]"),t.type==="imageReference")return[{type:"text",value:"!["+t.alt+i}];const u=e.all(t),o=u[0];o&&o.type==="text"?o.value="["+o.value:u.unshift({type:"text",value:"["});const l=u[u.length-1];return l&&l.type==="text"?l.value+=i:u.push({type:"text",value:i}),u}function t5(e,t){const n=String(t.identifier).toUpperCase(),i=e.definitionById.get(n);if(!i)return LC(e,t);const u={src:Ss(i.url||""),alt:t.alt};i.title!==null&&i.title!==void 0&&(u.title=i.title);const o={type:"element",tagName:"img",properties:u,children:[]};return e.patch(t,o),e.applyData(t,o)}function n5(e,t){const n={src:Ss(t.url)};t.alt!==null&&t.alt!==void 0&&(n.alt=t.alt),t.title!==null&&t.title!==void 0&&(n.title=t.title);const i={type:"element",tagName:"img",properties:n,children:[]};return e.patch(t,i),e.applyData(t,i)}function r5(e,t){const n={type:"text",value:t.value.replace(/\r?\n|\r/g," ")};e.patch(t,n);const i={type:"element",tagName:"code",properties:{},children:[n]};return e.patch(t,i),e.applyData(t,i)}function i5(e,t){const n=String(t.identifier).toUpperCase(),i=e.definitionById.get(n);if(!i)return LC(e,t);const u={href:Ss(i.url||"")};i.title!==null&&i.title!==void 0&&(u.title=i.title);const o={type:"element",tagName:"a",properties:u,children:e.all(t)};return e.patch(t,o),e.applyData(t,o)}function a5(e,t){const n={href:Ss(t.url)};t.title!==null&&t.title!==void 0&&(n.title=t.title);const i={type:"element",tagName:"a",properties:n,children:e.all(t)};return e.patch(t,i),e.applyData(t,i)}function u5(e,t,n){const i=e.all(t),u=n?s5(n):MC(t),o={},l=[];if(typeof t.checked=="boolean"){const p=i[0];let g;p&&p.type==="element"&&p.tagName==="p"?g=p:(g={type:"element",tagName:"p",properties:{},children:[]},i.unshift(g)),g.children.length>0&&g.children.unshift({type:"text",value:" "}),g.children.unshift({type:"element",tagName:"input",properties:{type:"checkbox",checked:t.checked,disabled:!0},children:[]}),o.className=["task-list-item"]}let f=-1;for(;++f<i.length;){const p=i[f];(u||f!==0||p.type!=="element"||p.tagName!=="p")&&l.push({type:"text",value:` +`}),p.type==="element"&&p.tagName==="p"&&!u?l.push(...p.children):l.push(p)}const d=i[i.length-1];d&&(u||d.type!=="element"||d.tagName!=="p")&&l.push({type:"text",value:` +`});const h={type:"element",tagName:"li",properties:o,children:l};return e.patch(t,h),e.applyData(t,h)}function s5(e){let t=!1;if(e.type==="list"){t=e.spread||!1;const n=e.children;let i=-1;for(;!t&&++i<n.length;)t=MC(n[i])}return t}function MC(e){const t=e.spread;return t??e.children.length>1}function o5(e,t){const n={},i=e.all(t);let u=-1;for(typeof t.start=="number"&&t.start!==1&&(n.start=t.start);++u<i.length;){const l=i[u];if(l.type==="element"&&l.tagName==="li"&&l.properties&&Array.isArray(l.properties.className)&&l.properties.className.includes("task-list-item")){n.className=["contains-task-list"];break}}const o={type:"element",tagName:t.ordered?"ol":"ul",properties:n,children:e.wrap(i,!0)};return e.patch(t,o),e.applyData(t,o)}function l5(e,t){const n={type:"element",tagName:"p",properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function c5(e,t){const n={type:"root",children:e.wrap(e.all(t))};return e.patch(t,n),e.applyData(t,n)}function f5(e,t){const n={type:"element",tagName:"strong",properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function d5(e,t){const n=e.all(t),i=n.shift(),u=[];if(i){const l={type:"element",tagName:"thead",properties:{},children:e.wrap([i],!0)};e.patch(t.children[0],l),u.push(l)}if(n.length>0){const l={type:"element",tagName:"tbody",properties:{},children:e.wrap(n,!0)},f=yi(t.children[1]),d=ud(t.children[t.children.length-1]);f&&d&&(l.position={start:f,end:d}),u.push(l)}const o={type:"element",tagName:"table",properties:{},children:e.wrap(u,!0)};return e.patch(t,o),e.applyData(t,o)}function h5(e,t,n){const i=n?n.children:void 0,o=(i?i.indexOf(t):1)===0?"th":"td",l=n&&n.type==="table"?n.align:void 0,f=l?l.length:t.children.length;let d=-1;const h=[];for(;++d<f;){const g=t.children[d],b={},T=l?l[d]:void 0;T&&(b.align=T);let A={type:"element",tagName:o,properties:b,children:[]};g&&(A.children=e.all(g),e.patch(g,A),A=e.applyData(g,A)),h.push(A)}const p={type:"element",tagName:"tr",properties:{},children:e.wrap(h,!0)};return e.patch(t,p),e.applyData(t,p)}function m5(e,t){const n={type:"element",tagName:"td",properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}const gS=9,ES=32;function p5(e){const t=String(e),n=/\r?\n|\r/g;let i=n.exec(t),u=0;const o=[];for(;i;)o.push(yS(t.slice(u,i.index),u>0,!0),i[0]),u=i.index+i[0].length,i=n.exec(t);return o.push(yS(t.slice(u),u>0,!1)),o.join("")}function yS(e,t,n){let i=0,u=e.length;if(t){let o=e.codePointAt(i);for(;o===gS||o===ES;)i++,o=e.codePointAt(i)}if(n){let o=e.codePointAt(u-1);for(;o===gS||o===ES;)u--,o=e.codePointAt(u-1)}return u>i?e.slice(i,u):""}function g5(e,t){const n={type:"text",value:p5(String(t.value))};return e.patch(t,n),e.applyData(t,n)}function E5(e,t){const n={type:"element",tagName:"hr",properties:{},children:[]};return e.patch(t,n),e.applyData(t,n)}const y5={blockquote:XP,break:KP,code:WP,delete:QP,emphasis:$P,footnoteReference:ZP,heading:JP,html:e5,imageReference:t5,image:n5,inlineCode:r5,linkReference:i5,link:a5,listItem:u5,list:o5,paragraph:l5,root:c5,strong:f5,table:d5,tableCell:m5,tableRow:h5,text:g5,thematicBreak:E5,toml:lf,yaml:lf,definition:lf,footnoteDefinition:lf};function lf(){}const IC=-1,ld=0,ol=1,qf=2,Lg=3,Mg=4,Ig=5,Pg=6,PC=7,FC=8,bS=typeof self=="object"?self:globalThis,b5=(e,t)=>{const n=(u,o)=>(e.set(o,u),u),i=u=>{if(e.has(u))return e.get(u);const[o,l]=t[u];switch(o){case ld:case IC:return n(l,u);case ol:{const f=n([],u);for(const d of l)f.push(i(d));return f}case qf:{const f=n({},u);for(const[d,h]of l)f[i(d)]=i(h);return f}case Lg:return n(new Date(l),u);case Mg:{const{source:f,flags:d}=l;return n(new RegExp(f,d),u)}case Ig:{const f=n(new Map,u);for(const[d,h]of l)f.set(i(d),i(h));return f}case Pg:{const f=n(new Set,u);for(const d of l)f.add(i(d));return f}case PC:{const{name:f,message:d}=l;return n(new bS[f](d),u)}case FC:return n(BigInt(l),u);case"BigInt":return n(Object(BigInt(l)),u);case"ArrayBuffer":return n(new Uint8Array(l).buffer,l);case"DataView":{const{buffer:f}=new Uint8Array(l);return n(new DataView(f),l)}}return n(new bS[o](l),u)};return i},TS=e=>b5(new Map,e)(0),Zu="",{toString:T5}={},{keys:A5}=Object,Vo=e=>{const t=typeof e;if(t!=="object"||!e)return[ld,t];const n=T5.call(e).slice(8,-1);switch(n){case"Array":return[ol,Zu];case"Object":return[qf,Zu];case"Date":return[Lg,Zu];case"RegExp":return[Mg,Zu];case"Map":return[Ig,Zu];case"Set":return[Pg,Zu];case"DataView":return[ol,n]}return n.includes("Array")?[ol,n]:n.includes("Error")?[PC,n]:[qf,n]},cf=([e,t])=>e===ld&&(t==="function"||t==="symbol"),S5=(e,t,n,i)=>{const u=(l,f)=>{const d=i.push(l)-1;return n.set(f,d),d},o=l=>{if(n.has(l))return n.get(l);let[f,d]=Vo(l);switch(f){case ld:{let p=l;switch(d){case"bigint":f=FC,p=l.toString();break;case"function":case"symbol":if(e)throw new TypeError("unable to serialize "+d);p=null;break;case"undefined":return u([IC],l)}return u([f,p],l)}case ol:{if(d){let b=l;return d==="DataView"?b=new Uint8Array(l.buffer):d==="ArrayBuffer"&&(b=new Uint8Array(l)),u([d,[...b]],l)}const p=[],g=u([f,p],l);for(const b of l)p.push(o(b));return g}case qf:{if(d)switch(d){case"BigInt":return u([d,l.toString()],l);case"Boolean":case"Number":case"String":return u([d,l.valueOf()],l)}if(t&&"toJSON"in l)return o(l.toJSON());const p=[],g=u([f,p],l);for(const b of A5(l))(e||!cf(Vo(l[b])))&&p.push([o(b),o(l[b])]);return g}case Lg:return u([f,l.toISOString()],l);case Mg:{const{source:p,flags:g}=l;return u([f,{source:p,flags:g}],l)}case Ig:{const p=[],g=u([f,p],l);for(const[b,T]of l)(e||!(cf(Vo(b))||cf(Vo(T))))&&p.push([o(b),o(T)]);return g}case Pg:{const p=[],g=u([f,p],l);for(const b of l)(e||!cf(Vo(b)))&&p.push(o(b));return g}}const{message:h}=l;return u([f,{name:d,message:h}],l)};return o},AS=(e,{json:t,lossy:n}={})=>{const i=[];return S5(!(t||n),!!t,new Map,i)(e),i},va=typeof structuredClone=="function"?(e,t)=>t&&("json"in t||"lossy"in t)?TS(AS(e,t)):structuredClone(e):(e,t)=>TS(AS(e,t));function D5(e,t){const n=[{type:"text",value:"↩"}];return t>1&&n.push({type:"element",tagName:"sup",properties:{},children:[{type:"text",value:String(t)}]}),n}function v5(e,t){return"Back to reference "+(e+1)+(t>1?"-"+t:"")}function C5(e){const t=typeof e.options.clobberPrefix=="string"?e.options.clobberPrefix:"user-content-",n=e.options.footnoteBackContent||D5,i=e.options.footnoteBackLabel||v5,u=e.options.footnoteLabel||"Footnotes",o=e.options.footnoteLabelTagName||"h2",l=e.options.footnoteLabelProperties||{className:["sr-only"]},f=[];let d=-1;for(;++d<e.footnoteOrder.length;){const h=e.footnoteById.get(e.footnoteOrder[d]);if(!h)continue;const p=e.all(h),g=String(h.identifier).toUpperCase(),b=Ss(g.toLowerCase());let T=0;const A=[],_=e.footnoteCounts.get(g);for(;_!==void 0&&++T<=_;){A.length>0&&A.push({type:"text",value:" "});let N=typeof n=="string"?n:n(d,T);typeof N=="string"&&(N={type:"text",value:N}),A.push({type:"element",tagName:"a",properties:{href:"#"+t+"fnref-"+b+(T>1?"-"+T:""),dataFootnoteBackref:"",ariaLabel:typeof i=="string"?i:i(d,T),className:["data-footnote-backref"]},children:Array.isArray(N)?N:[N]})}const O=p[p.length-1];if(O&&O.type==="element"&&O.tagName==="p"){const N=O.children[O.children.length-1];N&&N.type==="text"?N.value+=" ":O.children.push({type:"text",value:" "}),O.children.push(...A)}else p.push(...A);const C={type:"element",tagName:"li",properties:{id:t+"fn-"+b},children:e.wrap(p,!0)};e.patch(h,C),f.push(C)}if(f.length!==0)return{type:"element",tagName:"section",properties:{dataFootnotes:!0,className:["footnotes"]},children:[{type:"element",tagName:o,properties:{...va(l),id:"footnote-label"},children:[{type:"text",value:u}]},{type:"text",value:` +`},{type:"element",tagName:"ol",properties:{},children:e.wrap(f,!0)},{type:"text",value:` +`}]}}const cd=function(e){if(e==null)return w5;if(typeof e=="function")return fd(e);if(typeof e=="object")return Array.isArray(e)?_5(e):x5(e);if(typeof e=="string")return R5(e);throw new Error("Expected function, string, or object as test")};function _5(e){const t=[];let n=-1;for(;++n<e.length;)t[n]=cd(e[n]);return fd(i);function i(...u){let o=-1;for(;++o<t.length;)if(t[o].apply(this,u))return!0;return!1}}function x5(e){const t=e;return fd(n);function n(i){const u=i;let o;for(o in e)if(u[o]!==t[o])return!1;return!0}}function R5(e){return fd(t);function t(n){return n&&n.type===e}}function fd(e){return t;function t(n,i,u){return!!(O5(n)&&e.call(this,n,typeof i=="number"?i:void 0,u||void 0))}}function w5(){return!0}function O5(e){return e!==null&&typeof e=="object"&&"type"in e}const BC=[],N5=!0,d0=!1,xf="skip";function UC(e,t,n,i){let u;typeof t=="function"&&typeof n!="function"?(i=n,n=t):u=t;const o=cd(u),l=i?-1:1;f(e,void 0,[])();function f(d,h,p){const g=d&&typeof d=="object"?d:{};if(typeof g.type=="string"){const T=typeof g.tagName=="string"?g.tagName:typeof g.name=="string"?g.name:void 0;Object.defineProperty(b,"name",{value:"node ("+(d.type+(T?"<"+T+">":""))+")"})}return b;function b(){let T=BC,A,_,O;if((!t||o(d,h,p[p.length-1]||void 0))&&(T=k5(n(d,p)),T[0]===d0))return T;if("children"in d&&d.children){const C=d;if(C.children&&T[0]!==xf)for(_=(i?C.children.length:-1)+l,O=p.concat(C);_>-1&&_<C.children.length;){const N=C.children[_];if(A=f(N,_,O)(),A[0]===d0)return A;_=typeof A[1]=="number"?A[1]:_+l}}return T}}}function k5(e){return Array.isArray(e)?e:typeof e=="number"?[N5,e]:e==null?BC:[e]}function Ds(e,t,n,i){let u,o,l;typeof t=="function"&&typeof n!="function"?(o=void 0,l=t,u=n):(o=t,l=n,u=i),UC(e,o,f,u);function f(d,h){const p=h[h.length-1],g=p?p.children.indexOf(d):void 0;return l(d,g,p)}}const h0={}.hasOwnProperty,L5={};function M5(e,t){const n=t||L5,i=new Map,u=new Map,o=new Map,l={...y5,...n.handlers},f={all:h,applyData:P5,definitionById:i,footnoteById:u,footnoteCounts:o,footnoteOrder:[],handlers:l,one:d,options:n,patch:I5,wrap:B5};return Ds(e,function(p){if(p.type==="definition"||p.type==="footnoteDefinition"){const g=p.type==="definition"?i:u,b=String(p.identifier).toUpperCase();g.has(b)||g.set(b,p)}}),f;function d(p,g){const b=p.type,T=f.handlers[b];if(h0.call(f.handlers,b)&&T)return T(f,p,g);if(f.options.passThrough&&f.options.passThrough.includes(b)){if("children"in p){const{children:_,...O}=p,C=va(O);return C.children=f.all(p),C}return va(p)}return(f.options.unknownHandler||F5)(f,p,g)}function h(p){const g=[];if("children"in p){const b=p.children;let T=-1;for(;++T<b.length;){const A=f.one(b[T],p);if(A){if(T&&b[T-1].type==="break"&&(!Array.isArray(A)&&A.type==="text"&&(A.value=SS(A.value)),!Array.isArray(A)&&A.type==="element")){const _=A.children[0];_&&_.type==="text"&&(_.value=SS(_.value))}Array.isArray(A)?g.push(...A):g.push(A)}}}return g}}function I5(e,t){e.position&&(t.position=mC(e))}function P5(e,t){let n=t;if(e&&e.data){const i=e.data.hName,u=e.data.hChildren,o=e.data.hProperties;if(typeof i=="string")if(n.type==="element")n.tagName=i;else{const l="children"in n?n.children:[n];n={type:"element",tagName:i,properties:{},children:l}}n.type==="element"&&o&&Object.assign(n.properties,va(o)),"children"in n&&n.children&&u!==null&&u!==void 0&&(n.children=u)}return n}function F5(e,t){const n=t.data||{},i="value"in t&&!(h0.call(n,"hProperties")||h0.call(n,"hChildren"))?{type:"text",value:t.value}:{type:"element",tagName:"div",properties:{},children:e.all(t)};return e.patch(t,i),e.applyData(t,i)}function B5(e,t){const n=[];let i=-1;for(t&&n.push({type:"text",value:` +`});++i<e.length;)i&&n.push({type:"text",value:` +`}),n.push(e[i]);return t&&e.length>0&&n.push({type:"text",value:` +`}),n}function SS(e){let t=0,n=e.charCodeAt(t);for(;n===9||n===32;)t++,n=e.charCodeAt(t);return e.slice(t)}function DS(e,t){const n=M5(e,t),i=n.one(e,void 0),u=C5(n),o=Array.isArray(i)?{type:"root",children:i}:i||{type:"root",children:[]};return u&&o.children.push({type:"text",value:` +`},u),o}function U5(e,t){return e&&"run"in e?async function(n,i){const u=DS(n,{file:i,...t});await e.run(u,i)}:function(n,i){return DS(n,{file:i,...e||t})}}function vS(e){if(e)throw e}var lp,CS;function H5(){if(CS)return lp;CS=1;var e=Object.prototype.hasOwnProperty,t=Object.prototype.toString,n=Object.defineProperty,i=Object.getOwnPropertyDescriptor,u=function(h){return typeof Array.isArray=="function"?Array.isArray(h):t.call(h)==="[object Array]"},o=function(h){if(!h||t.call(h)!=="[object Object]")return!1;var p=e.call(h,"constructor"),g=h.constructor&&h.constructor.prototype&&e.call(h.constructor.prototype,"isPrototypeOf");if(h.constructor&&!p&&!g)return!1;var b;for(b in h);return typeof b>"u"||e.call(h,b)},l=function(h,p){n&&p.name==="__proto__"?n(h,p.name,{enumerable:!0,configurable:!0,value:p.newValue,writable:!0}):h[p.name]=p.newValue},f=function(h,p){if(p==="__proto__")if(e.call(h,p)){if(i)return i(h,p).value}else return;return h[p]};return lp=function d(){var h,p,g,b,T,A,_=arguments[0],O=1,C=arguments.length,N=!1;for(typeof _=="boolean"&&(N=_,_=arguments[1]||{},O=2),(_==null||typeof _!="object"&&typeof _!="function")&&(_={});O<C;++O)if(h=arguments[O],h!=null)for(p in h)g=f(_,p),b=f(h,p),_!==b&&(N&&b&&(o(b)||(T=u(b)))?(T?(T=!1,A=g&&u(g)?g:[]):A=g&&o(g)?g:{},l(_,{name:p,newValue:d(N,A,b)})):typeof b<"u"&&l(_,{name:p,newValue:b}));return _},lp}var z5=H5();const cp=Rl(z5);function m0(e){if(typeof e!="object"||e===null)return!1;const t=Object.getPrototypeOf(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)}function V5(){const e=[],t={run:n,use:i};return t;function n(...u){let o=-1;const l=u.pop();if(typeof l!="function")throw new TypeError("Expected function as last argument, not "+l);f(null,...u);function f(d,...h){const p=e[++o];let g=-1;if(d){l(d);return}for(;++g<u.length;)(h[g]===null||h[g]===void 0)&&(h[g]=u[g]);u=h,p?j5(p,f)(...h):l(null,...h)}}function i(u){if(typeof u!="function")throw new TypeError("Expected `middelware` to be a function, not "+u);return e.push(u),t}}function j5(e,t){let n;return i;function i(...l){const f=e.length>l.length;let d;f&&l.push(u);try{d=e.apply(this,l)}catch(h){const p=h;if(f&&n)throw p;return u(p)}f||(d&&d.then&&typeof d.then=="function"?d.then(o,u):d instanceof Error?u(d):o(d))}function u(l,...f){n||(n=!0,t(l,...f))}function o(l){u(null,l)}}const di={basename:q5,dirname:Y5,extname:G5,join:X5,sep:"/"};function q5(e,t){if(t!==void 0&&typeof t!="string")throw new TypeError('"ext" argument must be a string');Fl(e);let n=0,i=-1,u=e.length,o;if(t===void 0||t.length===0||t.length>e.length){for(;u--;)if(e.codePointAt(u)===47){if(o){n=u+1;break}}else i<0&&(o=!0,i=u+1);return i<0?"":e.slice(n,i)}if(t===e)return"";let l=-1,f=t.length-1;for(;u--;)if(e.codePointAt(u)===47){if(o){n=u+1;break}}else l<0&&(o=!0,l=u+1),f>-1&&(e.codePointAt(u)===t.codePointAt(f--)?f<0&&(i=u):(f=-1,i=l));return n===i?i=l:i<0&&(i=e.length),e.slice(n,i)}function Y5(e){if(Fl(e),e.length===0)return".";let t=-1,n=e.length,i;for(;--n;)if(e.codePointAt(n)===47){if(i){t=n;break}}else i||(i=!0);return t<0?e.codePointAt(0)===47?"/":".":t===1&&e.codePointAt(0)===47?"//":e.slice(0,t)}function G5(e){Fl(e);let t=e.length,n=-1,i=0,u=-1,o=0,l;for(;t--;){const f=e.codePointAt(t);if(f===47){if(l){i=t+1;break}continue}n<0&&(l=!0,n=t+1),f===46?u<0?u=t:o!==1&&(o=1):u>-1&&(o=-1)}return u<0||n<0||o===0||o===1&&u===n-1&&u===i+1?"":e.slice(u,n)}function X5(...e){let t=-1,n;for(;++t<e.length;)Fl(e[t]),e[t]&&(n=n===void 0?e[t]:n+"/"+e[t]);return n===void 0?".":K5(n)}function K5(e){Fl(e);const t=e.codePointAt(0)===47;let n=W5(e,!t);return n.length===0&&!t&&(n="."),n.length>0&&e.codePointAt(e.length-1)===47&&(n+="/"),t?"/"+n:n}function W5(e,t){let n="",i=0,u=-1,o=0,l=-1,f,d;for(;++l<=e.length;){if(l<e.length)f=e.codePointAt(l);else{if(f===47)break;f=47}if(f===47){if(!(u===l-1||o===1))if(u!==l-1&&o===2){if(n.length<2||i!==2||n.codePointAt(n.length-1)!==46||n.codePointAt(n.length-2)!==46){if(n.length>2){if(d=n.lastIndexOf("/"),d!==n.length-1){d<0?(n="",i=0):(n=n.slice(0,d),i=n.length-1-n.lastIndexOf("/")),u=l,o=0;continue}}else if(n.length>0){n="",i=0,u=l,o=0;continue}}t&&(n=n.length>0?n+"/..":"..",i=2)}else n.length>0?n+="/"+e.slice(u+1,l):n=e.slice(u+1,l),i=l-u-1;u=l,o=0}else f===46&&o>-1?o++:o=-1}return n}function Fl(e){if(typeof e!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}const Q5={cwd:$5};function $5(){return"/"}function p0(e){return!!(e!==null&&typeof e=="object"&&"href"in e&&e.href&&"protocol"in e&&e.protocol&&e.auth===void 0)}function Z5(e){if(typeof e=="string")e=new URL(e);else if(!p0(e)){const t=new TypeError('The "path" argument must be of type string or an instance of URL. Received `'+e+"`");throw t.code="ERR_INVALID_ARG_TYPE",t}if(e.protocol!=="file:"){const t=new TypeError("The URL must be of scheme file");throw t.code="ERR_INVALID_URL_SCHEME",t}return J5(e)}function J5(e){if(e.hostname!==""){const i=new TypeError('File URL host must be "localhost" or empty on darwin');throw i.code="ERR_INVALID_FILE_URL_HOST",i}const t=e.pathname;let n=-1;for(;++n<t.length;)if(t.codePointAt(n)===37&&t.codePointAt(n+1)===50){const i=t.codePointAt(n+2);if(i===70||i===102){const u=new TypeError("File URL path must not include encoded / characters");throw u.code="ERR_INVALID_FILE_URL_PATH",u}}return decodeURIComponent(t)}const fp=["history","path","basename","stem","extname","dirname"];class HC{constructor(t){let n;t?p0(t)?n={path:t}:typeof t=="string"||eF(t)?n={value:t}:n=t:n={},this.cwd="cwd"in n?"":Q5.cwd(),this.data={},this.history=[],this.messages=[],this.value,this.map,this.result,this.stored;let i=-1;for(;++i<fp.length;){const o=fp[i];o in n&&n[o]!==void 0&&n[o]!==null&&(this[o]=o==="history"?[...n[o]]:n[o])}let u;for(u in n)fp.includes(u)||(this[u]=n[u])}get basename(){return typeof this.path=="string"?di.basename(this.path):void 0}set basename(t){hp(t,"basename"),dp(t,"basename"),this.path=di.join(this.dirname||"",t)}get dirname(){return typeof this.path=="string"?di.dirname(this.path):void 0}set dirname(t){_S(this.basename,"dirname"),this.path=di.join(t||"",this.basename)}get extname(){return typeof this.path=="string"?di.extname(this.path):void 0}set extname(t){if(dp(t,"extname"),_S(this.dirname,"extname"),t){if(t.codePointAt(0)!==46)throw new Error("`extname` must start with `.`");if(t.includes(".",1))throw new Error("`extname` cannot contain multiple dots")}this.path=di.join(this.dirname,this.stem+(t||""))}get path(){return this.history[this.history.length-1]}set path(t){p0(t)&&(t=Z5(t)),hp(t,"path"),this.path!==t&&this.history.push(t)}get stem(){return typeof this.path=="string"?di.basename(this.path,this.extname):void 0}set stem(t){hp(t,"stem"),dp(t,"stem"),this.path=di.join(this.dirname||"",t+(this.extname||""))}fail(t,n,i){const u=this.message(t,n,i);throw u.fatal=!0,u}info(t,n,i){const u=this.message(t,n,i);return u.fatal=void 0,u}message(t,n,i){const u=new Pn(t,n,i);return this.path&&(u.name=this.path+":"+u.name,u.file=this.path),u.fatal=!1,this.messages.push(u),u}toString(t){return this.value===void 0?"":typeof this.value=="string"?this.value:new TextDecoder(t||void 0).decode(this.value)}}function dp(e,t){if(e&&e.includes(di.sep))throw new Error("`"+t+"` cannot be a path: did not expect `"+di.sep+"`")}function hp(e,t){if(!e)throw new Error("`"+t+"` cannot be empty")}function _S(e,t){if(!e)throw new Error("Setting `"+t+"` requires `path` to be set too")}function eF(e){return!!(e&&typeof e=="object"&&"byteLength"in e&&"byteOffset"in e)}const tF=function(e){const i=this.constructor.prototype,u=i[e],o=function(){return u.apply(o,arguments)};return Object.setPrototypeOf(o,i),o},nF={}.hasOwnProperty;class Fg extends tF{constructor(){super("copy"),this.Compiler=void 0,this.Parser=void 0,this.attachers=[],this.compiler=void 0,this.freezeIndex=-1,this.frozen=void 0,this.namespace={},this.parser=void 0,this.transformers=V5()}copy(){const t=new Fg;let n=-1;for(;++n<this.attachers.length;){const i=this.attachers[n];t.use(...i)}return t.data(cp(!0,{},this.namespace)),t}data(t,n){return typeof t=="string"?arguments.length===2?(gp("data",this.frozen),this.namespace[t]=n,this):nF.call(this.namespace,t)&&this.namespace[t]||void 0:t?(gp("data",this.frozen),this.namespace=t,this):this.namespace}freeze(){if(this.frozen)return this;const t=this;for(;++this.freezeIndex<this.attachers.length;){const[n,...i]=this.attachers[this.freezeIndex];if(i[0]===!1)continue;i[0]===!0&&(i[0]=void 0);const u=n.call(t,...i);typeof u=="function"&&this.transformers.use(u)}return this.frozen=!0,this.freezeIndex=Number.POSITIVE_INFINITY,this}parse(t){this.freeze();const n=ff(t),i=this.parser||this.Parser;return mp("parse",i),i(String(n),n)}process(t,n){const i=this;return this.freeze(),mp("process",this.parser||this.Parser),pp("process",this.compiler||this.Compiler),n?u(void 0,n):new Promise(u);function u(o,l){const f=ff(t),d=i.parse(f);i.run(d,f,function(p,g,b){if(p||!g||!b)return h(p);const T=g,A=i.stringify(T,b);aF(A)?b.value=A:b.result=A,h(p,b)});function h(p,g){p||!g?l(p):o?o(g):n(void 0,g)}}}processSync(t){let n=!1,i;return this.freeze(),mp("processSync",this.parser||this.Parser),pp("processSync",this.compiler||this.Compiler),this.process(t,u),RS("processSync","process",n),i;function u(o,l){n=!0,vS(o),i=l}}run(t,n,i){xS(t),this.freeze();const u=this.transformers;return!i&&typeof n=="function"&&(i=n,n=void 0),i?o(void 0,i):new Promise(o);function o(l,f){const d=ff(n);u.run(t,d,h);function h(p,g,b){const T=g||t;p?f(p):l?l(T):i(void 0,T,b)}}}runSync(t,n){let i=!1,u;return this.run(t,n,o),RS("runSync","run",i),u;function o(l,f){vS(l),u=f,i=!0}}stringify(t,n){this.freeze();const i=ff(n),u=this.compiler||this.Compiler;return pp("stringify",u),xS(t),u(t,i)}use(t,...n){const i=this.attachers,u=this.namespace;if(gp("use",this.frozen),t!=null)if(typeof t=="function")d(t,n);else if(typeof t=="object")Array.isArray(t)?f(t):l(t);else throw new TypeError("Expected usable value, not `"+t+"`");return this;function o(h){if(typeof h=="function")d(h,[]);else if(typeof h=="object")if(Array.isArray(h)){const[p,...g]=h;d(p,g)}else l(h);else throw new TypeError("Expected usable value, not `"+h+"`")}function l(h){if(!("plugins"in h)&&!("settings"in h))throw new Error("Expected usable value but received an empty preset, which is probably a mistake: presets typically come with `plugins` and sometimes with `settings`, but this has neither");f(h.plugins),h.settings&&(u.settings=cp(!0,u.settings,h.settings))}function f(h){let p=-1;if(h!=null)if(Array.isArray(h))for(;++p<h.length;){const g=h[p];o(g)}else throw new TypeError("Expected a list of plugins, not `"+h+"`")}function d(h,p){let g=-1,b=-1;for(;++g<i.length;)if(i[g][0]===h){b=g;break}if(b===-1)i.push([h,...p]);else if(p.length>0){let[T,...A]=p;const _=i[b][1];m0(_)&&m0(T)&&(T=cp(!0,_,T)),i[b]=[h,T,...A]}}}}const rF=new Fg().freeze();function mp(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `parser`")}function pp(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `compiler`")}function gp(e,t){if(t)throw new Error("Cannot call `"+e+"` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.")}function xS(e){if(!m0(e)||typeof e.type!="string")throw new TypeError("Expected node, got `"+e+"`")}function RS(e,t,n){if(!n)throw new Error("`"+e+"` finished async. Use `"+t+"` instead")}function ff(e){return iF(e)?e:new HC(e)}function iF(e){return!!(e&&typeof e=="object"&&"message"in e&&"messages"in e)}function aF(e){return typeof e=="string"||uF(e)}function uF(e){return!!(e&&typeof e=="object"&&"byteLength"in e&&"byteOffset"in e)}const sF="https://github.com/remarkjs/react-markdown/blob/main/changelog.md",wS=[],OS={allowDangerousHtml:!0},oF=/^(https?|ircs?|mailto|xmpp)$/i,lF=[{from:"astPlugins",id:"remove-buggy-html-in-markdown-parser"},{from:"allowDangerousHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"allowNode",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowElement"},{from:"allowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowedElements"},{from:"className",id:"remove-classname"},{from:"disallowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"disallowedElements"},{from:"escapeHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"includeElementIndex",id:"#remove-includeelementindex"},{from:"includeNodeIndex",id:"change-includenodeindex-to-includeelementindex"},{from:"linkTarget",id:"remove-linktarget"},{from:"plugins",id:"change-plugins-to-remarkplugins",to:"remarkPlugins"},{from:"rawSourcePos",id:"#remove-rawsourcepos"},{from:"renderers",id:"change-renderers-to-components",to:"components"},{from:"source",id:"change-source-to-children",to:"children"},{from:"sourcePos",id:"#remove-sourcepos"},{from:"transformImageUri",id:"#add-urltransform",to:"urlTransform"},{from:"transformLinkUri",id:"#add-urltransform",to:"urlTransform"}];function Eq(e){const t=cF(e),n=fF(e);return dF(t.runSync(t.parse(n),n),e)}function cF(e){const t=e.rehypePlugins||wS,n=e.remarkPlugins||wS,i=e.remarkRehypeOptions?{...e.remarkRehypeOptions,...OS}:OS;return rF().use(GP).use(n).use(U5,i).use(t)}function fF(e){const t=e.children||"",n=new HC;return typeof t=="string"&&(n.value=t),n}function dF(e,t){const n=t.allowedElements,i=t.allowElement,u=t.components,o=t.disallowedElements,l=t.skipHtml,f=t.unwrapDisallowed,d=t.urlTransform||hF;for(const p of lF)Object.hasOwn(t,p.from)&&(""+p.from+(p.to?"use `"+p.to+"` instead":"remove it")+sF+p.id,void 0);return Ds(e,h),wI(e,{Fragment:Br.Fragment,components:u,ignoreInvalidStyle:!0,jsx:Br.jsx,jsxs:Br.jsxs,passKeys:!0,passNode:!0});function h(p,g,b){if(p.type==="raw"&&b&&typeof g=="number")return l?b.children.splice(g,1):b.children[g]={type:"text",value:p.value},g;if(p.type==="element"){let T;for(T in up)if(Object.hasOwn(up,T)&&Object.hasOwn(p.properties,T)){const A=p.properties[T],_=up[T];(_===null||_.includes(p.tagName))&&(p.properties[T]=d(String(A||""),T,p))}}if(p.type==="element"){let T=n?!n.includes(p.tagName):o?o.includes(p.tagName):!1;if(!T&&i&&typeof g=="number"&&(T=!i(p,g,b)),T&&b&&typeof g=="number")return f&&p.children?b.children.splice(g,1,...p.children):b.children.splice(g,1),g}}}function hF(e){const t=e.indexOf(":"),n=e.indexOf("?"),i=e.indexOf("#"),u=e.indexOf("/");return t===-1||u!==-1&&t>u||n!==-1&&t>n||i!==-1&&t>i||oF.test(e.slice(0,t))?e:""}function NS(e,t){const n=String(e);if(typeof t!="string")throw new TypeError("Expected character");let i=0,u=n.indexOf(t);for(;u!==-1;)i++,u=n.indexOf(t,u+t.length);return i}function mF(e){if(typeof e!="string")throw new TypeError("Expected a string");return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}function pF(e,t,n){const u=cd((n||{}).ignore||[]),o=gF(t);let l=-1;for(;++l<o.length;)UC(e,"text",f);function f(h,p){let g=-1,b;for(;++g<p.length;){const T=p[g],A=b?b.children:void 0;if(u(T,A?A.indexOf(T):void 0,b))return;b=T}if(b)return d(h,p)}function d(h,p){const g=p[p.length-1],b=o[l][0],T=o[l][1];let A=0;const O=g.children.indexOf(h);let C=!1,N=[];b.lastIndex=0;let R=b.exec(h.value);for(;R;){const Y=R.index,M={index:R.index,input:R.input,stack:[...p,h]};let v=T(...R,M);if(typeof v=="string"&&(v=v.length>0?{type:"text",value:v}:void 0),v===!1?b.lastIndex=Y+1:(A!==Y&&N.push({type:"text",value:h.value.slice(A,Y)}),Array.isArray(v)?N.push(...v):v&&N.push(v),A=Y+R[0].length,C=!0),!b.global)break;R=b.exec(h.value)}return C?(A<h.value.length&&N.push({type:"text",value:h.value.slice(A)}),g.children.splice(O,1,...N)):N=[h],O+N.length}}function gF(e){const t=[];if(!Array.isArray(e))throw new TypeError("Expected find and replace tuple or list of tuples");const n=!e[0]||Array.isArray(e[0])?e:[e];let i=-1;for(;++i<n.length;){const u=n[i];t.push([EF(u[0]),yF(u[1])])}return t}function EF(e){return typeof e=="string"?new RegExp(mF(e),"g"):e}function yF(e){return typeof e=="function"?e:function(){return e}}const Ep="phrasing",yp=["autolink","link","image","label"];function bF(){return{transforms:[_F],enter:{literalAutolink:AF,literalAutolinkEmail:bp,literalAutolinkHttp:bp,literalAutolinkWww:bp},exit:{literalAutolink:CF,literalAutolinkEmail:vF,literalAutolinkHttp:SF,literalAutolinkWww:DF}}}function TF(){return{unsafe:[{character:"@",before:"[+\\-.\\w]",after:"[\\-.\\w]",inConstruct:Ep,notInConstruct:yp},{character:".",before:"[Ww]",after:"[\\-.\\w]",inConstruct:Ep,notInConstruct:yp},{character:":",before:"[ps]",after:"\\/",inConstruct:Ep,notInConstruct:yp}]}}function AF(e){this.enter({type:"link",title:null,url:"",children:[]},e)}function bp(e){this.config.enter.autolinkProtocol.call(this,e)}function SF(e){this.config.exit.autolinkProtocol.call(this,e)}function DF(e){this.config.exit.data.call(this,e);const t=this.stack[this.stack.length-1];t.type,t.url="http://"+this.sliceSerialize(e)}function vF(e){this.config.exit.autolinkEmail.call(this,e)}function CF(e){this.exit(e)}function _F(e){pF(e,[[/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/gi,xF],[new RegExp("(?<=^|\\s|\\p{P}|\\p{S})([-.\\w+]+)@([-\\w]+(?:\\.[-\\w]+)+)","gu"),RF]],{ignore:["link","linkReference"]})}function xF(e,t,n,i,u){let o="";if(!zC(u)||(/^w/i.test(t)&&(n=t+n,t="",o="http://"),!wF(n)))return!1;const l=OF(n+i);if(!l[0])return!1;const f={type:"link",title:null,url:o+t+l[0],children:[{type:"text",value:t+l[0]}]};return l[1]?[f,{type:"text",value:l[1]}]:f}function RF(e,t,n,i){return!zC(i,!0)||/[-\d_]$/.test(n)?!1:{type:"link",title:null,url:"mailto:"+t+"@"+n,children:[{type:"text",value:t+"@"+n}]}}function wF(e){const t=e.split(".");return!(t.length<2||t[t.length-1]&&(/_/.test(t[t.length-1])||!/[a-zA-Z\d]/.test(t[t.length-1]))||t[t.length-2]&&(/_/.test(t[t.length-2])||!/[a-zA-Z\d]/.test(t[t.length-2])))}function OF(e){const t=/[!"&'),.:;<>?\]}]+$/.exec(e);if(!t)return[e,void 0];e=e.slice(0,t.index);let n=t[0],i=n.indexOf(")");const u=NS(e,"(");let o=NS(e,")");for(;i!==-1&&u>o;)e+=n.slice(0,i+1),n=n.slice(i+1),i=n.indexOf(")"),o++;return[e,n]}function zC(e,t){const n=e.input.charCodeAt(e.index-1);return(e.index===0||cu(n)||sd(n))&&(!t||n!==47)}VC.peek=UF;function NF(){this.buffer()}function kF(e){this.enter({type:"footnoteReference",identifier:"",label:""},e)}function LF(){this.buffer()}function MF(e){this.enter({type:"footnoteDefinition",identifier:"",label:"",children:[]},e)}function IF(e){const t=this.resume(),n=this.stack[this.stack.length-1];n.type,n.identifier=$r(this.sliceSerialize(e)).toLowerCase(),n.label=t}function PF(e){this.exit(e)}function FF(e){const t=this.resume(),n=this.stack[this.stack.length-1];n.type,n.identifier=$r(this.sliceSerialize(e)).toLowerCase(),n.label=t}function BF(e){this.exit(e)}function UF(){return"["}function VC(e,t,n,i){const u=n.createTracker(i);let o=u.move("[^");const l=n.enter("footnoteReference"),f=n.enter("reference");return o+=u.move(n.safe(n.associationId(e),{after:"]",before:o})),f(),l(),o+=u.move("]"),o}function HF(){return{enter:{gfmFootnoteCallString:NF,gfmFootnoteCall:kF,gfmFootnoteDefinitionLabelString:LF,gfmFootnoteDefinition:MF},exit:{gfmFootnoteCallString:IF,gfmFootnoteCall:PF,gfmFootnoteDefinitionLabelString:FF,gfmFootnoteDefinition:BF}}}function zF(e){let t=!1;return e&&e.firstLineBlank&&(t=!0),{handlers:{footnoteDefinition:n,footnoteReference:VC},unsafe:[{character:"[",inConstruct:["label","phrasing","reference"]}]};function n(i,u,o,l){const f=o.createTracker(l);let d=f.move("[^");const h=o.enter("footnoteDefinition"),p=o.enter("label");return d+=f.move(o.safe(o.associationId(i),{before:d,after:"]"})),p(),d+=f.move("]:"),i.children&&i.children.length>0&&(f.shift(4),d+=f.move((t?` +`:" ")+o.indentLines(o.containerFlow(i,f.current()),t?jC:VF))),h(),d}}function VF(e,t,n){return t===0?e:jC(e,t,n)}function jC(e,t,n){return(n?"":" ")+e}const jF=["autolink","destinationLiteral","destinationRaw","reference","titleQuote","titleApostrophe"];qC.peek=KF;function qF(){return{canContainEols:["delete"],enter:{strikethrough:GF},exit:{strikethrough:XF}}}function YF(){return{unsafe:[{character:"~",inConstruct:"phrasing",notInConstruct:jF}],handlers:{delete:qC}}}function GF(e){this.enter({type:"delete",children:[]},e)}function XF(e){this.exit(e)}function qC(e,t,n,i){const u=n.createTracker(i),o=n.enter("strikethrough");let l=u.move("~~");return l+=n.containerPhrasing(e,{...u.current(),before:l,after:"~"}),l+=u.move("~~"),o(),l}function KF(){return"~"}function WF(e){return e.length}function QF(e,t){const n=t||{},i=(n.align||[]).concat(),u=n.stringLength||WF,o=[],l=[],f=[],d=[];let h=0,p=-1;for(;++p<e.length;){const _=[],O=[];let C=-1;for(e[p].length>h&&(h=e[p].length);++C<e[p].length;){const N=$F(e[p][C]);if(n.alignDelimiters!==!1){const R=u(N);O[C]=R,(d[C]===void 0||R>d[C])&&(d[C]=R)}_.push(N)}l[p]=_,f[p]=O}let g=-1;if(typeof i=="object"&&"length"in i)for(;++g<h;)o[g]=kS(i[g]);else{const _=kS(i);for(;++g<h;)o[g]=_}g=-1;const b=[],T=[];for(;++g<h;){const _=o[g];let O="",C="";_===99?(O=":",C=":"):_===108?O=":":_===114&&(C=":");let N=n.alignDelimiters===!1?1:Math.max(1,d[g]-O.length-C.length);const R=O+"-".repeat(N)+C;n.alignDelimiters!==!1&&(N=O.length+N+C.length,N>d[g]&&(d[g]=N),T[g]=N),b[g]=R}l.splice(1,0,b),f.splice(1,0,T),p=-1;const A=[];for(;++p<l.length;){const _=l[p],O=f[p];g=-1;const C=[];for(;++g<h;){const N=_[g]||"";let R="",Y="";if(n.alignDelimiters!==!1){const M=d[g]-(O[g]||0),v=o[g];v===114?R=" ".repeat(M):v===99?M%2?(R=" ".repeat(M/2+.5),Y=" ".repeat(M/2-.5)):(R=" ".repeat(M/2),Y=R):Y=" ".repeat(M)}n.delimiterStart!==!1&&!g&&C.push("|"),n.padding!==!1&&!(n.alignDelimiters===!1&&N==="")&&(n.delimiterStart!==!1||g)&&C.push(" "),n.alignDelimiters!==!1&&C.push(R),C.push(N),n.alignDelimiters!==!1&&C.push(Y),n.padding!==!1&&C.push(" "),(n.delimiterEnd!==!1||g!==h-1)&&C.push("|")}A.push(n.delimiterEnd===!1?C.join("").replace(/ +$/,""):C.join(""))}return A.join(` +`)}function $F(e){return e==null?"":String(e)}function kS(e){const t=typeof e=="string"?e.codePointAt(0):0;return t===67||t===99?99:t===76||t===108?108:t===82||t===114?114:0}const LS={}.hasOwnProperty;function YC(e,t){const n=t||{};function i(u,...o){let l=i.invalid;const f=i.handlers;if(u&&LS.call(u,e)){const d=String(u[e]);l=LS.call(f,d)?f[d]:i.unknown}if(l)return l.call(this,u,...o)}return i.handlers=n.handlers||{},i.invalid=n.invalid,i.unknown=n.unknown,i}function ZF(e,t,n,i){const u=n.enter("blockquote"),o=n.createTracker(i);o.move("> "),o.shift(2);const l=n.indentLines(n.containerFlow(e,o.current()),JF);return u(),l}function JF(e,t,n){return">"+(n?"":" ")+e}function eB(e,t){return MS(e,t.inConstruct,!0)&&!MS(e,t.notInConstruct,!1)}function MS(e,t,n){if(typeof t=="string"&&(t=[t]),!t||t.length===0)return n;let i=-1;for(;++i<t.length;)if(e.includes(t[i]))return!0;return!1}function IS(e,t,n,i){let u=-1;for(;++u<n.unsafe.length;)if(n.unsafe[u].character===` +`&&eB(n.stack,n.unsafe[u]))return/[ \t]/.test(i.before)?"":" ";return`\\ +`}function tB(e,t){const n=String(e);let i=n.indexOf(t),u=i,o=0,l=0;if(typeof t!="string")throw new TypeError("Expected substring");for(;i!==-1;)i===u?++o>l&&(l=o):o=1,u=i+t.length,i=n.indexOf(t,u);return l}function nB(e,t){return!!(t.options.fences===!1&&e.value&&!e.lang&&/[^ \r\n]/.test(e.value)&&!/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(e.value))}function rB(e){const t=e.options.fence||"`";if(t!=="`"&&t!=="~")throw new Error("Cannot serialize code with `"+t+"` for `options.fence`, expected `` ` `` or `~`");return t}function iB(e,t,n,i){const u=rB(n),o=e.value||"",l=u==="`"?"GraveAccent":"Tilde";if(nB(e,n)){const g=n.enter("codeIndented"),b=n.indentLines(o,aB);return g(),b}const f=n.createTracker(i),d=u.repeat(Math.max(tB(o,u)+1,3)),h=n.enter("codeFenced");let p=f.move(d);if(e.lang){const g=n.enter(`codeFencedLang${l}`);p+=f.move(n.safe(e.lang,{before:p,after:" ",encode:["`"],...f.current()})),g()}if(e.lang&&e.meta){const g=n.enter(`codeFencedMeta${l}`);p+=f.move(" "),p+=f.move(n.safe(e.meta,{before:p,after:` +`,encode:["`"],...f.current()})),g()}return p+=f.move(` +`),o&&(p+=f.move(o+` +`)),p+=f.move(d),h(),p}function aB(e,t,n){return(n?"":" ")+e}function Bg(e){const t=e.options.quote||'"';if(t!=='"'&&t!=="'")throw new Error("Cannot serialize title with `"+t+"` for `options.quote`, expected `\"`, or `'`");return t}function uB(e,t,n,i){const u=Bg(n),o=u==='"'?"Quote":"Apostrophe",l=n.enter("definition");let f=n.enter("label");const d=n.createTracker(i);let h=d.move("[");return h+=d.move(n.safe(n.associationId(e),{before:h,after:"]",...d.current()})),h+=d.move("]: "),f(),!e.url||/[\0- \u007F]/.test(e.url)?(f=n.enter("destinationLiteral"),h+=d.move("<"),h+=d.move(n.safe(e.url,{before:h,after:">",...d.current()})),h+=d.move(">")):(f=n.enter("destinationRaw"),h+=d.move(n.safe(e.url,{before:h,after:e.title?" ":` +`,...d.current()}))),f(),e.title&&(f=n.enter(`title${o}`),h+=d.move(" "+u),h+=d.move(n.safe(e.title,{before:h,after:u,...d.current()})),h+=d.move(u),f()),l(),h}function sB(e){const t=e.options.emphasis||"*";if(t!=="*"&&t!=="_")throw new Error("Cannot serialize emphasis with `"+t+"` for `options.emphasis`, expected `*`, or `_`");return t}function Cl(e){return"&#x"+e.toString(16).toUpperCase()+";"}function Yf(e,t,n){const i=ds(e),u=ds(t);return i===void 0?u===void 0?n==="_"?{inside:!0,outside:!0}:{inside:!1,outside:!1}:u===1?{inside:!0,outside:!0}:{inside:!1,outside:!0}:i===1?u===void 0?{inside:!1,outside:!1}:u===1?{inside:!0,outside:!0}:{inside:!1,outside:!1}:u===void 0?{inside:!1,outside:!1}:u===1?{inside:!0,outside:!1}:{inside:!1,outside:!1}}GC.peek=oB;function GC(e,t,n,i){const u=sB(n),o=n.enter("emphasis"),l=n.createTracker(i),f=l.move(u);let d=l.move(n.containerPhrasing(e,{after:u,before:f,...l.current()}));const h=d.charCodeAt(0),p=Yf(i.before.charCodeAt(i.before.length-1),h,u);p.inside&&(d=Cl(h)+d.slice(1));const g=d.charCodeAt(d.length-1),b=Yf(i.after.charCodeAt(0),g,u);b.inside&&(d=d.slice(0,-1)+Cl(g));const T=l.move(u);return o(),n.attentionEncodeSurroundingInfo={after:b.outside,before:p.outside},f+d+T}function oB(e,t,n){return n.options.emphasis||"*"}function lB(e,t){let n=!1;return Ds(e,function(i){if("value"in i&&/\r?\n|\r/.test(i.value)||i.type==="break")return n=!0,d0}),!!((!e.depth||e.depth<3)&&Og(e)&&(t.options.setext||n))}function cB(e,t,n,i){const u=Math.max(Math.min(6,e.depth||1),1),o=n.createTracker(i);if(lB(e,n)){const p=n.enter("headingSetext"),g=n.enter("phrasing"),b=n.containerPhrasing(e,{...o.current(),before:` +`,after:` +`});return g(),p(),b+` +`+(u===1?"=":"-").repeat(b.length-(Math.max(b.lastIndexOf("\r"),b.lastIndexOf(` +`))+1))}const l="#".repeat(u),f=n.enter("headingAtx"),d=n.enter("phrasing");o.move(l+" ");let h=n.containerPhrasing(e,{before:"# ",after:` +`,...o.current()});return/^[\t ]/.test(h)&&(h=Cl(h.charCodeAt(0))+h.slice(1)),h=h?l+" "+h:l,n.options.closeAtx&&(h+=" "+l),d(),f(),h}XC.peek=fB;function XC(e){return e.value||""}function fB(){return"<"}KC.peek=dB;function KC(e,t,n,i){const u=Bg(n),o=u==='"'?"Quote":"Apostrophe",l=n.enter("image");let f=n.enter("label");const d=n.createTracker(i);let h=d.move("![");return h+=d.move(n.safe(e.alt,{before:h,after:"]",...d.current()})),h+=d.move("]("),f(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(f=n.enter("destinationLiteral"),h+=d.move("<"),h+=d.move(n.safe(e.url,{before:h,after:">",...d.current()})),h+=d.move(">")):(f=n.enter("destinationRaw"),h+=d.move(n.safe(e.url,{before:h,after:e.title?" ":")",...d.current()}))),f(),e.title&&(f=n.enter(`title${o}`),h+=d.move(" "+u),h+=d.move(n.safe(e.title,{before:h,after:u,...d.current()})),h+=d.move(u),f()),h+=d.move(")"),l(),h}function dB(){return"!"}WC.peek=hB;function WC(e,t,n,i){const u=e.referenceType,o=n.enter("imageReference");let l=n.enter("label");const f=n.createTracker(i);let d=f.move("![");const h=n.safe(e.alt,{before:d,after:"]",...f.current()});d+=f.move(h+"]["),l();const p=n.stack;n.stack=[],l=n.enter("reference");const g=n.safe(n.associationId(e),{before:d,after:"]",...f.current()});return l(),n.stack=p,o(),u==="full"||!h||h!==g?d+=f.move(g+"]"):u==="shortcut"?d=d.slice(0,-1):d+=f.move("]"),d}function hB(){return"!"}QC.peek=mB;function QC(e,t,n){let i=e.value||"",u="`",o=-1;for(;new RegExp("(^|[^`])"+u+"([^`]|$)").test(i);)u+="`";for(/[^ \r\n]/.test(i)&&(/^[ \r\n]/.test(i)&&/[ \r\n]$/.test(i)||/^`|`$/.test(i))&&(i=" "+i+" ");++o<n.unsafe.length;){const l=n.unsafe[o],f=n.compilePattern(l);let d;if(l.atBreak)for(;d=f.exec(i);){let h=d.index;i.charCodeAt(h)===10&&i.charCodeAt(h-1)===13&&h--,i=i.slice(0,h)+" "+i.slice(d.index+1)}}return u+i+u}function mB(){return"`"}function $C(e,t){const n=Og(e);return!!(!t.options.resourceLink&&e.url&&!e.title&&e.children&&e.children.length===1&&e.children[0].type==="text"&&(n===e.url||"mailto:"+n===e.url)&&/^[a-z][a-z+.-]+:/i.test(e.url)&&!/[\0- <>\u007F]/.test(e.url))}ZC.peek=pB;function ZC(e,t,n,i){const u=Bg(n),o=u==='"'?"Quote":"Apostrophe",l=n.createTracker(i);let f,d;if($C(e,n)){const p=n.stack;n.stack=[],f=n.enter("autolink");let g=l.move("<");return g+=l.move(n.containerPhrasing(e,{before:g,after:">",...l.current()})),g+=l.move(">"),f(),n.stack=p,g}f=n.enter("link"),d=n.enter("label");let h=l.move("[");return h+=l.move(n.containerPhrasing(e,{before:h,after:"](",...l.current()})),h+=l.move("]("),d(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(d=n.enter("destinationLiteral"),h+=l.move("<"),h+=l.move(n.safe(e.url,{before:h,after:">",...l.current()})),h+=l.move(">")):(d=n.enter("destinationRaw"),h+=l.move(n.safe(e.url,{before:h,after:e.title?" ":")",...l.current()}))),d(),e.title&&(d=n.enter(`title${o}`),h+=l.move(" "+u),h+=l.move(n.safe(e.title,{before:h,after:u,...l.current()})),h+=l.move(u),d()),h+=l.move(")"),f(),h}function pB(e,t,n){return $C(e,n)?"<":"["}JC.peek=gB;function JC(e,t,n,i){const u=e.referenceType,o=n.enter("linkReference");let l=n.enter("label");const f=n.createTracker(i);let d=f.move("[");const h=n.containerPhrasing(e,{before:d,after:"]",...f.current()});d+=f.move(h+"]["),l();const p=n.stack;n.stack=[],l=n.enter("reference");const g=n.safe(n.associationId(e),{before:d,after:"]",...f.current()});return l(),n.stack=p,o(),u==="full"||!h||h!==g?d+=f.move(g+"]"):u==="shortcut"?d=d.slice(0,-1):d+=f.move("]"),d}function gB(){return"["}function Ug(e){const t=e.options.bullet||"*";if(t!=="*"&&t!=="+"&&t!=="-")throw new Error("Cannot serialize items with `"+t+"` for `options.bullet`, expected `*`, `+`, or `-`");return t}function EB(e){const t=Ug(e),n=e.options.bulletOther;if(!n)return t==="*"?"-":"*";if(n!=="*"&&n!=="+"&&n!=="-")throw new Error("Cannot serialize items with `"+n+"` for `options.bulletOther`, expected `*`, `+`, or `-`");if(n===t)throw new Error("Expected `bullet` (`"+t+"`) and `bulletOther` (`"+n+"`) to be different");return n}function yB(e){const t=e.options.bulletOrdered||".";if(t!=="."&&t!==")")throw new Error("Cannot serialize items with `"+t+"` for `options.bulletOrdered`, expected `.` or `)`");return t}function e_(e){const t=e.options.rule||"*";if(t!=="*"&&t!=="-"&&t!=="_")throw new Error("Cannot serialize rules with `"+t+"` for `options.rule`, expected `*`, `-`, or `_`");return t}function bB(e,t,n,i){const u=n.enter("list"),o=n.bulletCurrent;let l=e.ordered?yB(n):Ug(n);const f=e.ordered?l==="."?")":".":EB(n);let d=t&&n.bulletLastUsed?l===n.bulletLastUsed:!1;if(!e.ordered){const p=e.children?e.children[0]:void 0;if((l==="*"||l==="-")&&p&&(!p.children||!p.children[0])&&n.stack[n.stack.length-1]==="list"&&n.stack[n.stack.length-2]==="listItem"&&n.stack[n.stack.length-3]==="list"&&n.stack[n.stack.length-4]==="listItem"&&n.indexStack[n.indexStack.length-1]===0&&n.indexStack[n.indexStack.length-2]===0&&n.indexStack[n.indexStack.length-3]===0&&(d=!0),e_(n)===l&&p){let g=-1;for(;++g<e.children.length;){const b=e.children[g];if(b&&b.type==="listItem"&&b.children&&b.children[0]&&b.children[0].type==="thematicBreak"){d=!0;break}}}}d&&(l=f),n.bulletCurrent=l;const h=n.containerFlow(e,i);return n.bulletLastUsed=l,n.bulletCurrent=o,u(),h}function TB(e){const t=e.options.listItemIndent||"one";if(t!=="tab"&&t!=="one"&&t!=="mixed")throw new Error("Cannot serialize items with `"+t+"` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`");return t}function AB(e,t,n,i){const u=TB(n);let o=n.bulletCurrent||Ug(n);t&&t.type==="list"&&t.ordered&&(o=(typeof t.start=="number"&&t.start>-1?t.start:1)+(n.options.incrementListMarker===!1?0:t.children.indexOf(e))+o);let l=o.length+1;(u==="tab"||u==="mixed"&&(t&&t.type==="list"&&t.spread||e.spread))&&(l=Math.ceil(l/4)*4);const f=n.createTracker(i);f.move(o+" ".repeat(l-o.length)),f.shift(l);const d=n.enter("listItem"),h=n.indentLines(n.containerFlow(e,f.current()),p);return d(),h;function p(g,b,T){return b?(T?"":" ".repeat(l))+g:(T?o:o+" ".repeat(l-o.length))+g}}function SB(e,t,n,i){const u=n.enter("paragraph"),o=n.enter("phrasing"),l=n.containerPhrasing(e,i);return o(),u(),l}const DB=cd(["break","delete","emphasis","footnote","footnoteReference","image","imageReference","inlineCode","inlineMath","link","linkReference","mdxJsxTextElement","mdxTextExpression","strong","text","textDirective"]);function vB(e,t,n,i){return(e.children.some(function(l){return DB(l)})?n.containerPhrasing:n.containerFlow).call(n,e,i)}function CB(e){const t=e.options.strong||"*";if(t!=="*"&&t!=="_")throw new Error("Cannot serialize strong with `"+t+"` for `options.strong`, expected `*`, or `_`");return t}t_.peek=_B;function t_(e,t,n,i){const u=CB(n),o=n.enter("strong"),l=n.createTracker(i),f=l.move(u+u);let d=l.move(n.containerPhrasing(e,{after:u,before:f,...l.current()}));const h=d.charCodeAt(0),p=Yf(i.before.charCodeAt(i.before.length-1),h,u);p.inside&&(d=Cl(h)+d.slice(1));const g=d.charCodeAt(d.length-1),b=Yf(i.after.charCodeAt(0),g,u);b.inside&&(d=d.slice(0,-1)+Cl(g));const T=l.move(u+u);return o(),n.attentionEncodeSurroundingInfo={after:b.outside,before:p.outside},f+d+T}function _B(e,t,n){return n.options.strong||"*"}function xB(e,t,n,i){return n.safe(e.value,i)}function RB(e){const t=e.options.ruleRepetition||3;if(t<3)throw new Error("Cannot serialize rules with repetition `"+t+"` for `options.ruleRepetition`, expected `3` or more");return t}function wB(e,t,n){const i=(e_(n)+(n.options.ruleSpaces?" ":"")).repeat(RB(n));return n.options.ruleSpaces?i.slice(0,-1):i}const n_={blockquote:ZF,break:IS,code:iB,definition:uB,emphasis:GC,hardBreak:IS,heading:cB,html:XC,image:KC,imageReference:WC,inlineCode:QC,link:ZC,linkReference:JC,list:bB,listItem:AB,paragraph:SB,root:vB,strong:t_,text:xB,thematicBreak:wB};function OB(){return{enter:{table:NB,tableData:PS,tableHeader:PS,tableRow:LB},exit:{codeText:MB,table:kB,tableData:Tp,tableHeader:Tp,tableRow:Tp}}}function NB(e){const t=e._align;this.enter({type:"table",align:t.map(function(n){return n==="none"?null:n}),children:[]},e),this.data.inTable=!0}function kB(e){this.exit(e),this.data.inTable=void 0}function LB(e){this.enter({type:"tableRow",children:[]},e)}function Tp(e){this.exit(e)}function PS(e){this.enter({type:"tableCell",children:[]},e)}function MB(e){let t=this.resume();this.data.inTable&&(t=t.replace(/\\([\\|])/g,IB));const n=this.stack[this.stack.length-1];n.type,n.value=t,this.exit(e)}function IB(e,t){return t==="|"?t:e}function PB(e){const t=e||{},n=t.tableCellPadding,i=t.tablePipeAlign,u=t.stringLength,o=n?" ":"|";return{unsafe:[{character:"\r",inConstruct:"tableCell"},{character:` +`,inConstruct:"tableCell"},{atBreak:!0,character:"|",after:"[ :-]"},{character:"|",inConstruct:"tableCell"},{atBreak:!0,character:":",after:"-"},{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{inlineCode:b,table:l,tableCell:d,tableRow:f}};function l(T,A,_,O){return h(p(T,_,O),T.align)}function f(T,A,_,O){const C=g(T,_,O),N=h([C]);return N.slice(0,N.indexOf(` +`))}function d(T,A,_,O){const C=_.enter("tableCell"),N=_.enter("phrasing"),R=_.containerPhrasing(T,{...O,before:o,after:o});return N(),C(),R}function h(T,A){return QF(T,{align:A,alignDelimiters:i,padding:n,stringLength:u})}function p(T,A,_){const O=T.children;let C=-1;const N=[],R=A.enter("table");for(;++C<O.length;)N[C]=g(O[C],A,_);return R(),N}function g(T,A,_){const O=T.children;let C=-1;const N=[],R=A.enter("tableRow");for(;++C<O.length;)N[C]=d(O[C],T,A,_);return R(),N}function b(T,A,_){let O=n_.inlineCode(T,A,_);return _.stack.includes("tableCell")&&(O=O.replace(/\|/g,"\\$&")),O}}function FB(){return{exit:{taskListCheckValueChecked:FS,taskListCheckValueUnchecked:FS,paragraph:UB}}}function BB(){return{unsafe:[{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{listItem:HB}}}function FS(e){const t=this.stack[this.stack.length-2];t.type,t.checked=e.type==="taskListCheckValueChecked"}function UB(e){const t=this.stack[this.stack.length-2];if(t&&t.type==="listItem"&&typeof t.checked=="boolean"){const n=this.stack[this.stack.length-1];n.type;const i=n.children[0];if(i&&i.type==="text"){const u=t.children;let o=-1,l;for(;++o<u.length;){const f=u[o];if(f.type==="paragraph"){l=f;break}}l===n&&(i.value=i.value.slice(1),i.value.length===0?n.children.shift():n.position&&i.position&&typeof i.position.start.offset=="number"&&(i.position.start.column++,i.position.start.offset++,n.position.start=Object.assign({},i.position.start)))}}this.exit(e)}function HB(e,t,n,i){const u=e.children[0],o=typeof e.checked=="boolean"&&u&&u.type==="paragraph",l="["+(e.checked?"x":" ")+"] ",f=n.createTracker(i);o&&f.move(l);let d=n_.listItem(e,t,n,{...i,...f.current()});return o&&(d=d.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/,h)),d;function h(p){return p+l}}function zB(){return[bF(),HF(),qF(),OB(),FB()]}function VB(e){return{extensions:[TF(),zF(e),YF(),PB(e),BB()]}}const jB={tokenize:WB,partial:!0},r_={tokenize:QB,partial:!0},i_={tokenize:$B,partial:!0},a_={tokenize:ZB,partial:!0},qB={tokenize:JB,partial:!0},u_={name:"wwwAutolink",tokenize:XB,previous:o_},s_={name:"protocolAutolink",tokenize:KB,previous:l_},zi={name:"emailAutolink",tokenize:GB,previous:c_},bi={};function YB(){return{text:bi}}let Qa=48;for(;Qa<123;)bi[Qa]=zi,Qa++,Qa===58?Qa=65:Qa===91&&(Qa=97);bi[43]=zi;bi[45]=zi;bi[46]=zi;bi[95]=zi;bi[72]=[zi,s_];bi[104]=[zi,s_];bi[87]=[zi,u_];bi[119]=[zi,u_];function GB(e,t,n){const i=this;let u,o;return l;function l(g){return!g0(g)||!c_.call(i,i.previous)||Hg(i.events)?n(g):(e.enter("literalAutolink"),e.enter("literalAutolinkEmail"),f(g))}function f(g){return g0(g)?(e.consume(g),f):g===64?(e.consume(g),d):n(g)}function d(g){return g===46?e.check(qB,p,h)(g):g===45||g===95||In(g)?(o=!0,e.consume(g),d):p(g)}function h(g){return e.consume(g),u=!0,d}function p(g){return o&&u&&zn(i.previous)?(e.exit("literalAutolinkEmail"),e.exit("literalAutolink"),t(g)):n(g)}}function XB(e,t,n){const i=this;return u;function u(l){return l!==87&&l!==119||!o_.call(i,i.previous)||Hg(i.events)?n(l):(e.enter("literalAutolink"),e.enter("literalAutolinkWww"),e.check(jB,e.attempt(r_,e.attempt(i_,o),n),n)(l))}function o(l){return e.exit("literalAutolinkWww"),e.exit("literalAutolink"),t(l)}}function KB(e,t,n){const i=this;let u="",o=!1;return l;function l(g){return(g===72||g===104)&&l_.call(i,i.previous)&&!Hg(i.events)?(e.enter("literalAutolink"),e.enter("literalAutolinkHttp"),u+=String.fromCodePoint(g),e.consume(g),f):n(g)}function f(g){if(zn(g)&&u.length<5)return u+=String.fromCodePoint(g),e.consume(g),f;if(g===58){const b=u.toLowerCase();if(b==="http"||b==="https")return e.consume(g),d}return n(g)}function d(g){return g===47?(e.consume(g),o?h:(o=!0,d)):n(g)}function h(g){return g===null||jf(g)||wt(g)||cu(g)||sd(g)?n(g):e.attempt(r_,e.attempt(i_,p),n)(g)}function p(g){return e.exit("literalAutolinkHttp"),e.exit("literalAutolink"),t(g)}}function WB(e,t,n){let i=0;return u;function u(l){return(l===87||l===119)&&i<3?(i++,e.consume(l),u):l===46&&i===3?(e.consume(l),o):n(l)}function o(l){return l===null?n(l):t(l)}}function QB(e,t,n){let i,u,o;return l;function l(h){return h===46||h===95?e.check(a_,d,f)(h):h===null||wt(h)||cu(h)||h!==45&&sd(h)?d(h):(o=!0,e.consume(h),l)}function f(h){return h===95?i=!0:(u=i,i=void 0),e.consume(h),l}function d(h){return u||i||!o?n(h):t(h)}}function $B(e,t){let n=0,i=0;return u;function u(l){return l===40?(n++,e.consume(l),u):l===41&&i<n?o(l):l===33||l===34||l===38||l===39||l===41||l===42||l===44||l===46||l===58||l===59||l===60||l===63||l===93||l===95||l===126?e.check(a_,t,o)(l):l===null||wt(l)||cu(l)?t(l):(e.consume(l),u)}function o(l){return l===41&&i++,e.consume(l),u}}function ZB(e,t,n){return i;function i(f){return f===33||f===34||f===39||f===41||f===42||f===44||f===46||f===58||f===59||f===63||f===95||f===126?(e.consume(f),i):f===38?(e.consume(f),o):f===93?(e.consume(f),u):f===60||f===null||wt(f)||cu(f)?t(f):n(f)}function u(f){return f===null||f===40||f===91||wt(f)||cu(f)?t(f):i(f)}function o(f){return zn(f)?l(f):n(f)}function l(f){return f===59?(e.consume(f),i):zn(f)?(e.consume(f),l):n(f)}}function JB(e,t,n){return i;function i(o){return e.consume(o),u}function u(o){return In(o)?n(o):t(o)}}function o_(e){return e===null||e===40||e===42||e===95||e===91||e===93||e===126||wt(e)}function l_(e){return!zn(e)}function c_(e){return!(e===47||g0(e))}function g0(e){return e===43||e===45||e===46||e===95||In(e)}function Hg(e){let t=e.length,n=!1;for(;t--;){const i=e[t][1];if((i.type==="labelLink"||i.type==="labelImage")&&!i._balanced){n=!0;break}if(i._gfmAutolinkLiteralWalkedInto){n=!1;break}}return e.length>0&&!n&&(e[e.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),n}const e9={tokenize:o9,partial:!0};function t9(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:a9,continuation:{tokenize:u9},exit:s9}},text:{91:{name:"gfmFootnoteCall",tokenize:i9},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:n9,resolveTo:r9}}}}function n9(e,t,n){const i=this;let u=i.events.length;const o=i.parser.gfmFootnotes||(i.parser.gfmFootnotes=[]);let l;for(;u--;){const d=i.events[u][1];if(d.type==="labelImage"){l=d;break}if(d.type==="gfmFootnoteCall"||d.type==="labelLink"||d.type==="label"||d.type==="image"||d.type==="link")break}return f;function f(d){if(!l||!l._balanced)return n(d);const h=$r(i.sliceSerialize({start:l.end,end:i.now()}));return h.codePointAt(0)!==94||!o.includes(h.slice(1))?n(d):(e.enter("gfmFootnoteCallLabelMarker"),e.consume(d),e.exit("gfmFootnoteCallLabelMarker"),t(d))}}function r9(e,t){let n=e.length;for(;n--;)if(e[n][1].type==="labelImage"&&e[n][0]==="enter"){e[n][1];break}e[n+1][1].type="data",e[n+3][1].type="gfmFootnoteCallLabelMarker";const i={type:"gfmFootnoteCall",start:Object.assign({},e[n+3][1].start),end:Object.assign({},e[e.length-1][1].end)},u={type:"gfmFootnoteCallMarker",start:Object.assign({},e[n+3][1].end),end:Object.assign({},e[n+3][1].end)};u.end.column++,u.end.offset++,u.end._bufferIndex++;const o={type:"gfmFootnoteCallString",start:Object.assign({},u.end),end:Object.assign({},e[e.length-1][1].start)},l={type:"chunkString",contentType:"string",start:Object.assign({},o.start),end:Object.assign({},o.end)},f=[e[n+1],e[n+2],["enter",i,t],e[n+3],e[n+4],["enter",u,t],["exit",u,t],["enter",o,t],["enter",l,t],["exit",l,t],["exit",o,t],e[e.length-2],e[e.length-1],["exit",i,t]];return e.splice(n,e.length-n+1,...f),e}function i9(e,t,n){const i=this,u=i.parser.gfmFootnotes||(i.parser.gfmFootnotes=[]);let o=0,l;return f;function f(g){return e.enter("gfmFootnoteCall"),e.enter("gfmFootnoteCallLabelMarker"),e.consume(g),e.exit("gfmFootnoteCallLabelMarker"),d}function d(g){return g!==94?n(g):(e.enter("gfmFootnoteCallMarker"),e.consume(g),e.exit("gfmFootnoteCallMarker"),e.enter("gfmFootnoteCallString"),e.enter("chunkString").contentType="string",h)}function h(g){if(o>999||g===93&&!l||g===null||g===91||wt(g))return n(g);if(g===93){e.exit("chunkString");const b=e.exit("gfmFootnoteCallString");return u.includes($r(i.sliceSerialize(b)))?(e.enter("gfmFootnoteCallLabelMarker"),e.consume(g),e.exit("gfmFootnoteCallLabelMarker"),e.exit("gfmFootnoteCall"),t):n(g)}return wt(g)||(l=!0),o++,e.consume(g),g===92?p:h}function p(g){return g===91||g===92||g===93?(e.consume(g),o++,h):h(g)}}function a9(e,t,n){const i=this,u=i.parser.gfmFootnotes||(i.parser.gfmFootnotes=[]);let o,l=0,f;return d;function d(A){return e.enter("gfmFootnoteDefinition")._container=!0,e.enter("gfmFootnoteDefinitionLabel"),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(A),e.exit("gfmFootnoteDefinitionLabelMarker"),h}function h(A){return A===94?(e.enter("gfmFootnoteDefinitionMarker"),e.consume(A),e.exit("gfmFootnoteDefinitionMarker"),e.enter("gfmFootnoteDefinitionLabelString"),e.enter("chunkString").contentType="string",p):n(A)}function p(A){if(l>999||A===93&&!f||A===null||A===91||wt(A))return n(A);if(A===93){e.exit("chunkString");const _=e.exit("gfmFootnoteDefinitionLabelString");return o=$r(i.sliceSerialize(_)),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(A),e.exit("gfmFootnoteDefinitionLabelMarker"),e.exit("gfmFootnoteDefinitionLabel"),b}return wt(A)||(f=!0),l++,e.consume(A),A===92?g:p}function g(A){return A===91||A===92||A===93?(e.consume(A),l++,p):p(A)}function b(A){return A===58?(e.enter("definitionMarker"),e.consume(A),e.exit("definitionMarker"),u.includes(o)||u.push(o),Et(e,T,"gfmFootnoteDefinitionWhitespace")):n(A)}function T(A){return t(A)}}function u9(e,t,n){return e.check(Pl,t,e.attempt(e9,t,n))}function s9(e){e.exit("gfmFootnoteDefinition")}function o9(e,t,n){const i=this;return Et(e,u,"gfmFootnoteDefinitionIndent",5);function u(o){const l=i.events[i.events.length-1];return l&&l[1].type==="gfmFootnoteDefinitionIndent"&&l[2].sliceSerialize(l[1],!0).length===4?t(o):n(o)}}function l9(e){let n=(e||{}).singleTilde;const i={name:"strikethrough",tokenize:o,resolveAll:u};return n==null&&(n=!0),{text:{126:i},insideSpan:{null:[i]},attentionMarkers:{null:[126]}};function u(l,f){let d=-1;for(;++d<l.length;)if(l[d][0]==="enter"&&l[d][1].type==="strikethroughSequenceTemporary"&&l[d][1]._close){let h=d;for(;h--;)if(l[h][0]==="exit"&&l[h][1].type==="strikethroughSequenceTemporary"&&l[h][1]._open&&l[d][1].end.offset-l[d][1].start.offset===l[h][1].end.offset-l[h][1].start.offset){l[d][1].type="strikethroughSequence",l[h][1].type="strikethroughSequence";const p={type:"strikethrough",start:Object.assign({},l[h][1].start),end:Object.assign({},l[d][1].end)},g={type:"strikethroughText",start:Object.assign({},l[h][1].end),end:Object.assign({},l[d][1].start)},b=[["enter",p,f],["enter",l[h][1],f],["exit",l[h][1],f],["enter",g,f]],T=f.parser.constructs.insideSpan.null;T&&Tr(b,b.length,0,od(T,l.slice(h+1,d),f)),Tr(b,b.length,0,[["exit",g,f],["enter",l[d][1],f],["exit",l[d][1],f],["exit",p,f]]),Tr(l,h-1,d-h+3,b),d=h+b.length-2;break}}for(d=-1;++d<l.length;)l[d][1].type==="strikethroughSequenceTemporary"&&(l[d][1].type="data");return l}function o(l,f,d){const h=this.previous,p=this.events;let g=0;return b;function b(A){return h===126&&p[p.length-1][1].type!=="characterEscape"?d(A):(l.enter("strikethroughSequenceTemporary"),T(A))}function T(A){const _=ds(h);if(A===126)return g>1?d(A):(l.consume(A),g++,T);if(g<2&&!n)return d(A);const O=l.exit("strikethroughSequenceTemporary"),C=ds(A);return O._open=!C||C===2&&!!_,O._close=!_||_===2&&!!C,f(A)}}}class c9{constructor(){this.map=[]}add(t,n,i){f9(this,t,n,i)}consume(t){if(this.map.sort(function(o,l){return o[0]-l[0]}),this.map.length===0)return;let n=this.map.length;const i=[];for(;n>0;)n-=1,i.push(t.slice(this.map[n][0]+this.map[n][1]),this.map[n][2]),t.length=this.map[n][0];i.push(t.slice()),t.length=0;let u=i.pop();for(;u;){for(const o of u)t.push(o);u=i.pop()}this.map.length=0}}function f9(e,t,n,i){let u=0;if(!(n===0&&i.length===0)){for(;u<e.map.length;){if(e.map[u][0]===t){e.map[u][1]+=n,e.map[u][2].push(...i);return}u+=1}e.map.push([t,n,i])}}function d9(e,t){let n=!1;const i=[];for(;t<e.length;){const u=e[t];if(n){if(u[0]==="enter")u[1].type==="tableContent"&&i.push(e[t+1][1].type==="tableDelimiterMarker"?"left":"none");else if(u[1].type==="tableContent"){if(e[t-1][1].type==="tableDelimiterMarker"){const o=i.length-1;i[o]=i[o]==="left"?"center":"right"}}else if(u[1].type==="tableDelimiterRow")break}else u[0]==="enter"&&u[1].type==="tableDelimiterRow"&&(n=!0);t+=1}return i}function h9(){return{flow:{null:{name:"table",tokenize:m9,resolveAll:p9}}}}function m9(e,t,n){const i=this;let u=0,o=0,l;return f;function f(z){let V=i.events.length-1;for(;V>-1;){const Z=i.events[V][1].type;if(Z==="lineEnding"||Z==="linePrefix")V--;else break}const F=V>-1?i.events[V][1].type:null,$=F==="tableHead"||F==="tableRow"?v:d;return $===v&&i.parser.lazy[i.now().line]?n(z):$(z)}function d(z){return e.enter("tableHead"),e.enter("tableRow"),h(z)}function h(z){return z===124||(l=!0,o+=1),p(z)}function p(z){return z===null?n(z):Ve(z)?o>1?(o=0,i.interrupt=!0,e.exit("tableRow"),e.enter("lineEnding"),e.consume(z),e.exit("lineEnding"),T):n(z):nt(z)?Et(e,p,"whitespace")(z):(o+=1,l&&(l=!1,u+=1),z===124?(e.enter("tableCellDivider"),e.consume(z),e.exit("tableCellDivider"),l=!0,p):(e.enter("data"),g(z)))}function g(z){return z===null||z===124||wt(z)?(e.exit("data"),p(z)):(e.consume(z),z===92?b:g)}function b(z){return z===92||z===124?(e.consume(z),g):g(z)}function T(z){return i.interrupt=!1,i.parser.lazy[i.now().line]?n(z):(e.enter("tableDelimiterRow"),l=!1,nt(z)?Et(e,A,"linePrefix",i.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(z):A(z))}function A(z){return z===45||z===58?O(z):z===124?(l=!0,e.enter("tableCellDivider"),e.consume(z),e.exit("tableCellDivider"),_):M(z)}function _(z){return nt(z)?Et(e,O,"whitespace")(z):O(z)}function O(z){return z===58?(o+=1,l=!0,e.enter("tableDelimiterMarker"),e.consume(z),e.exit("tableDelimiterMarker"),C):z===45?(o+=1,C(z)):z===null||Ve(z)?Y(z):M(z)}function C(z){return z===45?(e.enter("tableDelimiterFiller"),N(z)):M(z)}function N(z){return z===45?(e.consume(z),N):z===58?(l=!0,e.exit("tableDelimiterFiller"),e.enter("tableDelimiterMarker"),e.consume(z),e.exit("tableDelimiterMarker"),R):(e.exit("tableDelimiterFiller"),R(z))}function R(z){return nt(z)?Et(e,Y,"whitespace")(z):Y(z)}function Y(z){return z===124?A(z):z===null||Ve(z)?!l||u!==o?M(z):(e.exit("tableDelimiterRow"),e.exit("tableHead"),t(z)):M(z)}function M(z){return n(z)}function v(z){return e.enter("tableRow"),J(z)}function J(z){return z===124?(e.enter("tableCellDivider"),e.consume(z),e.exit("tableCellDivider"),J):z===null||Ve(z)?(e.exit("tableRow"),t(z)):nt(z)?Et(e,J,"whitespace")(z):(e.enter("data"),P(z))}function P(z){return z===null||z===124||wt(z)?(e.exit("data"),J(z)):(e.consume(z),z===92?q:P)}function q(z){return z===92||z===124?(e.consume(z),P):P(z)}}function p9(e,t){let n=-1,i=!0,u=0,o=[0,0,0,0],l=[0,0,0,0],f=!1,d=0,h,p,g;const b=new c9;for(;++n<e.length;){const T=e[n],A=T[1];T[0]==="enter"?A.type==="tableHead"?(f=!1,d!==0&&(BS(b,t,d,h,p),p=void 0,d=0),h={type:"table",start:Object.assign({},A.start),end:Object.assign({},A.end)},b.add(n,0,[["enter",h,t]])):A.type==="tableRow"||A.type==="tableDelimiterRow"?(i=!0,g=void 0,o=[0,0,0,0],l=[0,n+1,0,0],f&&(f=!1,p={type:"tableBody",start:Object.assign({},A.start),end:Object.assign({},A.end)},b.add(n,0,[["enter",p,t]])),u=A.type==="tableDelimiterRow"?2:p?3:1):u&&(A.type==="data"||A.type==="tableDelimiterMarker"||A.type==="tableDelimiterFiller")?(i=!1,l[2]===0&&(o[1]!==0&&(l[0]=l[1],g=df(b,t,o,u,void 0,g),o=[0,0,0,0]),l[2]=n)):A.type==="tableCellDivider"&&(i?i=!1:(o[1]!==0&&(l[0]=l[1],g=df(b,t,o,u,void 0,g)),o=l,l=[o[1],n,0,0])):A.type==="tableHead"?(f=!0,d=n):A.type==="tableRow"||A.type==="tableDelimiterRow"?(d=n,o[1]!==0?(l[0]=l[1],g=df(b,t,o,u,n,g)):l[1]!==0&&(g=df(b,t,l,u,n,g)),u=0):u&&(A.type==="data"||A.type==="tableDelimiterMarker"||A.type==="tableDelimiterFiller")&&(l[3]=n)}for(d!==0&&BS(b,t,d,h,p),b.consume(t.events),n=-1;++n<t.events.length;){const T=t.events[n];T[0]==="enter"&&T[1].type==="table"&&(T[1]._align=d9(t.events,n))}return e}function df(e,t,n,i,u,o){const l=i===1?"tableHeader":i===2?"tableDelimiter":"tableData",f="tableContent";n[0]!==0&&(o.end=Object.assign({},es(t.events,n[0])),e.add(n[0],0,[["exit",o,t]]));const d=es(t.events,n[1]);if(o={type:l,start:Object.assign({},d),end:Object.assign({},d)},e.add(n[1],0,[["enter",o,t]]),n[2]!==0){const h=es(t.events,n[2]),p=es(t.events,n[3]),g={type:f,start:Object.assign({},h),end:Object.assign({},p)};if(e.add(n[2],0,[["enter",g,t]]),i!==2){const b=t.events[n[2]],T=t.events[n[3]];if(b[1].end=Object.assign({},T[1].end),b[1].type="chunkText",b[1].contentType="text",n[3]>n[2]+1){const A=n[2]+1,_=n[3]-n[2]-1;e.add(A,_,[])}}e.add(n[3]+1,0,[["exit",g,t]])}return u!==void 0&&(o.end=Object.assign({},es(t.events,u)),e.add(u,0,[["exit",o,t]]),o=void 0),o}function BS(e,t,n,i,u){const o=[],l=es(t.events,n);u&&(u.end=Object.assign({},l),o.push(["exit",u,t])),i.end=Object.assign({},l),o.push(["exit",i,t]),e.add(n+1,0,o)}function es(e,t){const n=e[t],i=n[0]==="enter"?"start":"end";return n[1][i]}const g9={name:"tasklistCheck",tokenize:y9};function E9(){return{text:{91:g9}}}function y9(e,t,n){const i=this;return u;function u(d){return i.previous!==null||!i._gfmTasklistFirstContentOfListItem?n(d):(e.enter("taskListCheck"),e.enter("taskListCheckMarker"),e.consume(d),e.exit("taskListCheckMarker"),o)}function o(d){return wt(d)?(e.enter("taskListCheckValueUnchecked"),e.consume(d),e.exit("taskListCheckValueUnchecked"),l):d===88||d===120?(e.enter("taskListCheckValueChecked"),e.consume(d),e.exit("taskListCheckValueChecked"),l):n(d)}function l(d){return d===93?(e.enter("taskListCheckMarker"),e.consume(d),e.exit("taskListCheckMarker"),e.exit("taskListCheck"),f):n(d)}function f(d){return Ve(d)?t(d):nt(d)?e.check({tokenize:b9},t,n)(d):n(d)}}function b9(e,t,n){return Et(e,i,"whitespace");function i(u){return u===null?n(u):t(u)}}function T9(e){return TC([YB(),t9(),l9(e),h9(),E9()])}const A9={};function yq(e){const t=this,n=e||A9,i=t.data(),u=i.micromarkExtensions||(i.micromarkExtensions=[]),o=i.fromMarkdownExtensions||(i.fromMarkdownExtensions=[]),l=i.toMarkdownExtensions||(i.toMarkdownExtensions=[]);u.push(T9(n)),o.push(zB()),l.push(VB(n))}const f_=function(e){if(e==null)return C9;if(typeof e=="string")return v9(e);if(typeof e=="object")return Array.isArray(e)?S9(e):D9(e);if(typeof e=="function")return dd(e);throw new Error("Expected function, string, or object as test")};function S9(e){const t=[];let n=-1;for(;++n<e.length;)t[n]=f_(e[n]);return dd(i);function i(...u){let o=-1;for(;++o<t.length;)if(t[o].call(this,...u))return!0;return!1}}function D9(e){return dd(t);function t(n){let i;for(i in e)if(n[i]!==e[i])return!1;return!0}}function v9(e){return dd(t);function t(n){return n&&n.type===e}}function dd(e){return t;function t(n,...i){return!!(n&&typeof n=="object"&&"type"in n&&e.call(this,n,...i))}}function C9(){return!0}const _9=!0,US=!1,x9="skip",R9=function(e,t,n,i){typeof t=="function"&&typeof n!="function"&&(i=n,n=t,t=null);const u=f_(t),o=i?-1:1;l(e,void 0,[])();function l(f,d,h){const p=f&&typeof f=="object"?f:{};if(typeof p.type=="string"){const b=typeof p.tagName=="string"?p.tagName:typeof p.name=="string"?p.name:void 0;Object.defineProperty(g,"name",{value:"node ("+(f.type+(b?"<"+b+">":""))+")"})}return g;function g(){let b=[],T,A,_;if((!t||u(f,d,h[h.length-1]||null))&&(b=w9(n(f,h)),b[0]===US))return b;if(f.children&&b[0]!==x9)for(A=(i?f.children.length:-1)+o,_=h.concat(f);A>-1&&A<f.children.length;){if(T=l(f.children[A],A,_)(),T[0]===US)return T;A=typeof T[1]=="number"?T[1]:A+o}return b}}};function w9(e){return Array.isArray(e)?e:typeof e=="number"?[_9,e]:[e]}const HS=function(e,t,n,i){typeof t=="function"&&typeof n!="function"&&(i=n,n=t,t=null),R9(e,t,u,i);function u(o,l){const f=l[l.length-1];return n(o,f?f.children.indexOf(o):null,f)}};function bq(){return e=>{HS(e,["text"],(t,n,i)=>{if(t.type!=="text")return;const{value:u}=t,o=u.split(/\^/);if(o.length===1||o.length%2===0)return;const l=o.map((f,d)=>d%2===0?{type:"text",value:f}:{type:"superscript",data:{hName:"sup"},children:[{type:"text",value:f}]});i.children.splice(n,1,...l)}),HS(e,["text"],(t,n,i)=>{if(t.type!=="text")return;const{value:u}=t,o=u.split(/\~/);if(o.length===1||o.length%2===0)return;const l=o.map((f,d)=>d%2===0?{type:"text",value:f}:{type:"subscript",data:{hName:"sub"},children:[{type:"text",value:f}]});i.children.splice(n,1,...l)})}}var Ap={exports:{}},zS;function O9(){return zS||(zS=1,function(e){(function(){var t;t=e.exports=u,t.format=u,t.vsprintf=i,typeof console<"u"&&typeof console.log=="function"&&(t.printf=n);function n(){console.log(u.apply(null,arguments))}function i(o,l){return u.apply(null,[o].concat(l))}function u(o){for(var l=1,f=[].slice.call(arguments),d=0,h=o.length,p="",g,b=!1,T,A,_=!1,O,C=function(){return f[l++]},N=function(){for(var R="";/\d/.test(o[d]);)R+=o[d++],g=o[d];return R.length>0?parseInt(R):null};d<h;++d)if(g=o[d],b)switch(b=!1,g=="."?(_=!1,g=o[++d]):g=="0"&&o[d+1]=="."?(_=!0,d+=2,g=o[d]):_=!0,O=N(),g){case"b":p+=parseInt(C(),10).toString(2);break;case"c":T=C(),typeof T=="string"||T instanceof String?p+=T:p+=String.fromCharCode(parseInt(T,10));break;case"d":p+=parseInt(C(),10);break;case"f":A=String(parseFloat(C()).toFixed(O||6)),p+=_?A:A.replace(/^0/,"");break;case"j":p+=JSON.stringify(C());break;case"o":p+="0"+parseInt(C(),10).toString(8);break;case"s":p+=C();break;case"x":p+="0x"+parseInt(C(),10).toString(16);break;case"X":p+="0x"+parseInt(C(),10).toString(16).toUpperCase();break;default:p+=g;break}else g==="%"?b=!0:p+=g;return p}})()}(Ap)),Ap.exports}var N9=O9();const k9=Rl(N9),hf=Object.assign($a(Error),{eval:$a(EvalError),range:$a(RangeError),reference:$a(ReferenceError),syntax:$a(SyntaxError),type:$a(TypeError),uri:$a(URIError)});function $a(e){return t.displayName=e.displayName||e.name,t;function t(n,...i){const u=n&&k9(n,...i);return new e(u)}}const mf={}.hasOwnProperty,VS={yaml:"-",toml:"+"};function zg(e){const t=[];let n=-1;const i=Array.isArray(e)?e:e?[e]:["yaml"];for(;++n<i.length;)t[n]=L9(i[n]);return t}function L9(e){let t=e;if(typeof t=="string"){if(!mf.call(VS,t))throw hf("Missing matter definition for `%s`",t);t={type:t,marker:VS[t]}}else if(typeof t!="object")throw hf("Expected matter to be an object, not `%j`",t);if(!mf.call(t,"type"))throw hf("Missing `type` in matter `%j`",t);if(!mf.call(t,"fence")&&!mf.call(t,"marker"))throw hf("Missing `marker` or `fence` in matter `%j`",t);return t}function M9(e){const t=zg(e),n={};let i=-1;for(;++i<t.length;){const u=t[i],o=E0(u,"open").charCodeAt(0),l=I9(u),f=n[o];Array.isArray(f)?f.push(l):n[o]=[l]}return{flow:n}}function I9(e){const t=e.anywhere,n=e.type,i=n+"Fence",u=i+"Sequence",o=n+"Value",l={tokenize:p,partial:!0};let f,d=0;return{tokenize:h,concrete:!0};function h(g,b,T){const A=this;return _;function _(J){const P=A.now();return P.column===1&&(P.line===1||t)&&(f=E0(e,"open"),d=0,J===f.charCodeAt(d))?(g.enter(n),g.enter(i),g.enter(u),O(J)):T(J)}function O(J){return d===f.length?(g.exit(u),nt(J)?(g.enter("whitespace"),C(J)):N(J)):J===f.charCodeAt(d++)?(g.consume(J),O):T(J)}function C(J){return nt(J)?(g.consume(J),C):(g.exit("whitespace"),N(J))}function N(J){return Ve(J)?(g.exit(i),g.enter("lineEnding"),g.consume(J),g.exit("lineEnding"),f=E0(e,"close"),d=0,g.attempt(l,v,R)):T(J)}function R(J){return J===null||Ve(J)?M(J):(g.enter(o),Y(J))}function Y(J){return J===null||Ve(J)?(g.exit(o),M(J)):(g.consume(J),Y)}function M(J){return J===null?T(J):(g.enter("lineEnding"),g.consume(J),g.exit("lineEnding"),g.attempt(l,v,R))}function v(J){return g.exit(n),b(J)}}function p(g,b,T){let A=0;return _;function _(R){return R===f.charCodeAt(A)?(g.enter(i),g.enter(u),O(R)):T(R)}function O(R){return A===f.length?(g.exit(u),nt(R)?(g.enter("whitespace"),C(R)):N(R)):R===f.charCodeAt(A++)?(g.consume(R),O):T(R)}function C(R){return nt(R)?(g.consume(R),C):(g.exit("whitespace"),N(R))}function N(R){return R===null||Ve(R)?(g.exit(i),b(R)):T(R)}}}function E0(e,t){return e.marker?jS(e.marker,t).repeat(3):jS(e.fence,t)}function jS(e,t){return typeof e=="string"?e:e[t]}function P9(e){if(typeof e!="string")throw new TypeError("Expected a string");return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}function F9(e){const t=zg(e),n={},i={};let u=-1;for(;++u<t.length;){const o=t[u];n[o.type]=B9(o),i[o.type]=U9,i[o.type+"Value"]=H9}return{enter:n,exit:i}}function B9(e){return t;function t(n){this.enter({type:e.type,value:""},n),this.buffer()}}function U9(e){const t=this.resume(),n=this.stack[this.stack.length-1];this.exit(e),n.value=t.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g,"")}function H9(e){this.config.enter.data.call(this,e),this.config.exit.data.call(this,e)}function z9(e){const t=[],n={},i=zg(e);let u=-1;for(;++u<i.length;){const o=i[u];n[o.type]=V9(o);const l=y0(o,"open");t.push({atBreak:!0,character:l.charAt(0),after:P9(l.charAt(1))})}return{unsafe:t,handlers:n}}function V9(e){const t=y0(e,"open"),n=y0(e,"close");return i;function i(u){return t+(u.value?` +`+u.value:"")+` +`+n}}function y0(e,t){return e.marker?qS(e.marker,t).repeat(3):qS(e.fence,t)}function qS(e,t){return typeof e=="string"?e:e[t]}const j9="yaml";function Tq(e){const t=this,n=e||j9,i=t.data(),u=i.micromarkExtensions||(i.micromarkExtensions=[]),o=i.fromMarkdownExtensions||(i.fromMarkdownExtensions=[]),l=i.toMarkdownExtensions||(i.toMarkdownExtensions=[]);u.push(M9(n)),o.push(F9(n)),l.push(z9(n))}const YS=/[#.]/g;function q9(e,t){const n=e||"",i={};let u=0,o,l;for(;u<n.length;){YS.lastIndex=u;const f=YS.exec(n),d=n.slice(u,f?f.index:n.length);d&&(o?o==="#"?i.id=d:Array.isArray(i.className)?i.className.push(d):i.className=[d]:l=d,u+=d.length),f&&(o=f[0],u++)}return{type:"element",tagName:l||t||"div",properties:i,children:[]}}function d_(e,t,n){const i=n?K9(n):void 0;function u(o,l,...f){let d;if(o==null){d={type:"root",children:[]};const h=l;f.unshift(h)}else{d=q9(o,t);const h=d.tagName.toLowerCase(),p=i?i.get(h):void 0;if(d.tagName=p||h,Y9(l))f.unshift(l);else for(const[g,b]of Object.entries(l))G9(e,d.properties,g,b)}for(const h of f)b0(d.children,h);return d.type==="element"&&d.tagName==="template"&&(d.content={type:"root",children:d.children},d.children=[]),d}return u}function Y9(e){if(e===null||typeof e!="object"||Array.isArray(e))return!0;if(typeof e.type!="string")return!1;const t=e,n=Object.keys(e);for(const i of n){const u=t[i];if(u&&typeof u=="object"){if(!Array.isArray(u))return!0;const o=u;for(const l of o)if(typeof l!="number"&&typeof l!="string")return!0}}return!!("children"in e&&Array.isArray(e.children))}function G9(e,t,n,i){const u=_g(e,n);let o;if(i!=null){if(typeof i=="number"){if(Number.isNaN(i))return;o=i}else typeof i=="boolean"?o=i:typeof i=="string"?u.spaceSeparated?o=ZA(i):u.commaSeparated?o=XA(i):u.commaOrSpaceSeparated?o=ZA(XA(i).join(" ")):o=GS(u,u.property,i):Array.isArray(i)?o=[...i]:o=u.property==="style"?X9(i):String(i);if(Array.isArray(o)){const l=[];for(const f of o)l.push(GS(u,u.property,f));o=l}u.property==="className"&&Array.isArray(t.className)&&(o=t.className.concat(o)),t[u.property]=o}}function b0(e,t){if(t!=null)if(typeof t=="number"||typeof t=="string")e.push({type:"text",value:String(t)});else if(Array.isArray(t))for(const n of t)b0(e,n);else if(typeof t=="object"&&"type"in t)t.type==="root"?b0(e,t.children):e.push(t);else throw new Error("Expected node, nodes, or string, got `"+t+"`")}function GS(e,t,n){if(typeof n=="string"){if(e.number&&n&&!Number.isNaN(Number(n)))return Number(n);if((e.boolean||e.overloadedBoolean)&&(n===""||Dl(n)===Dl(t)))return!0}return n}function X9(e){const t=[];for(const[n,i]of Object.entries(e))t.push([n,i].join(": "));return t.join("; ")}function K9(e){const t=new Map;for(const n of e)t.set(n.toLowerCase(),n);return t}const W9=["altGlyph","altGlyphDef","altGlyphItem","animateColor","animateMotion","animateTransform","clipPath","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","foreignObject","glyphRef","linearGradient","radialGradient","solidColor","textArea","textPath"],Q9=d_(ad,"div"),$9=d_(As,"g",W9);function Z9(e){const t=String(e),n=[];return{toOffset:u,toPoint:i};function i(o){if(typeof o=="number"&&o>-1&&o<=t.length){let l=0;for(;;){let f=n[l];if(f===void 0){const d=XS(t,n[l-1]);f=d===-1?t.length+1:d+1,n[l]=f}if(f>o)return{line:l+1,column:o-(l>0?n[l-1]:0)+1,offset:o};l++}}}function u(o){if(o&&typeof o.line=="number"&&typeof o.column=="number"&&!Number.isNaN(o.line)&&!Number.isNaN(o.column)){for(;n.length<o.line;){const f=n[n.length-1],d=XS(t,f),h=d===-1?t.length+1:d+1;if(f===h)break;n.push(h)}const l=(o.line>1?n[o.line-2]:0)+o.column-1;if(l<n[o.line-1])return l}}}function XS(e,t){const n=e.indexOf("\r",t),i=e.indexOf(` +`,t);return i===-1?n:n===-1||n+1===i?i:n<i?n:i}const iu={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},h_={}.hasOwnProperty,J9=Object.prototype;function e7(e,t){const n=t||{};return Vg({file:n.file||void 0,location:!1,schema:n.space==="svg"?As:ad,verbose:n.verbose||!1},e)}function Vg(e,t){let n;switch(t.nodeName){case"#comment":{const i=t;return n={type:"comment",value:i.data},Rf(e,i,n),n}case"#document":case"#document-fragment":{const i=t,u="mode"in i?i.mode==="quirks"||i.mode==="limited-quirks":!1;if(n={type:"root",children:m_(e,t.childNodes),data:{quirksMode:u}},e.file&&e.location){const o=String(e.file),l=Z9(o),f=l.toPoint(0),d=l.toPoint(o.length);n.position={start:f,end:d}}return n}case"#documentType":{const i=t;return n={type:"doctype"},Rf(e,i,n),n}case"#text":{const i=t;return n={type:"text",value:i.value},Rf(e,i,n),n}default:return n=t7(e,t),n}}function m_(e,t){let n=-1;const i=[];for(;++n<t.length;){const u=Vg(e,t[n]);i.push(u)}return i}function t7(e,t){const n=e.schema;e.schema=t.namespaceURI===iu.svg?As:ad;let i=-1;const u={};for(;++i<t.attrs.length;){const f=t.attrs[i],d=(f.prefix?f.prefix+":":"")+f.name;h_.call(J9,d)||(u[d]=f.value)}const l=(e.schema.space==="svg"?$9:Q9)(t.tagName,u,m_(e,t.childNodes));if(Rf(e,t,l),l.tagName==="template"){const f=t,d=f.sourceCodeLocation,h=d&&d.startTag&&us(d.startTag),p=d&&d.endTag&&us(d.endTag),g=Vg(e,f.content);h&&p&&e.file&&(g.position={start:h.end,end:p.start}),l.content=g}return e.schema=n,l}function Rf(e,t,n){if("sourceCodeLocation"in t&&t.sourceCodeLocation&&e.file){const i=n7(e,n,t.sourceCodeLocation);i&&(e.location=!0,n.position=i)}}function n7(e,t,n){const i=us(n);if(t.type==="element"){const u=t.children[t.children.length-1];if(i&&!n.endTag&&u&&u.position&&u.position.end&&(i.end=Object.assign({},u.position.end)),e.verbose){const o={};let l;if(n.attrs)for(l in n.attrs)h_.call(n.attrs,l)&&(o[_g(e.schema,l).property]=us(n.attrs[l]));n.startTag;const f=us(n.startTag),d=n.endTag?us(n.endTag):void 0,h={opening:f};d&&(h.closing=d),h.properties=o,t.data={position:h}}}return i}function us(e){const t=KS({line:e.startLine,column:e.startCol,offset:e.startOffset}),n=KS({line:e.endLine,column:e.endCol,offset:e.endOffset});return t||n?{start:t,end:n}:void 0}function KS(e){return e.line&&e.column?e:void 0}class Bl{constructor(t,n,i){this.property=t,this.normal=n,i&&(this.space=i)}}Bl.prototype.property={};Bl.prototype.normal={};Bl.prototype.space=null;function p_(e,t){const n={},i={};let u=-1;for(;++u<e.length;)Object.assign(n,e[u].property),Object.assign(i,e[u].normal);return new Bl(n,i,t)}function T0(e){return e.toLowerCase()}class Vr{constructor(t,n){this.property=t,this.attribute=n}}Vr.prototype.space=null;Vr.prototype.boolean=!1;Vr.prototype.booleanish=!1;Vr.prototype.overloadedBoolean=!1;Vr.prototype.number=!1;Vr.prototype.commaSeparated=!1;Vr.prototype.spaceSeparated=!1;Vr.prototype.commaOrSpaceSeparated=!1;Vr.prototype.mustUseProperty=!1;Vr.prototype.defined=!1;let r7=0;const Ze=mu(),mn=mu(),g_=mu(),ve=mu(),Pt=mu(),ls=mu(),Er=mu();function mu(){return 2**++r7}const A0=Object.freeze(Object.defineProperty({__proto__:null,boolean:Ze,booleanish:mn,commaOrSpaceSeparated:Er,commaSeparated:ls,number:ve,overloadedBoolean:g_,spaceSeparated:Pt},Symbol.toStringTag,{value:"Module"})),Sp=Object.keys(A0);class jg extends Vr{constructor(t,n,i,u){let o=-1;if(super(t,n),WS(this,"space",u),typeof i=="number")for(;++o<Sp.length;){const l=Sp[o];WS(this,Sp[o],(i&A0[l])===A0[l])}}}jg.prototype.defined=!0;function WS(e,t,n){n&&(e[t]=n)}const i7={}.hasOwnProperty;function vs(e){const t={},n={};let i;for(i in e.properties)if(i7.call(e.properties,i)){const u=e.properties[i],o=new jg(i,e.transform(e.attributes||{},i),u,e.space);e.mustUseProperty&&e.mustUseProperty.includes(i)&&(o.mustUseProperty=!0),t[i]=o,n[T0(i)]=i,n[T0(o.attribute)]=i}return new Bl(t,n,e.space)}const E_=vs({space:"xlink",transform(e,t){return"xlink:"+t.slice(5).toLowerCase()},properties:{xLinkActuate:null,xLinkArcRole:null,xLinkHref:null,xLinkRole:null,xLinkShow:null,xLinkTitle:null,xLinkType:null}}),y_=vs({space:"xml",transform(e,t){return"xml:"+t.slice(3).toLowerCase()},properties:{xmlLang:null,xmlBase:null,xmlSpace:null}});function b_(e,t){return t in e?e[t]:t}function T_(e,t){return b_(e,t.toLowerCase())}const A_=vs({space:"xmlns",attributes:{xmlnsxlink:"xmlns:xlink"},transform:T_,properties:{xmlns:null,xmlnsXLink:null}}),S_=vs({transform(e,t){return t==="role"?t:"aria-"+t.slice(4).toLowerCase()},properties:{ariaActiveDescendant:null,ariaAtomic:mn,ariaAutoComplete:null,ariaBusy:mn,ariaChecked:mn,ariaColCount:ve,ariaColIndex:ve,ariaColSpan:ve,ariaControls:Pt,ariaCurrent:null,ariaDescribedBy:Pt,ariaDetails:null,ariaDisabled:mn,ariaDropEffect:Pt,ariaErrorMessage:null,ariaExpanded:mn,ariaFlowTo:Pt,ariaGrabbed:mn,ariaHasPopup:null,ariaHidden:mn,ariaInvalid:null,ariaKeyShortcuts:null,ariaLabel:null,ariaLabelledBy:Pt,ariaLevel:ve,ariaLive:null,ariaModal:mn,ariaMultiLine:mn,ariaMultiSelectable:mn,ariaOrientation:null,ariaOwns:Pt,ariaPlaceholder:null,ariaPosInSet:ve,ariaPressed:mn,ariaReadOnly:mn,ariaRelevant:null,ariaRequired:mn,ariaRoleDescription:Pt,ariaRowCount:ve,ariaRowIndex:ve,ariaRowSpan:ve,ariaSelected:mn,ariaSetSize:ve,ariaSort:null,ariaValueMax:ve,ariaValueMin:ve,ariaValueNow:ve,ariaValueText:null,role:null}}),a7=vs({space:"html",attributes:{acceptcharset:"accept-charset",classname:"class",htmlfor:"for",httpequiv:"http-equiv"},transform:T_,mustUseProperty:["checked","multiple","muted","selected"],properties:{abbr:null,accept:ls,acceptCharset:Pt,accessKey:Pt,action:null,allow:null,allowFullScreen:Ze,allowPaymentRequest:Ze,allowUserMedia:Ze,alt:null,as:null,async:Ze,autoCapitalize:null,autoComplete:Pt,autoFocus:Ze,autoPlay:Ze,blocking:Pt,capture:null,charSet:null,checked:Ze,cite:null,className:Pt,cols:ve,colSpan:null,content:null,contentEditable:mn,controls:Ze,controlsList:Pt,coords:ve|ls,crossOrigin:null,data:null,dateTime:null,decoding:null,default:Ze,defer:Ze,dir:null,dirName:null,disabled:Ze,download:g_,draggable:mn,encType:null,enterKeyHint:null,fetchPriority:null,form:null,formAction:null,formEncType:null,formMethod:null,formNoValidate:Ze,formTarget:null,headers:Pt,height:ve,hidden:Ze,high:ve,href:null,hrefLang:null,htmlFor:Pt,httpEquiv:Pt,id:null,imageSizes:null,imageSrcSet:null,inert:Ze,inputMode:null,integrity:null,is:null,isMap:Ze,itemId:null,itemProp:Pt,itemRef:Pt,itemScope:Ze,itemType:Pt,kind:null,label:null,lang:null,language:null,list:null,loading:null,loop:Ze,low:ve,manifest:null,max:null,maxLength:ve,media:null,method:null,min:null,minLength:ve,multiple:Ze,muted:Ze,name:null,nonce:null,noModule:Ze,noValidate:Ze,onAbort:null,onAfterPrint:null,onAuxClick:null,onBeforeMatch:null,onBeforePrint:null,onBeforeToggle:null,onBeforeUnload:null,onBlur:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onContextLost:null,onContextMenu:null,onContextRestored:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnded:null,onError:null,onFocus:null,onFormData:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLanguageChange:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadEnd:null,onLoadStart:null,onMessage:null,onMessageError:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRejectionHandled:null,onReset:null,onResize:null,onScroll:null,onScrollEnd:null,onSecurityPolicyViolation:null,onSeeked:null,onSeeking:null,onSelect:null,onSlotChange:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnhandledRejection:null,onUnload:null,onVolumeChange:null,onWaiting:null,onWheel:null,open:Ze,optimum:ve,pattern:null,ping:Pt,placeholder:null,playsInline:Ze,popover:null,popoverTarget:null,popoverTargetAction:null,poster:null,preload:null,readOnly:Ze,referrerPolicy:null,rel:Pt,required:Ze,reversed:Ze,rows:ve,rowSpan:ve,sandbox:Pt,scope:null,scoped:Ze,seamless:Ze,selected:Ze,shadowRootClonable:Ze,shadowRootDelegatesFocus:Ze,shadowRootMode:null,shape:null,size:ve,sizes:null,slot:null,span:ve,spellCheck:mn,src:null,srcDoc:null,srcLang:null,srcSet:null,start:ve,step:null,style:null,tabIndex:ve,target:null,title:null,translate:null,type:null,typeMustMatch:Ze,useMap:null,value:mn,width:ve,wrap:null,writingSuggestions:null,align:null,aLink:null,archive:Pt,axis:null,background:null,bgColor:null,border:ve,borderColor:null,bottomMargin:ve,cellPadding:null,cellSpacing:null,char:null,charOff:null,classId:null,clear:null,code:null,codeBase:null,codeType:null,color:null,compact:Ze,declare:Ze,event:null,face:null,frame:null,frameBorder:null,hSpace:ve,leftMargin:ve,link:null,longDesc:null,lowSrc:null,marginHeight:ve,marginWidth:ve,noResize:Ze,noHref:Ze,noShade:Ze,noWrap:Ze,object:null,profile:null,prompt:null,rev:null,rightMargin:ve,rules:null,scheme:null,scrolling:mn,standby:null,summary:null,text:null,topMargin:ve,valueType:null,version:null,vAlign:null,vLink:null,vSpace:ve,allowTransparency:null,autoCorrect:null,autoSave:null,disablePictureInPicture:Ze,disableRemotePlayback:Ze,prefix:null,property:null,results:ve,security:null,unselectable:null}}),u7=vs({space:"svg",attributes:{accentHeight:"accent-height",alignmentBaseline:"alignment-baseline",arabicForm:"arabic-form",baselineShift:"baseline-shift",capHeight:"cap-height",className:"class",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorProfile:"color-profile",colorRendering:"color-rendering",crossOrigin:"crossorigin",dataType:"datatype",dominantBaseline:"dominant-baseline",enableBackground:"enable-background",fillOpacity:"fill-opacity",fillRule:"fill-rule",floodColor:"flood-color",floodOpacity:"flood-opacity",fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",glyphName:"glyph-name",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",hrefLang:"hreflang",horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",horizOriginY:"horiz-origin-y",imageRendering:"image-rendering",letterSpacing:"letter-spacing",lightingColor:"lighting-color",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",navDown:"nav-down",navDownLeft:"nav-down-left",navDownRight:"nav-down-right",navLeft:"nav-left",navNext:"nav-next",navPrev:"nav-prev",navRight:"nav-right",navUp:"nav-up",navUpLeft:"nav-up-left",navUpRight:"nav-up-right",onAbort:"onabort",onActivate:"onactivate",onAfterPrint:"onafterprint",onBeforePrint:"onbeforeprint",onBegin:"onbegin",onCancel:"oncancel",onCanPlay:"oncanplay",onCanPlayThrough:"oncanplaythrough",onChange:"onchange",onClick:"onclick",onClose:"onclose",onCopy:"oncopy",onCueChange:"oncuechange",onCut:"oncut",onDblClick:"ondblclick",onDrag:"ondrag",onDragEnd:"ondragend",onDragEnter:"ondragenter",onDragExit:"ondragexit",onDragLeave:"ondragleave",onDragOver:"ondragover",onDragStart:"ondragstart",onDrop:"ondrop",onDurationChange:"ondurationchange",onEmptied:"onemptied",onEnd:"onend",onEnded:"onended",onError:"onerror",onFocus:"onfocus",onFocusIn:"onfocusin",onFocusOut:"onfocusout",onHashChange:"onhashchange",onInput:"oninput",onInvalid:"oninvalid",onKeyDown:"onkeydown",onKeyPress:"onkeypress",onKeyUp:"onkeyup",onLoad:"onload",onLoadedData:"onloadeddata",onLoadedMetadata:"onloadedmetadata",onLoadStart:"onloadstart",onMessage:"onmessage",onMouseDown:"onmousedown",onMouseEnter:"onmouseenter",onMouseLeave:"onmouseleave",onMouseMove:"onmousemove",onMouseOut:"onmouseout",onMouseOver:"onmouseover",onMouseUp:"onmouseup",onMouseWheel:"onmousewheel",onOffline:"onoffline",onOnline:"ononline",onPageHide:"onpagehide",onPageShow:"onpageshow",onPaste:"onpaste",onPause:"onpause",onPlay:"onplay",onPlaying:"onplaying",onPopState:"onpopstate",onProgress:"onprogress",onRateChange:"onratechange",onRepeat:"onrepeat",onReset:"onreset",onResize:"onresize",onScroll:"onscroll",onSeeked:"onseeked",onSeeking:"onseeking",onSelect:"onselect",onShow:"onshow",onStalled:"onstalled",onStorage:"onstorage",onSubmit:"onsubmit",onSuspend:"onsuspend",onTimeUpdate:"ontimeupdate",onToggle:"ontoggle",onUnload:"onunload",onVolumeChange:"onvolumechange",onWaiting:"onwaiting",onZoom:"onzoom",overlinePosition:"overline-position",overlineThickness:"overline-thickness",paintOrder:"paint-order",panose1:"panose-1",pointerEvents:"pointer-events",referrerPolicy:"referrerpolicy",renderingIntent:"rendering-intent",shapeRendering:"shape-rendering",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",strokeDashArray:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeLineCap:"stroke-linecap",strokeLineJoin:"stroke-linejoin",strokeMiterLimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",tabIndex:"tabindex",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",transformOrigin:"transform-origin",typeOf:"typeof",underlinePosition:"underline-position",underlineThickness:"underline-thickness",unicodeBidi:"unicode-bidi",unicodeRange:"unicode-range",unitsPerEm:"units-per-em",vAlphabetic:"v-alphabetic",vHanging:"v-hanging",vIdeographic:"v-ideographic",vMathematical:"v-mathematical",vectorEffect:"vector-effect",vertAdvY:"vert-adv-y",vertOriginX:"vert-origin-x",vertOriginY:"vert-origin-y",wordSpacing:"word-spacing",writingMode:"writing-mode",xHeight:"x-height",playbackOrder:"playbackorder",timelineBegin:"timelinebegin"},transform:b_,properties:{about:Er,accentHeight:ve,accumulate:null,additive:null,alignmentBaseline:null,alphabetic:ve,amplitude:ve,arabicForm:null,ascent:ve,attributeName:null,attributeType:null,azimuth:ve,bandwidth:null,baselineShift:null,baseFrequency:null,baseProfile:null,bbox:null,begin:null,bias:ve,by:null,calcMode:null,capHeight:ve,className:Pt,clip:null,clipPath:null,clipPathUnits:null,clipRule:null,color:null,colorInterpolation:null,colorInterpolationFilters:null,colorProfile:null,colorRendering:null,content:null,contentScriptType:null,contentStyleType:null,crossOrigin:null,cursor:null,cx:null,cy:null,d:null,dataType:null,defaultAction:null,descent:ve,diffuseConstant:ve,direction:null,display:null,dur:null,divisor:ve,dominantBaseline:null,download:Ze,dx:null,dy:null,edgeMode:null,editable:null,elevation:ve,enableBackground:null,end:null,event:null,exponent:ve,externalResourcesRequired:null,fill:null,fillOpacity:ve,fillRule:null,filter:null,filterRes:null,filterUnits:null,floodColor:null,floodOpacity:null,focusable:null,focusHighlight:null,fontFamily:null,fontSize:null,fontSizeAdjust:null,fontStretch:null,fontStyle:null,fontVariant:null,fontWeight:null,format:null,fr:null,from:null,fx:null,fy:null,g1:ls,g2:ls,glyphName:ls,glyphOrientationHorizontal:null,glyphOrientationVertical:null,glyphRef:null,gradientTransform:null,gradientUnits:null,handler:null,hanging:ve,hatchContentUnits:null,hatchUnits:null,height:null,href:null,hrefLang:null,horizAdvX:ve,horizOriginX:ve,horizOriginY:ve,id:null,ideographic:ve,imageRendering:null,initialVisibility:null,in:null,in2:null,intercept:ve,k:ve,k1:ve,k2:ve,k3:ve,k4:ve,kernelMatrix:Er,kernelUnitLength:null,keyPoints:null,keySplines:null,keyTimes:null,kerning:null,lang:null,lengthAdjust:null,letterSpacing:null,lightingColor:null,limitingConeAngle:ve,local:null,markerEnd:null,markerMid:null,markerStart:null,markerHeight:null,markerUnits:null,markerWidth:null,mask:null,maskContentUnits:null,maskUnits:null,mathematical:null,max:null,media:null,mediaCharacterEncoding:null,mediaContentEncodings:null,mediaSize:ve,mediaTime:null,method:null,min:null,mode:null,name:null,navDown:null,navDownLeft:null,navDownRight:null,navLeft:null,navNext:null,navPrev:null,navRight:null,navUp:null,navUpLeft:null,navUpRight:null,numOctaves:null,observer:null,offset:null,onAbort:null,onActivate:null,onAfterPrint:null,onBeforePrint:null,onBegin:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnd:null,onEnded:null,onError:null,onFocus:null,onFocusIn:null,onFocusOut:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadStart:null,onMessage:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onMouseWheel:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRepeat:null,onReset:null,onResize:null,onScroll:null,onSeeked:null,onSeeking:null,onSelect:null,onShow:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnload:null,onVolumeChange:null,onWaiting:null,onZoom:null,opacity:null,operator:null,order:null,orient:null,orientation:null,origin:null,overflow:null,overlay:null,overlinePosition:ve,overlineThickness:ve,paintOrder:null,panose1:null,path:null,pathLength:ve,patternContentUnits:null,patternTransform:null,patternUnits:null,phase:null,ping:Pt,pitch:null,playbackOrder:null,pointerEvents:null,points:null,pointsAtX:ve,pointsAtY:ve,pointsAtZ:ve,preserveAlpha:null,preserveAspectRatio:null,primitiveUnits:null,propagate:null,property:Er,r:null,radius:null,referrerPolicy:null,refX:null,refY:null,rel:Er,rev:Er,renderingIntent:null,repeatCount:null,repeatDur:null,requiredExtensions:Er,requiredFeatures:Er,requiredFonts:Er,requiredFormats:Er,resource:null,restart:null,result:null,rotate:null,rx:null,ry:null,scale:null,seed:null,shapeRendering:null,side:null,slope:null,snapshotTime:null,specularConstant:ve,specularExponent:ve,spreadMethod:null,spacing:null,startOffset:null,stdDeviation:null,stemh:null,stemv:null,stitchTiles:null,stopColor:null,stopOpacity:null,strikethroughPosition:ve,strikethroughThickness:ve,string:null,stroke:null,strokeDashArray:Er,strokeDashOffset:null,strokeLineCap:null,strokeLineJoin:null,strokeMiterLimit:ve,strokeOpacity:ve,strokeWidth:null,style:null,surfaceScale:ve,syncBehavior:null,syncBehaviorDefault:null,syncMaster:null,syncTolerance:null,syncToleranceDefault:null,systemLanguage:Er,tabIndex:ve,tableValues:null,target:null,targetX:ve,targetY:ve,textAnchor:null,textDecoration:null,textRendering:null,textLength:null,timelineBegin:null,title:null,transformBehavior:null,type:null,typeOf:Er,to:null,transform:null,transformOrigin:null,u1:null,u2:null,underlinePosition:ve,underlineThickness:ve,unicode:null,unicodeBidi:null,unicodeRange:null,unitsPerEm:ve,values:null,vAlphabetic:ve,vMathematical:ve,vectorEffect:null,vHanging:ve,vIdeographic:ve,version:null,vertAdvY:ve,vertOriginX:ve,vertOriginY:ve,viewBox:null,viewTarget:null,visibility:null,width:null,widths:null,wordSpacing:null,writingMode:null,x:null,x1:null,x2:null,xChannelSelector:null,xHeight:ve,y:null,y1:null,y2:null,yChannelSelector:null,z:null,zoomAndPan:null}}),s7=/^data[-\w.:]+$/i,QS=/-[a-z]/g,o7=/[A-Z]/g;function l7(e,t){const n=T0(t);let i=t,u=Vr;if(n in e.normal)return e.property[e.normal[n]];if(n.length>4&&n.slice(0,4)==="data"&&s7.test(t)){if(t.charAt(4)==="-"){const o=t.slice(5).replace(QS,f7);i="data"+o.charAt(0).toUpperCase()+o.slice(1)}else{const o=t.slice(4);if(!QS.test(o)){let l=o.replace(o7,c7);l.charAt(0)!=="-"&&(l="-"+l),t="data"+l}}u=jg}return new u(i,t)}function c7(e){return"-"+e.toLowerCase()}function f7(e){return e.charAt(1).toUpperCase()}const d7=p_([y_,E_,A_,S_,a7],"html"),D_=p_([y_,E_,A_,S_,u7],"svg"),h7={},m7={}.hasOwnProperty,v_=YC("type",{handlers:{root:g7,element:A7,text:b7,comment:T7,doctype:y7}});function p7(e,t){const i=(t||h7).space;return v_(e,i==="svg"?D_:d7)}function g7(e,t){const n={nodeName:"#document",mode:(e.data||{}).quirksMode?"quirks":"no-quirks",childNodes:[]};return n.childNodes=qg(e.children,n,t),Cs(e,n),n}function E7(e,t){const n={nodeName:"#document-fragment",childNodes:[]};return n.childNodes=qg(e.children,n,t),Cs(e,n),n}function y7(e){const t={nodeName:"#documentType",name:"html",publicId:"",systemId:"",parentNode:null};return Cs(e,t),t}function b7(e){const t={nodeName:"#text",value:e.value,parentNode:null};return Cs(e,t),t}function T7(e){const t={nodeName:"#comment",data:e.value,parentNode:null};return Cs(e,t),t}function A7(e,t){const n=t;let i=n;e.type==="element"&&e.tagName.toLowerCase()==="svg"&&n.space==="html"&&(i=D_);const u=[];let o;if(e.properties){for(o in e.properties)if(o!=="children"&&m7.call(e.properties,o)){const d=S7(i,o,e.properties[o]);d&&u.push(d)}}const l=i.space,f={nodeName:e.tagName,tagName:e.tagName,attrs:u,namespaceURI:iu[l],childNodes:[],parentNode:null};return f.childNodes=qg(e.children,f,i),Cs(e,f),e.tagName==="template"&&e.content&&(f.content=E7(e.content,i)),f}function S7(e,t,n){const i=l7(e,t);if(n===!1||n===null||n===void 0||typeof n=="number"&&Number.isNaN(n)||!n&&i.boolean)return;Array.isArray(n)&&(n=i.commaSeparated?iC(n):dC(n));const u={name:i.attribute,value:n===!0?"":String(n)};if(i.space&&i.space!=="html"&&i.space!=="svg"){const o=u.name.indexOf(":");o<0?u.prefix="":(u.name=u.name.slice(o+1),u.prefix=i.attribute.slice(0,o)),u.namespace=iu[i.space]}return u}function qg(e,t,n){let i=-1;const u=[];if(e)for(;++i<e.length;){const o=v_(e[i],n);o.parentNode=t,u.push(o)}return u}function Cs(e,t){const n=e.position;n&&n.start&&n.end&&(n.start.offset,n.end.offset,t.sourceCodeLocation={startLine:n.start.line,startCol:n.start.column,startOffset:n.start.offset,endLine:n.end.line,endCol:n.end.column,endOffset:n.end.offset})}const D7=["area","base","basefont","bgsound","br","col","command","embed","frame","hr","image","img","input","keygen","link","meta","param","source","track","wbr"],v7=new Set([65534,65535,131070,131071,196606,196607,262142,262143,327678,327679,393214,393215,458750,458751,524286,524287,589822,589823,655358,655359,720894,720895,786430,786431,851966,851967,917502,917503,983038,983039,1048574,1048575,1114110,1114111]),Vt="�";var k;(function(e){e[e.EOF=-1]="EOF",e[e.NULL=0]="NULL",e[e.TABULATION=9]="TABULATION",e[e.CARRIAGE_RETURN=13]="CARRIAGE_RETURN",e[e.LINE_FEED=10]="LINE_FEED",e[e.FORM_FEED=12]="FORM_FEED",e[e.SPACE=32]="SPACE",e[e.EXCLAMATION_MARK=33]="EXCLAMATION_MARK",e[e.QUOTATION_MARK=34]="QUOTATION_MARK",e[e.AMPERSAND=38]="AMPERSAND",e[e.APOSTROPHE=39]="APOSTROPHE",e[e.HYPHEN_MINUS=45]="HYPHEN_MINUS",e[e.SOLIDUS=47]="SOLIDUS",e[e.DIGIT_0=48]="DIGIT_0",e[e.DIGIT_9=57]="DIGIT_9",e[e.SEMICOLON=59]="SEMICOLON",e[e.LESS_THAN_SIGN=60]="LESS_THAN_SIGN",e[e.EQUALS_SIGN=61]="EQUALS_SIGN",e[e.GREATER_THAN_SIGN=62]="GREATER_THAN_SIGN",e[e.QUESTION_MARK=63]="QUESTION_MARK",e[e.LATIN_CAPITAL_A=65]="LATIN_CAPITAL_A",e[e.LATIN_CAPITAL_Z=90]="LATIN_CAPITAL_Z",e[e.RIGHT_SQUARE_BRACKET=93]="RIGHT_SQUARE_BRACKET",e[e.GRAVE_ACCENT=96]="GRAVE_ACCENT",e[e.LATIN_SMALL_A=97]="LATIN_SMALL_A",e[e.LATIN_SMALL_Z=122]="LATIN_SMALL_Z"})(k||(k={}));const er={DASH_DASH:"--",CDATA_START:"[CDATA[",DOCTYPE:"doctype",SCRIPT:"script",PUBLIC:"public",SYSTEM:"system"};function C_(e){return e>=55296&&e<=57343}function C7(e){return e>=56320&&e<=57343}function _7(e,t){return(e-55296)*1024+9216+t}function __(e){return e!==32&&e!==10&&e!==13&&e!==9&&e!==12&&e>=1&&e<=31||e>=127&&e<=159}function x_(e){return e>=64976&&e<=65007||v7.has(e)}var fe;(function(e){e.controlCharacterInInputStream="control-character-in-input-stream",e.noncharacterInInputStream="noncharacter-in-input-stream",e.surrogateInInputStream="surrogate-in-input-stream",e.nonVoidHtmlElementStartTagWithTrailingSolidus="non-void-html-element-start-tag-with-trailing-solidus",e.endTagWithAttributes="end-tag-with-attributes",e.endTagWithTrailingSolidus="end-tag-with-trailing-solidus",e.unexpectedSolidusInTag="unexpected-solidus-in-tag",e.unexpectedNullCharacter="unexpected-null-character",e.unexpectedQuestionMarkInsteadOfTagName="unexpected-question-mark-instead-of-tag-name",e.invalidFirstCharacterOfTagName="invalid-first-character-of-tag-name",e.unexpectedEqualsSignBeforeAttributeName="unexpected-equals-sign-before-attribute-name",e.missingEndTagName="missing-end-tag-name",e.unexpectedCharacterInAttributeName="unexpected-character-in-attribute-name",e.unknownNamedCharacterReference="unknown-named-character-reference",e.missingSemicolonAfterCharacterReference="missing-semicolon-after-character-reference",e.unexpectedCharacterAfterDoctypeSystemIdentifier="unexpected-character-after-doctype-system-identifier",e.unexpectedCharacterInUnquotedAttributeValue="unexpected-character-in-unquoted-attribute-value",e.eofBeforeTagName="eof-before-tag-name",e.eofInTag="eof-in-tag",e.missingAttributeValue="missing-attribute-value",e.missingWhitespaceBetweenAttributes="missing-whitespace-between-attributes",e.missingWhitespaceAfterDoctypePublicKeyword="missing-whitespace-after-doctype-public-keyword",e.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers="missing-whitespace-between-doctype-public-and-system-identifiers",e.missingWhitespaceAfterDoctypeSystemKeyword="missing-whitespace-after-doctype-system-keyword",e.missingQuoteBeforeDoctypePublicIdentifier="missing-quote-before-doctype-public-identifier",e.missingQuoteBeforeDoctypeSystemIdentifier="missing-quote-before-doctype-system-identifier",e.missingDoctypePublicIdentifier="missing-doctype-public-identifier",e.missingDoctypeSystemIdentifier="missing-doctype-system-identifier",e.abruptDoctypePublicIdentifier="abrupt-doctype-public-identifier",e.abruptDoctypeSystemIdentifier="abrupt-doctype-system-identifier",e.cdataInHtmlContent="cdata-in-html-content",e.incorrectlyOpenedComment="incorrectly-opened-comment",e.eofInScriptHtmlCommentLikeText="eof-in-script-html-comment-like-text",e.eofInDoctype="eof-in-doctype",e.nestedComment="nested-comment",e.abruptClosingOfEmptyComment="abrupt-closing-of-empty-comment",e.eofInComment="eof-in-comment",e.incorrectlyClosedComment="incorrectly-closed-comment",e.eofInCdata="eof-in-cdata",e.absenceOfDigitsInNumericCharacterReference="absence-of-digits-in-numeric-character-reference",e.nullCharacterReference="null-character-reference",e.surrogateCharacterReference="surrogate-character-reference",e.characterReferenceOutsideUnicodeRange="character-reference-outside-unicode-range",e.controlCharacterReference="control-character-reference",e.noncharacterCharacterReference="noncharacter-character-reference",e.missingWhitespaceBeforeDoctypeName="missing-whitespace-before-doctype-name",e.missingDoctypeName="missing-doctype-name",e.invalidCharacterSequenceAfterDoctypeName="invalid-character-sequence-after-doctype-name",e.duplicateAttribute="duplicate-attribute",e.nonConformingDoctype="non-conforming-doctype",e.missingDoctype="missing-doctype",e.misplacedDoctype="misplaced-doctype",e.endTagWithoutMatchingOpenElement="end-tag-without-matching-open-element",e.closingOfElementWithOpenChildElements="closing-of-element-with-open-child-elements",e.disallowedContentInNoscriptInHead="disallowed-content-in-noscript-in-head",e.openElementsLeftAfterEof="open-elements-left-after-eof",e.abandonedHeadElementChild="abandoned-head-element-child",e.misplacedStartTagForHeadElement="misplaced-start-tag-for-head-element",e.nestedNoscriptInHead="nested-noscript-in-head",e.eofInElementThatCanContainOnlyText="eof-in-element-that-can-contain-only-text"})(fe||(fe={}));const x7=65536;class R7{constructor(t){this.handler=t,this.html="",this.pos=-1,this.lastGapPos=-2,this.gapStack=[],this.skipNextNewLine=!1,this.lastChunkWritten=!1,this.endOfChunkHit=!1,this.bufferWaterline=x7,this.isEol=!1,this.lineStartPos=0,this.droppedBufferSize=0,this.line=1,this.lastErrOffset=-1}get col(){return this.pos-this.lineStartPos+ +(this.lastGapPos!==this.pos)}get offset(){return this.droppedBufferSize+this.pos}getError(t,n){const{line:i,col:u,offset:o}=this,l=u+n,f=o+n;return{code:t,startLine:i,endLine:i,startCol:l,endCol:l,startOffset:f,endOffset:f}}_err(t){this.handler.onParseError&&this.lastErrOffset!==this.offset&&(this.lastErrOffset=this.offset,this.handler.onParseError(this.getError(t,0)))}_addGap(){this.gapStack.push(this.lastGapPos),this.lastGapPos=this.pos}_processSurrogate(t){if(this.pos!==this.html.length-1){const n=this.html.charCodeAt(this.pos+1);if(C7(n))return this.pos++,this._addGap(),_7(t,n)}else if(!this.lastChunkWritten)return this.endOfChunkHit=!0,k.EOF;return this._err(fe.surrogateInInputStream),t}willDropParsedChunk(){return this.pos>this.bufferWaterline}dropParsedChunk(){this.willDropParsedChunk()&&(this.html=this.html.substring(this.pos),this.lineStartPos-=this.pos,this.droppedBufferSize+=this.pos,this.pos=0,this.lastGapPos=-2,this.gapStack.length=0)}write(t,n){this.html.length>0?this.html+=t:this.html=t,this.endOfChunkHit=!1,this.lastChunkWritten=n}insertHtmlAtCurrentPos(t){this.html=this.html.substring(0,this.pos+1)+t+this.html.substring(this.pos+1),this.endOfChunkHit=!1}startsWith(t,n){if(this.pos+t.length>this.html.length)return this.endOfChunkHit=!this.lastChunkWritten,!1;if(n)return this.html.startsWith(t,this.pos);for(let i=0;i<t.length;i++)if((this.html.charCodeAt(this.pos+i)|32)!==t.charCodeAt(i))return!1;return!0}peek(t){const n=this.pos+t;if(n>=this.html.length)return this.endOfChunkHit=!this.lastChunkWritten,k.EOF;const i=this.html.charCodeAt(n);return i===k.CARRIAGE_RETURN?k.LINE_FEED:i}advance(){if(this.pos++,this.isEol&&(this.isEol=!1,this.line++,this.lineStartPos=this.pos),this.pos>=this.html.length)return this.endOfChunkHit=!this.lastChunkWritten,k.EOF;let t=this.html.charCodeAt(this.pos);return t===k.CARRIAGE_RETURN?(this.isEol=!0,this.skipNextNewLine=!0,k.LINE_FEED):t===k.LINE_FEED&&(this.isEol=!0,this.skipNextNewLine)?(this.line--,this.skipNextNewLine=!1,this._addGap(),this.advance()):(this.skipNextNewLine=!1,C_(t)&&(t=this._processSurrogate(t)),this.handler.onParseError===null||t>31&&t<127||t===k.LINE_FEED||t===k.CARRIAGE_RETURN||t>159&&t<64976||this._checkForProblematicCharacters(t),t)}_checkForProblematicCharacters(t){__(t)?this._err(fe.controlCharacterInInputStream):x_(t)&&this._err(fe.noncharacterInInputStream)}retreat(t){for(this.pos-=t;this.pos<this.lastGapPos;)this.lastGapPos=this.gapStack.pop(),this.pos--;this.isEol=!1}}var st;(function(e){e[e.CHARACTER=0]="CHARACTER",e[e.NULL_CHARACTER=1]="NULL_CHARACTER",e[e.WHITESPACE_CHARACTER=2]="WHITESPACE_CHARACTER",e[e.START_TAG=3]="START_TAG",e[e.END_TAG=4]="END_TAG",e[e.COMMENT=5]="COMMENT",e[e.DOCTYPE=6]="DOCTYPE",e[e.EOF=7]="EOF",e[e.HIBERNATION=8]="HIBERNATION"})(st||(st={}));function R_(e,t){for(let n=e.attrs.length-1;n>=0;n--)if(e.attrs[n].name===t)return e.attrs[n].value;return null}const w7=new Uint16Array('ᵁ<Õıʊҝջאٵ۞ޢߖࠏઑඡ༉༦ረዡᐕᒝᓃᓟᔥ\0\0\0\0\0\0ᕫᛍᦍᰒᷝ↰⊍⏀⏻⑂⠤⤒ⴈ⹈⿎〖㊺㘹㞬㣾㨨㩱㫠㬮ࠀEMabcfglmnoprstu\\bfms¦³¹ÈÏlig耻Æ䃆P耻&䀦cute耻Á䃁reve;䄂Āiyx}rc耻Â䃂;䐐r;쀀𝔄rave耻À䃀pha;䎑acr;䄀d;橓Āgp¡on;䄄f;쀀𝔸plyFunction;恡ing耻Å䃅Ācs¾Ãr;쀀𝒜ign;扔ilde耻Ã䃃ml耻Ä䃄ЀaceforsuåûþėĜĢħĪĀcrêòkslash;或Ŷöø;櫧ed;挆y;䐑ƀcrtąċĔause;戵noullis;愬a;䎒r;쀀𝔅pf;쀀𝔹eve;䋘còēmpeq;扎܀HOacdefhilorsuōőŖƀƞƢƵƷƺǜȕɳɸɾcy;䐧PY耻©䂩ƀcpyŝŢźute;䄆Ā;iŧŨ拒talDifferentialD;慅leys;愭ȀaeioƉƎƔƘron;䄌dil耻Ç䃇rc;䄈nint;戰ot;䄊ĀdnƧƭilla;䂸terDot;䂷òſi;䎧rcleȀDMPTLJNjǑǖot;抙inus;抖lus;投imes;抗oĀcsǢǸkwiseContourIntegral;戲eCurlyĀDQȃȏoubleQuote;思uote;怙ȀlnpuȞȨɇɕonĀ;eȥȦ户;橴ƀgitȯȶȺruent;扡nt;戯ourIntegral;戮ĀfrɌɎ;愂oduct;成nterClockwiseContourIntegral;戳oss;樯cr;쀀𝒞pĀ;Cʄʅ拓ap;才րDJSZacefiosʠʬʰʴʸˋ˗ˡ˦̳ҍĀ;oŹʥtrahd;椑cy;䐂cy;䐅cy;䐏ƀgrsʿ˄ˇger;怡r;憡hv;櫤Āayː˕ron;䄎;䐔lĀ;t˝˞戇a;䎔r;쀀𝔇Āaf˫̧Ācm˰̢riticalȀADGT̖̜̀̆cute;䂴oŴ̋̍;䋙bleAcute;䋝rave;䁠ilde;䋜ond;拄ferentialD;慆Ѱ̽\0\0\0͔͂\0Ѕf;쀀𝔻ƀ;DE͈͉͍䂨ot;惜qual;扐blèCDLRUVͣͲϏϢϸontourIntegraìȹoɴ\0\0ͻ»͉nArrow;懓Āeo·ΤftƀARTΐΖΡrrow;懐ightArrow;懔eåˊngĀLRΫτeftĀARγιrrow;柸ightArrow;柺ightArrow;柹ightĀATϘϞrrow;懒ee;抨pɁϩ\0\0ϯrrow;懑ownArrow;懕erticalBar;戥ǹABLRTaВЪаўѿͼrrowƀ;BUНОТ憓ar;椓pArrow;懵reve;䌑eft˒к\0ц\0ѐightVector;楐eeVector;楞ectorĀ;Bљњ憽ar;楖ightǔѧ\0ѱeeVector;楟ectorĀ;BѺѻ懁ar;楗eeĀ;A҆҇护rrow;憧ĀctҒҗr;쀀𝒟rok;䄐ࠀNTacdfglmopqstuxҽӀӄӋӞӢӧӮӵԡԯԶՒ՝ՠեG;䅊H耻Ð䃐cute耻É䃉ƀaiyӒӗӜron;䄚rc耻Ê䃊;䐭ot;䄖r;쀀𝔈rave耻È䃈ement;戈ĀapӺӾcr;䄒tyɓԆ\0\0ԒmallSquare;旻erySmallSquare;斫ĀgpԦԪon;䄘f;쀀𝔼silon;䎕uĀaiԼՉlĀ;TՂՃ橵ilde;扂librium;懌Āci՚r;愰m;橳a;䎗ml耻Ë䃋Āipժկsts;戃onentialE;慇ʀcfiosօֈ֍ֲy;䐤r;쀀𝔉lledɓ֗\0\0֣mallSquare;旼erySmallSquare;斪Ͱֺ\0ֿ\0\0ׄf;쀀𝔽All;戀riertrf;愱còJTabcdfgorstרׯؒؖ؛؝أ٬ٲcy;䐃耻>䀾mmaĀ;d䎓;䏜reve;䄞ƀeiy؇،ؐdil;䄢rc;䄜;䐓ot;䄠r;쀀𝔊;拙pf;쀀𝔾eater̀EFGLSTصلَٖٛ٦qualĀ;Lؾؿ扥ess;招ullEqual;执reater;檢ess;扷lantEqual;橾ilde;扳cr;쀀𝒢;扫ЀAacfiosuڅڋږڛڞڪھۊRDcy;䐪Āctڐڔek;䋇;䁞irc;䄤r;愌lbertSpace;愋ǰگ\0ڲf;愍izontalLine;攀Āctۃۅòکrok;䄦mpńېۘownHumðįqual;扏܀EJOacdfgmnostuۺ۾܃܇ܚܞܡܨ݄ݸދޏޕcy;䐕lig;䄲cy;䐁cute耻Í䃍Āiyܓܘrc耻Î䃎;䐘ot;䄰r;愑rave耻Ì䃌ƀ;apܠܯܿĀcgܴܷr;䄪inaryI;慈lieóϝǴ݉\0ݢĀ;eݍݎ戬Āgrݓݘral;戫section;拂isibleĀCTݬݲomma;恣imes;恢ƀgptݿރވon;䄮f;쀀𝕀a;䎙cr;愐ilde;䄨ǫޚ\0ޞcy;䐆l耻Ï䃏ʀcfosuެ߂ߐĀiyޱrc;䄴;䐙r;쀀𝔍pf;쀀𝕁ǣ߇\0ߌr;쀀𝒥rcy;䐈kcy;䐄HJacfosߤߨ߽߬߱ࠂࠈcy;䐥cy;䐌ppa;䎚Āey߶dil;䄶;䐚r;쀀𝔎pf;쀀𝕂cr;쀀𝒦րJTaceflmostࠥࠩࠬࡐࡣসে্ੇcy;䐉耻<䀼ʀcmnpr࠷࠼ࡁࡄࡍute;䄹bda;䎛g;柪lacetrf;愒r;憞ƀaeyࡗࡡron;䄽dil;䄻;䐛Āfsࡨ॰tԀACDFRTUVarࡾࢩࢱࣦ࣠ࣼयज़ΐ४ĀnrࢃgleBracket;柨rowƀ;BR࢙࢚࢞憐ar;懤ightArrow;懆eiling;挈oǵࢷ\0ࣃbleBracket;柦nǔࣈ\0࣒eeVector;楡ectorĀ;Bࣛࣜ懃ar;楙loor;挊ightĀAV࣯ࣵrrow;憔ector;楎Āerँगeƀ;AVउऊऐ抣rrow;憤ector;楚iangleƀ;BEतथऩ抲ar;槏qual;抴pƀDTVषूौownVector;楑eeVector;楠ectorĀ;Bॖॗ憿ar;楘ectorĀ;B॥०憼ar;楒ightáΜs̀EFGLSTॾঋকঝঢভqualGreater;拚ullEqual;扦reater;扶ess;檡lantEqual;橽ilde;扲r;쀀𝔏Ā;eঽা拘ftarrow;懚idot;䄿ƀnpwਖਛgȀLRlr৷ਂਐeftĀAR০৬rrow;柵ightArrow;柷ightArrow;柶eftĀarγਊightáοightáϊf;쀀𝕃erĀLRਢਬeftArrow;憙ightArrow;憘ƀchtਾੀੂòࡌ;憰rok;䅁;扪Ѐacefiosuਗ਼અઋp;椅y;䐜Ādl੯iumSpace;恟lintrf;愳r;쀀𝔐nusPlus;戓pf;쀀𝕄cò੶;䎜ҀJacefostuણધભીଔଙඑඞcy;䐊cute;䅃ƀaeyહાron;䅇dil;䅅;䐝ƀgswે૰ativeƀMTV૨ediumSpace;怋hiĀcn૦ëeryThiîtedĀGLଆreaterGreateòٳessLesóੈLine;䀊r;쀀𝔑ȀBnptଢନଷreak;恠BreakingSpace;䂠f;愕ڀ;CDEGHLNPRSTV୕ୖ୪௫ఄ಄ದൡඅ櫬Āoungruent;扢pCap;扭oubleVerticalBar;戦ƀlqxஃஊement;戉ualĀ;Tஒஓ扠ilde;쀀≂̸ists;戄reater;EFGLSTஶஷ扯qual;扱ullEqual;쀀≧̸reater;쀀≫̸ess;批lantEqual;쀀⩾̸ilde;扵umpń௲ownHump;쀀≎̸qual;쀀≏̸eĀfsఊధtTriangleƀ;BEచఛడ拪ar;쀀⧏̸qual;括s̀;EGLSTవశ఼ౄోౘ扮qual;扰reater;扸ess;쀀≪̸lantEqual;쀀⩽̸ilde;扴estedĀGL౨౹reaterGreater;쀀⪢̸essLess;쀀⪡̸recedesƀ;ESಒಓಛ技qual;쀀⪯̸lantEqual;拠ĀeiಫಹverseElement;戌ghtTriangleƀ;BEೋೌ拫ar;쀀⧐̸qual;拭ĀquೝഌuareSuĀbp೨setĀ;Eೳ쀀⊏̸qual;拢ersetĀ;Eഃആ쀀⊐̸qual;拣ƀbcpഓതൎsetĀ;Eഛഞ쀀⊂⃒qual;抈ceedsȀ;ESTലള഻െ抁qual;쀀⪰̸lantEqual;拡ilde;쀀≿̸ersetĀ;E൘൛쀀⊃⃒qual;抉ildeȀ;EFT൮൯൵ൿ扁qual;扄ullEqual;扇ilde;扉erticalBar;戤cr;쀀𝒩ilde耻Ñ䃑;䎝܀Eacdfgmoprstuvලෂෛ෧ขภยา฿ไlig;䅒cute耻Ó䃓Āiyීrc耻Ô䃔;䐞blac;䅐r;쀀𝔒rave耻Ò䃒ƀaei෮ෲcr;䅌ga;䎩cron;䎟pf;쀀𝕆enCurlyĀDQฎบoubleQuote;怜uote;怘;橔Āclวฬr;쀀𝒪ash耻Ø䃘iŬืde耻Õ䃕es;樷ml耻Ö䃖erĀBP๋Āar๐๓r;怾acĀek๚;揞et;掴arenthesis;揜ҀacfhilorsງຊຏຒດຝະrtialD;戂y;䐟r;쀀𝔓i;䎦;䎠usMinus;䂱Āipຢອncareplanåڝf;愙Ȁ;eio຺ູ檻cedesȀ;EST່້扺qual;檯lantEqual;扼ilde;找me;怳Ādpuct;戏ortionĀ;aȥl;戝Āci༁༆r;쀀𝒫;䎨ȀUfos༑༖༛༟OT耻"䀢r;쀀𝔔pf;愚cr;쀀𝒬BEacefhiorsu༾གྷཇའཱིྦྷྪྭ႖ႩႴႾarr;椐G耻®䂮ƀcnrཎནབute;䅔g;柫rĀ;tཛྷཝ憠l;椖ƀaeyཧཬཱron;䅘dil;䅖;䐠Ā;vླྀཹ愜erseĀEUྂྙĀlq྇ྎement;戋uilibrium;懋pEquilibrium;楯r»ཹo;䎡ghtЀACDFTUVa࿁ဢဨၛႇϘĀnr࿆࿒gleBracket;柩rowƀ;BL憒ar;懥eftArrow;懄eiling;按oǵ\0စbleBracket;柧nǔည\0နeeVector;楝ectorĀ;Bဝသ懂ar;楕loor;挋Āerိ၃eƀ;AVဵံြ抢rrow;憦ector;楛iangleƀ;BEၐၑၕ抳ar;槐qual;抵pƀDTVၣၮၸownVector;楏eeVector;楜ectorĀ;Bႂႃ憾ar;楔ectorĀ;B႑႒懀ar;楓Āpuႛ႞f;愝ndImplies;楰ightarrow;懛ĀchႹႼr;愛;憱leDelayed;槴ڀHOacfhimoqstuფჱჷჽᄙᄞᅑᅖᅡᅧᆵᆻᆿĀCcჩხHcy;䐩y;䐨FTcy;䐬cute;䅚ʀ;aeiyᄈᄉᄎᄓᄗ檼ron;䅠dil;䅞rc;䅜;䐡r;쀀𝔖ortȀDLRUᄪᄴᄾᅉownArrow»ОeftArrow»࢚ightArrow»pArrow;憑gma;䎣allCircle;战pf;쀀𝕊ɲᅭ\0\0ᅰt;戚areȀ;ISUᅻᅼᆉᆯ斡ntersection;抓uĀbpᆏᆞsetĀ;Eᆗᆘ抏qual;抑ersetĀ;Eᆨᆩ抐qual;抒nion;抔cr;쀀𝒮ar;拆ȀbcmpᇈᇛሉላĀ;sᇍᇎ拐etĀ;Eᇍᇕqual;抆ĀchᇠህeedsȀ;ESTᇭᇮᇴᇿ扻qual;檰lantEqual;扽ilde;承Tháྌ;我ƀ;esሒሓሣ拑rsetĀ;Eሜም抃qual;抇et»ሓրHRSacfhiorsሾቄቕቱቶኟዂወዑORN耻Þ䃞ADE;愢ĀHcቒcy;䐋y;䐦Ābuቚቜ;䀉;䎤ƀaeyብቪቯron;䅤dil;䅢;䐢r;쀀𝔗ĀeiቻDzኀ\0ኇefore;戴a;䎘ĀcnኘkSpace;쀀 Space;怉ldeȀ;EFTካኬኲኼ戼qual;扃ullEqual;扅ilde;扈pf;쀀𝕋ipleDot;惛Āctዖዛr;쀀𝒯rok;䅦ૡዷጎጚጦ\0ጬጱ\0\0\0\0\0ጸጽ፷ᎅ\0ᐄᐊᐐĀcrዻጁute耻Ú䃚rĀ;oጇገ憟cir;楉rǣጓ\0y;䐎ve;䅬Āiyጞጣrc耻Û䃛;䐣blac;䅰r;쀀𝔘rave耻Ù䃙acr;䅪Ādiፁ፩erĀBPፈ፝Āarፍፐr;䁟acĀekፗፙ;揟et;掵arenthesis;揝onĀ;P፰፱拃lus;抎Āgp፻on;䅲f;쀀𝕌ЀADETadps᎕ᎮᎸᏄϨᏒᏗᏳrrowƀ;BDᅐᎠᎤar;椒ownArrow;懅ownArrow;憕quilibrium;楮eeĀ;AᏋᏌ报rrow;憥ownáϳerĀLRᏞᏨeftArrow;憖ightArrow;憗iĀ;lᏹᏺ䏒on;䎥ing;䅮cr;쀀𝒰ilde;䅨ml耻Ü䃜ҀDbcdefosvᐧᐬᐰᐳᐾᒅᒊᒐᒖash;披ar;櫫y;䐒ashĀ;lᐻᐼ抩;櫦Āerᑃᑅ;拁ƀbtyᑌᑐᑺar;怖Ā;iᑏᑕcalȀBLSTᑡᑥᑪᑴar;戣ine;䁼eparator;杘ilde;所ThinSpace;怊r;쀀𝔙pf;쀀𝕍cr;쀀𝒱dash;抪ʀcefosᒧᒬᒱᒶᒼirc;䅴dge;拀r;쀀𝔚pf;쀀𝕎cr;쀀𝒲Ȁfiosᓋᓐᓒᓘr;쀀𝔛;䎞pf;쀀𝕏cr;쀀𝒳ҀAIUacfosuᓱᓵᓹᓽᔄᔏᔔᔚᔠcy;䐯cy;䐇cy;䐮cute耻Ý䃝Āiyᔉᔍrc;䅶;䐫r;쀀𝔜pf;쀀𝕐cr;쀀𝒴ml;䅸ЀHacdefosᔵᔹᔿᕋᕏᕝᕠᕤcy;䐖cute;䅹Āayᕄᕉron;䅽;䐗ot;䅻Dzᕔ\0ᕛoWidtèa;䎖r;愨pf;愤cr;쀀𝒵ᖃᖊᖐ\0ᖰᖶᖿ\0\0\0\0ᗆᗛᗫᙟ᙭\0ᚕ᚛ᚲᚹ\0ᚾcute耻á䃡reve;䄃̀;Ediuyᖜᖝᖡᖣᖨᖭ戾;쀀∾̳;房rc耻â䃢te肻´̆;䐰lig耻æ䃦Ā;r²ᖺ;쀀𝔞rave耻à䃠ĀepᗊᗖĀfpᗏᗔsym;愵èᗓha;䎱ĀapᗟcĀclᗤᗧr;䄁g;樿ɤᗰ\0\0ᘊʀ;adsvᗺᗻᗿᘁᘇ戧nd;橕;橜lope;橘;橚;elmrszᘘᘙᘛᘞᘿᙏᙙ戠;榤e»ᘙsdĀ;aᘥᘦ戡ѡᘰᘲᘴᘶᘸᘺᘼᘾ;榨;榩;榪;榫;榬;榭;榮;榯tĀ;vᙅᙆ戟bĀ;dᙌᙍ抾;榝Āptᙔᙗh;戢»¹arr;捼Āgpᙣᙧon;䄅f;쀀𝕒;Eaeiopᙻᙽᚂᚄᚇᚊ;橰cir;橯;扊d;手s;䀧roxĀ;eᚒñᚃing耻å䃥ƀctyᚡᚦᚨr;쀀𝒶;䀪mpĀ;eᚯñʈilde耻ã䃣ml耻ä䃤Āciᛂᛈoninôɲnt;樑ࠀNabcdefiklnoprsu᛭ᛱᜰᝃᝈ០៦ᠹᡐᜍ᥈ᥰot;櫭ĀcrᛶkȀcepsᜀᜅᜍᜓong;扌psilon;䏶rime;怵imĀ;e戽q;拍Ŷᜢᜦee;抽edĀ;gᜬᜭ挅e»ᜭrkĀ;tbrk;掶Āoyᜁᝁ;䐱quo;怞ʀcmprtᝓᝡᝤᝨausĀ;eĊĉptyv;榰séᜌnoõēƀahwᝯᝳ;䎲;愶een;扬r;쀀𝔟gcostuvwឍឝឳេ៕៛ƀaiuបពរðݠrc;旯p»፱ƀdptឤឨឭot;樀lus;樁imes;樂ɱឹ\0\0ើcup;樆ar;昅riangleĀdu៍្own;施p;斳plus;樄eåᑄåᒭarow;植ƀakoᠦᠵĀcn៲ᠣkƀlst֫᠂ozenge;槫riangleȀ;dlr᠒᠓᠘斴own;斾eft;旂ight;斸k;搣Ʊᠫ\0ᠳƲᠯ\0ᠱ;斒;斑4;斓ck;斈ĀeoᠾᡍĀ;qᡃᡆ쀀=⃥uiv;쀀≡⃥t;挐Ȁptwxᡙᡞᡧᡬf;쀀𝕓Ā;tᏋᡣom»Ꮜtie;拈DHUVbdhmptuvᢅᢖᢪᢻᣗᣛᣬᤅᤊᤐᤡȀLRlrᢎᢐᢒᢔ;敗;敔;敖;敓ʀ;DUduᢡᢢᢤᢦᢨ敐;敦;敩;敤;敧ȀLRlrᢳᢵᢷᢹ;敝;敚;敜;教;HLRhlrᣊᣋᣍᣏᣑᣓᣕ救;敬;散;敠;敫;敢;敟ox;槉ȀLRlrᣤᣦᣨᣪ;敕;敒;攐;攌ʀ;DUduڽ;敥;敨;攬;攴inus;抟lus;択imes;抠ȀLRlrᤙᤛᤝ;敛;敘;攘;攔;HLRhlrᤰᤱᤳᤵᤷ᤻᤹攂;敪;敡;敞;攼;攤;攜Āevģbar耻¦䂦Ȁceioᥑᥖᥚᥠr;쀀𝒷mi;恏mĀ;elƀ;bhᥨᥩᥫ䁜;槅sub;柈ŬᥴlĀ;e怢t»pƀ;Eeįᦅᦇ;檮Ā;qۜۛೡᦧ\0᧨ᨑᨕᨲ\0ᨷᩐ\0\0᪴\0\0᫁\0\0ᬡᬮ᭒\0᯽\0ᰌƀcprᦲute;䄇̀;abcdsᦿᧀᧄ᧕᧙戩nd;橄rcup;橉Āau᧒p;橋p;橇ot;橀;쀀∩︀Āeo᧢᧥t;恁îړȀaeiu᧰᧻ᨁᨅǰ᧵\0᧸s;橍on;䄍dil耻ç䃧rc;䄉psĀ;sᨌᨍ橌m;橐ot;䄋ƀdmnᨛᨠᨦil肻¸ƭptyv;榲t脀¢;eᨭᨮ䂢räƲr;쀀𝔠ƀceiᨽᩀᩍy;䑇ckĀ;mᩇᩈ朓ark»ᩈ;䏇r;Ecefms᩠ᩢᩫ᪤᪪旋;槃ƀ;elᩩᩪᩭ䋆q;扗eɡᩴ\0\0᪈rrowĀlr᩼᪁eft;憺ight;憻ʀRSacd᪒᪔᪖»ཇ;擈st;抛irc;抚ash;抝nint;樐id;櫯cir;槂ubsĀ;u᪻᪼晣it»᪼ˬ᫇\0ᬊonĀ;eᫍᫎ䀺Ā;qÇÆɭ\0\0aĀ;t䀬;䁀ƀ;fl戁îᅠeĀmxent»eóɍǧ\0ᬇĀ;dኻᬂot;橭nôɆƀfryᬐᬔᬗ;쀀𝕔oäɔ脀©;sŕᬝr;愗Āaoᬥᬩrr;憵ss;朗Ācuᬲᬷr;쀀𝒸Ābpᬼ᭄Ā;eᭁᭂ櫏;櫑Ā;eᭉᭊ櫐;櫒dot;拯delprvw᭠᭬᭷ᮂᮬᯔarrĀlr᭨᭪;椸;椵ɰ᭲\0\0᭵r;拞c;拟arrĀ;pᮀ憶;椽̀;bcdosᮏᮐᮖᮡᮥᮨ截rcap;橈Āauᮛᮞp;橆p;橊ot;抍r;橅;쀀∪︀Ȁalrv᮵ᮿᯞᯣrrĀ;mᮼᮽ憷;椼yƀevwᯇᯔᯘqɰᯎ\0\0ᯒreã᭳uã᭵ee;拎edge;拏en耻¤䂤earrowĀlrᯮ᯳eft»ᮀight»ᮽeäᯝĀciᰁᰇoninôǷnt;戱lcty;挭ঀAHabcdefhijlorstuwz᰻᰿ᱝᱩᱵᲞᲬᲷᴍᵻᶑᶫᶻ᷆᷍ròar;楥Ȁglrs᱈ᱍ᱒᱔ger;怠eth;愸òᄳhĀ;vᱚᱛ怐»ऊūᱡᱧarow;椏aã̕Āayᱮᱳron;䄏;䐴ƀ;ao̲ᱼᲄĀgrʿᲁr;懊tseq;橷ƀglmᲑᲔᲘ耻°䂰ta;䎴ptyv;榱ĀirᲣᲨsht;楿;쀀𝔡arĀlrᲳᲵ»ࣜ»သʀaegsv᳂᳖᳜᳠mƀ;oș᳔ndĀ;ș᳑uit;晦amma;䏝in;拲ƀ;io᳧᳨᳸䃷de脀÷;o᳧ᳰntimes;拇nø᳷cy;䑒cɯᴆ\0\0ᴊrn;挞op;挍ʀlptuwᴘᴝᴢᵉᵕlar;䀤f;쀀𝕕ʀ;emps̋ᴭᴷᴽᵂqĀ;d͒ᴳot;扑inus;戸lus;戔quare;抡blebarwedgåúnƀadhᄮᵝᵧownarrowóᲃarpoonĀlrᵲᵶefôᲴighôᲶŢᵿᶅkaro÷གɯᶊ\0\0ᶎrn;挟op;挌ƀcotᶘᶣᶦĀryᶝᶡ;쀀𝒹;䑕l;槶rok;䄑Ādrᶰᶴot;拱iĀ;fᶺ᠖斿Āah᷀᷃ròЩaòྦangle;榦Āci᷒ᷕy;䑟grarr;柿ऀDacdefglmnopqrstuxḁḉḙḸոḼṉṡṾấắẽỡἪἷὄĀDoḆᴴoôĀcsḎḔute耻é䃩ter;橮ȀaioyḢḧḱḶron;䄛rĀ;cḭḮ扖耻ê䃪lon;払;䑍ot;䄗ĀDrṁṅot;扒;쀀𝔢ƀ;rsṐṑṗ檚ave耻è䃨Ā;dṜṝ檖ot;檘Ȁ;ilsṪṫṲṴ檙nters;揧;愓Ā;dṹṺ檕ot;檗ƀapsẅẉẗcr;䄓tyƀ;svẒẓẕ戅et»ẓpĀ1;ẝẤijạả;怄;怅怃ĀgsẪẬ;䅋p;怂ĀgpẴẸon;䄙f;쀀𝕖ƀalsỄỎỒrĀ;sỊị拕l;槣us;橱iƀ;lvỚớở䎵on»ớ;䏵ȀcsuvỪỳἋἣĀioữḱrc»Ḯɩỹ\0\0ỻíՈantĀglἂἆtr»ṝess»ṺƀaeiἒἚls;䀽st;扟vĀ;DȵἠD;橸parsl;槥ĀDaἯἳot;打rr;楱ƀcdiἾὁỸr;愯oô͒ĀahὉὋ;䎷耻ð䃰Āmrὓὗl耻ë䃫o;悬ƀcipὡὤὧl;䀡sôծĀeoὬὴctatioîՙnentialåչৡᾒ\0ᾞ\0ᾡᾧ\0\0ῆῌ\0ΐ\0ῦῪ \0 ⁚llingdotseñṄy;䑄male;晀ƀilrᾭᾳ῁lig;耀ffiɩᾹ\0\0᾽g;耀ffig;耀ffl;쀀𝔣lig;耀filig;쀀fjƀaltῙῡt;晭ig;耀flns;斱of;䆒ǰ΅\0ῳf;쀀𝕗ĀakֿῷĀ;vῼ´拔;櫙artint;樍Āao⁕Ācs‑⁒ႉ‸⁅⁈\0⁐β•‥‧\0耻½䂽;慓耻¼䂼;慕;慙;慛Ƴ‴\0‶;慔;慖ʴ‾⁁\0\0⁃耻¾䂾;慗;慜5;慘ƶ⁌\0⁎;慚;慝8;慞l;恄wn;挢cr;쀀𝒻ࢀEabcdefgijlnorstv₂₉₥₰₴⃰℃ℒℸ̗ℾ⅒↞Ā;lٍ₇;檌ƀcmpₐₕute;䇵maĀ;dₜ᳚䎳;檆reve;䄟Āiy₪₮rc;䄝;䐳ot;䄡Ȁ;lqsؾق₽ƀ;qsؾٌlanô٥Ȁ;cdl٥⃒⃥⃕c;檩otĀ;o⃜⃝檀Ā;l⃢⃣檂;檄Ā;e⃪⃭쀀⋛︀s;檔r;쀀𝔤Ā;gٳ؛mel;愷cy;䑓Ȁ;Eajٚℌℎℐ;檒;檥;檤ȀEaesℛℝ℩ℴ;扩pĀ;p℣ℤ檊rox»ℤĀ;q℮ℯ檈Ā;q℮ℛim;拧pf;쀀𝕘Āci⅃ⅆr;愊mƀ;el٫ⅎ⅐;檎;檐茀>;cdlqrⅠⅪⅮⅳⅹĀciⅥⅧ;檧r;橺ot;拗Par;榕uest;橼ʀadelsↄⅪ←ٖ↛ǰ↉\0proør;楸qĀlqؿ↖lesó₈ií٫Āen↣↭rtneqq;쀀≩︀Å↪ԀAabcefkosy⇄⇇⇱⇵⇺∘∝∯≨≽ròΠȀilmr⇐⇔⇗⇛rsðᒄf»․ilôکĀdr⇠⇤cy;䑊ƀ;cwࣴ⇫⇯ir;楈;憭ar;意irc;䄥ƀalr∁∎∓rtsĀ;u∉∊晥it»∊lip;怦con;抹r;쀀𝔥sĀew∣∩arow;椥arow;椦ʀamopr∺∾≃≞≣rr;懿tht;戻kĀlr≉≓eftarrow;憩ightarrow;憪f;쀀𝕙bar;怕ƀclt≯≴≸r;쀀𝒽asè⇴rok;䄧Ābp⊂⊇ull;恃hen»ᱛૡ⊣\0⊪\0⊸⋅⋎\0⋕⋳\0\0⋸⌢⍧⍢⍿\0⎆⎪⎴cute耻í䃭ƀ;iyݱ⊰⊵rc耻î䃮;䐸Ācx⊼⊿y;䐵cl耻¡䂡ĀfrΟ⋉;쀀𝔦rave耻ì䃬Ȁ;inoܾ⋝⋩⋮Āin⋢⋦nt;樌t;戭fin;槜ta;愩lig;䄳ƀaop⋾⌚⌝ƀcgt⌅⌈⌗r;䄫ƀelpܟ⌏⌓inåގarôܠh;䄱f;抷ed;䆵ʀ;cfotӴ⌬⌱⌽⍁are;愅inĀ;t⌸⌹戞ie;槝doô⌙ʀ;celpݗ⍌⍐⍛⍡al;抺Āgr⍕⍙eróᕣã⍍arhk;樗rod;樼Ȁcgpt⍯⍲⍶⍻y;䑑on;䄯f;쀀𝕚a;䎹uest耻¿䂿Āci⎊⎏r;쀀𝒾nʀ;EdsvӴ⎛⎝⎡ӳ;拹ot;拵Ā;v⎦⎧拴;拳Ā;iݷ⎮lde;䄩ǫ⎸\0⎼cy;䑖l耻ï䃯̀cfmosu⏌⏗⏜⏡⏧⏵Āiy⏑⏕rc;䄵;䐹r;쀀𝔧ath;䈷pf;쀀𝕛ǣ⏬\0⏱r;쀀𝒿rcy;䑘kcy;䑔Ѐacfghjos␋␖␢ppaĀ;v␓␔䎺;䏰Āey␛␠dil;䄷;䐺r;쀀𝔨reen;䄸cy;䑅cy;䑜pf;쀀𝕜cr;쀀𝓀ABEHabcdefghjlmnoprstuv⑰⒁⒆⒍⒑┎┽╚▀♎♞♥♹♽⚚⚲⛘❝❨➋⟀⠁⠒ƀart⑷⑺⑼ròòΕail;椛arr;椎Ā;gঔ⒋;檋ar;楢ॣ⒥\0⒪\0⒱\0\0\0\0\0⒵Ⓔ\0ⓆⓈⓍ\0⓹ute;䄺mptyv;榴raîࡌbda;䎻gƀ;dlࢎⓁⓃ;榑åࢎ;檅uo耻«䂫rЀ;bfhlpst࢙ⓞⓦⓩ⓫⓮⓱⓵Ā;f࢝ⓣs;椟s;椝ë≒p;憫l;椹im;楳l;憢ƀ;ae⓿─┄檫il;椙Ā;s┉┊檭;쀀⪭︀ƀabr┕┙┝rr;椌rk;杲Āak┢┬cĀek┨┪;䁻;䁛Āes┱┳;榋lĀdu┹┻;榏;榍Ȁaeuy╆╋╖╘ron;䄾Ādi═╔il;䄼ìࢰâ┩;䐻Ȁcqrs╣╦╭╽a;椶uoĀ;rนᝆĀdu╲╷har;楧shar;楋h;憲ʀ;fgqs▋▌উ◳◿扤tʀahlrt▘▤▷◂◨rrowĀ;t࢙□aé⓶arpoonĀdu▯▴own»њp»०eftarrows;懇ightƀahs◍◖◞rrowĀ;sࣴࢧarpoonóquigarro÷⇰hreetimes;拋ƀ;qs▋ও◺lanôবʀ;cdgsব☊☍☝☨c;檨otĀ;o☔☕橿Ā;r☚☛檁;檃Ā;e☢☥쀀⋚︀s;檓ʀadegs☳☹☽♉♋pproøⓆot;拖qĀgq♃♅ôউgtò⒌ôছiíলƀilr♕࣡♚sht;楼;쀀𝔩Ā;Eজ♣;檑š♩♶rĀdu▲♮Ā;l॥♳;楪lk;斄cy;䑙ʀ;achtੈ⚈⚋⚑⚖rò◁orneòᴈard;楫ri;旺Āio⚟⚤dot;䅀ustĀ;a⚬⚭掰che»⚭ȀEaes⚻⚽⛉⛔;扨pĀ;p⛃⛄檉rox»⛄Ā;q⛎⛏檇Ā;q⛎⚻im;拦Ѐabnoptwz⛩⛴⛷✚✯❁❇❐Ānr⛮⛱g;柬r;懽rëࣁgƀlmr⛿✍✔eftĀar০✇ightá৲apsto;柼ightá৽parrowĀlr✥✩efô⓭ight;憬ƀafl✶✹✽r;榅;쀀𝕝us;樭imes;樴š❋❏st;戗áፎƀ;ef❗❘᠀旊nge»❘arĀ;l❤❥䀨t;榓ʀachmt❳❶❼➅➇ròࢨorneòᶌarĀ;d➃;業;怎ri;抿̀achiqt➘➝ੀ➢➮➻quo;怹r;쀀𝓁mƀ;egল➪➬;檍;檏Ābu┪➳oĀ;rฟ➹;怚rok;䅂萀<;cdhilqrࠫ⟒☹⟜⟠⟥⟪⟰Āci⟗⟙;檦r;橹reå◲mes;拉arr;楶uest;橻ĀPi⟵⟹ar;榖ƀ;ef⠀भ旃rĀdu⠇⠍shar;楊har;楦Āen⠗⠡rtneqq;쀀≨︀Å⠞܀Dacdefhilnopsu⡀⡅⢂⢎⢓⢠⢥⢨⣚⣢⣤ઃ⣳⤂Dot;戺Ȁclpr⡎⡒⡣⡽r耻¯䂯Āet⡗⡙;時Ā;e⡞⡟朠se»⡟Ā;sျ⡨toȀ;dluျ⡳⡷⡻owîҌefôएðᏑker;斮Āoy⢇⢌mma;権;䐼ash;怔asuredangle»ᘦr;쀀𝔪o;愧ƀcdn⢯⢴⣉ro耻µ䂵Ȁ;acdᑤ⢽⣀⣄sôᚧir;櫰ot肻·Ƶusƀ;bd⣒ᤃ⣓戒Ā;uᴼ⣘;横ţ⣞⣡p;櫛ò−ðઁĀdp⣩⣮els;抧f;쀀𝕞Āct⣸⣽r;쀀𝓂pos»ᖝƀ;lm⤉⤊⤍䎼timap;抸ఀGLRVabcdefghijlmoprstuvw⥂⥓⥾⦉⦘⧚⧩⨕⨚⩘⩝⪃⪕⪤⪨⬄⬇⭄⭿⮮ⰴⱧⱼ⳩Āgt⥇⥋;쀀⋙̸Ā;v⥐쀀≫⃒ƀelt⥚⥲⥶ftĀar⥡⥧rrow;懍ightarrow;懎;쀀⋘̸Ā;v⥻ే쀀≪⃒ightarrow;懏ĀDd⦎⦓ash;抯ash;抮ʀbcnpt⦣⦧⦬⦱⧌la»˞ute;䅄g;쀀∠⃒ʀ;Eiop⦼⧀⧅⧈;쀀⩰̸d;쀀≋̸s;䅉roøurĀ;a⧓⧔普lĀ;s⧓ସdz⧟\0⧣p肻 ଷmpĀ;e௹ఀʀaeouy⧴⧾⨃⨐⨓ǰ⧹\0⧻;橃on;䅈dil;䅆ngĀ;dൾ⨊ot;쀀⩭̸p;橂;䐽ash;怓;Aadqsxஒ⨩⨭⨻⩁⩅⩐rr;懗rĀhr⨳⨶k;椤Ā;oᏲᏰot;쀀≐̸uiöୣĀei⩊⩎ar;椨íistĀ;sடr;쀀𝔫ȀEest⩦⩹⩼ƀ;qs⩭ƀ;qs⩴lanôií௪Ā;rஶ⪁»ஷƀAap⪊⪍⪑rò⥱rr;憮ar;櫲ƀ;svྍ⪜ྌĀ;d⪡⪢拼;拺cy;䑚AEadest⪷⪺⪾⫂⫅⫶⫹rò⥦;쀀≦̸rr;憚r;急Ȁ;fqs⫎⫣⫯tĀar⫔⫙rro÷⫁ightarro÷⪐ƀ;qs⪺⫪lanôౕĀ;sౕ⫴»శiíౝĀ;rవ⫾iĀ;eచథiäඐĀpt⬌⬑f;쀀𝕟膀¬;in⬙⬚⬶䂬nȀ;Edvஉ⬤⬨⬮;쀀⋹̸ot;쀀⋵̸ǡஉ⬳⬵;拷;拶iĀ;vಸ⬼ǡಸ⭁⭃;拾;拽ƀaor⭋⭣⭩rȀ;ast⭕⭚⭟lleìl;쀀⫽⃥;쀀∂̸lint;樔ƀ;ceಒ⭰⭳uåಥĀ;cಘ⭸Ā;eಒ⭽ñಘȀAait⮈⮋⮝⮧rò⦈rrƀ;cw⮔⮕⮙憛;쀀⤳̸;쀀↝̸ghtarrow»⮕riĀ;eೋೖchimpqu⮽⯍⯙⬄⯤⯯Ȁ;cerല⯆ഷ⯉uå;쀀𝓃ortɭ⬅\0\0⯖ará⭖mĀ;e൮⯟Ā;q൴൳suĀbp⯫⯭ååഋƀbcp⯶ⰑⰙȀ;Ees⯿ⰀഢⰄ抄;쀀⫅̸etĀ;eഛⰋqĀ;qണⰀcĀ;eലⰗñസȀ;EesⰢⰣൟⰧ抅;쀀⫆̸etĀ;e൘ⰮqĀ;qൠⰣȀgilrⰽⰿⱅⱇìௗlde耻ñ䃱çృiangleĀlrⱒⱜeftĀ;eచⱚñదightĀ;eೋⱥñĀ;mⱬⱭ䎽ƀ;esⱴⱵⱹ䀣ro;愖p;怇ҀDHadgilrsⲏⲔⲙⲞⲣⲰⲶⳓⳣash;抭arr;椄p;쀀≍⃒ash;抬ĀetⲨⲬ;쀀≥⃒;쀀>⃒nfin;槞ƀAetⲽⳁⳅrr;椂;쀀≤⃒Ā;rⳊⳍ쀀<⃒ie;쀀⊴⃒ĀAtⳘⳜrr;椃rie;쀀⊵⃒im;쀀∼⃒ƀAan⳰ⴂrr;懖rĀhr⳺⳽k;椣Ā;oᏧᏥear;椧ቓ᪕\0\0\0\0\0\0\0\0\0\0\0\0\0ⴭ\0ⴸⵈⵠⵥⶄᬇ\0\0ⶍⶫ\0ⷈⷎ\0ⷜ⸙⸫⸾⹃Ācsⴱ᪗ute耻ó䃳ĀiyⴼⵅrĀ;cⵂ耻ô䃴;䐾ʀabios᪠ⵒⵗLjⵚlac;䅑v;樸old;榼lig;䅓Ācrir;榿;쀀𝔬ͯ\0\0\0ⶂn;䋛ave耻ò䃲;槁Ābmⶈ෴ar;榵Ȁacitⶕⶥⶨrò᪀Āirⶠr;榾oss;榻nå๒;槀ƀaeiⶱⶵⶹcr;䅍ga;䏉ƀcdnⷀⷅǍron;䎿;榶pf;쀀𝕠ƀaelⷔǒr;榷rp;榹;adiosvⷪⷫⷮ⸈⸍⸐⸖戨rò᪆Ȁ;efmⷷⷸ⸂⸅橝rĀ;oⷾⷿ愴f»ⷿ耻ª䂪耻º䂺gof;抶r;橖lope;橗;橛ƀclo⸟⸡⸧ò⸁ash耻ø䃸l;折iŬⸯ⸴de耻õ䃵esĀ;aǛ⸺s;樶ml耻ö䃶bar;挽ૡ\0\0⺀⺝\0⺢⺹\0\0⻋ຜ\0⼓\0\0⼫⾼\0⿈rȀ;astЃ脀¶;l䂶leìЃɩ\0\0m;櫳;櫽y;䐿rʀcimpt⺋⺏⺓ᡥ⺗nt;䀥od;䀮il;怰enk;怱r;쀀𝔭ƀimo⺨⺰⺴Ā;v⺭⺮䏆;䏕maô੶ne;明ƀ;tv⺿⻀⻈䏀chfork»´;䏖Āau⻏⻟nĀck⻕⻝kĀ;h⇴⻛;愎ö⇴sҀ;abcdemst⻳ᤈ⼄⼆⼊⼎䀫cir;樣ir;樢Āouᵀ⼂;樥;橲n肻±ຝim;樦wo;樧ƀipu⼙⼠⼥ntint;樕f;쀀𝕡nd耻£䂣Ԁ;Eaceinosu່⼿⽁⽄⽇⾁⾉⾒⽾⾶;檳p;檷uå໙Ā;c໎⽌̀;acens່⽙⽟⽦⽨⽾pproø⽃urlyeñ໙ñ໎ƀaes⽯⽶⽺pprox;檹qq;檵im;拨iíໟmeĀ;s⾈ຮ怲ƀEas⽸⾐⽺ð⽵ƀdfp⾙⾯ƀals⾠⾥⾪lar;挮ine;挒urf;挓Ā;t⾴ïrel;抰Āci⿀⿅r;쀀𝓅;䏈ncsp;怈̀fiopsu⋢⿱r;쀀𝔮pf;쀀𝕢rime;恗cr;쀀𝓆ƀaeo⿸〉〓tĀei々rnionóڰnt;樖stĀ;e【】䀿ñἙô༔ABHabcdefhilmnoprstuxけさすムㄎㄫㅇㅢㅲㆎ㈆㈕㈤㈩㉘㉮㉲㊐㊰㊷ƀartぇおがròႳòϝail;検aròᱥar;楤cdenqrtとふへみわゔヌĀeuねぱ;쀀∽̱te;䅕iãᅮmptyv;榳gȀ;del࿑らるろ;榒;榥å࿑uo耻»䂻rր;abcfhlpstwガクシスゼゾダッデナp;極Ā;fゴs;椠;椳s;椞ë≝ð✮l;楅im;楴l;憣;憝Āaiパフil;椚oĀ;nホボ戶aló༞ƀabrョリヮrò៥rk;杳ĀakンヽcĀekヹ・;䁽;䁝Āes;榌lĀduㄊㄌ;榎;榐Ȁaeuyㄗㄜㄧㄩron;䅙Ādiㄡㄥil;䅗ìâヺ;䑀Ȁclqsㄴㄷㄽㅄa;椷dhar;楩uoĀ;rȎȍh;憳ƀacgㅎㅟངlȀ;ipsླྀㅘㅛႜnåႻarôྩt;断ƀilrㅩဣㅮsht;楽;쀀𝔯ĀaoㅷㆆrĀduㅽㅿ»ѻĀ;l႑ㆄ;楬Ā;vㆋㆌ䏁;䏱ƀgns㆕ㇹㇼht̀ahlrstㆤㆰ㇂㇘rrowĀ;tㆭaéトarpoonĀduㆻㆿowîㅾp»႒eftĀah㇊㇐rrowóarpoonóՑightarrows;應quigarro÷ニhreetimes;拌g;䋚ingdotseñἲƀahm㈍㈐㈓ròaòՑ;怏oustĀ;a㈞掱che»mid;櫮Ȁabpt㈲㈽㉀㉒Ānr㈷㈺g;柭r;懾rëဃƀafl㉇㉊㉎r;榆;쀀𝕣us;樮imes;樵Āap㉝㉧rĀ;g㉣㉤䀩t;榔olint;樒arò㇣Ȁachq㉻㊀Ⴜ㊅quo;怺r;쀀𝓇Ābu・㊊oĀ;rȔȓƀhir㊗㊛㊠reåㇸmes;拊iȀ;efl㊪ၙᠡ㊫方tri;槎luhar;楨;愞ൡ㋕㋛㋟㌬㌸㍱\0㍺㎤\0\0㏬㏰\0㐨㑈㑚㒭㒱㓊㓱\0㘖\0\0㘳cute;䅛quï➺Ԁ;Eaceinpsyᇭ㋳㋵㋿㌂㌋㌏㌟㌦㌩;檴ǰ㋺\0㋼;檸on;䅡uåᇾĀ;dᇳ㌇il;䅟rc;䅝ƀEas㌖㌘㌛;檶p;檺im;择olint;樓iíሄ;䑁otƀ;be㌴ᵇ㌵担;橦Aacmstx㍆㍊㍗㍛㍞㍣㍭rr;懘rĀhr㍐㍒ë∨Ā;oਸ਼t耻§䂧i;䀻war;椩mĀin㍩ðnuóñt;朶rĀ;o㍶⁕쀀𝔰Ȁacoy㎂㎆㎑㎠rp;景Āhy㎋㎏cy;䑉;䑈rtɭ㎙\0\0㎜iäᑤaraì耻䂭Āgm㎨㎴maƀ;fv㎱㎲㎲䏃;䏂Ѐ;deglnprካ㏅㏉㏎㏖㏞㏡㏦ot;橪Ā;qኰĀ;E㏓㏔檞;檠Ā;E㏛㏜檝;檟e;扆lus;樤arr;楲aròᄽȀaeit㏸㐈㐏㐗Āls㏽㐄lsetmé㍪hp;樳parsl;槤Ādlᑣ㐔e;挣Ā;e㐜㐝檪Ā;s㐢㐣檬;쀀⪬︀ƀflp㐮㐳㑂tcy;䑌Ā;b㐸㐹䀯Ā;a㐾㐿槄r;挿f;쀀𝕤aĀdr㑍ЂesĀ;u㑔㑕晠it»㑕ƀcsu㑠㑹㒟Āau㑥㑯pĀ;sᆈ㑫;쀀⊓︀pĀ;sᆴ㑵;쀀⊔︀uĀbp㑿㒏ƀ;esᆗᆜ㒆etĀ;eᆗ㒍ñᆝƀ;esᆨᆭ㒖etĀ;eᆨ㒝ñᆮƀ;afᅻ㒦ְrť㒫ֱ»ᅼaròᅈȀcemt㒹㒾㓂㓅r;쀀𝓈tmîñiì㐕aræᆾĀar㓎㓕rĀ;f㓔ឿ昆Āan㓚㓭ightĀep㓣㓪psiloîỠhé⺯s»⡒ʀbcmnp㓻㕞ሉ㖋㖎Ҁ;Edemnprs㔎㔏㔑㔕㔞㔣㔬㔱㔶抂;櫅ot;檽Ā;dᇚ㔚ot;櫃ult;櫁ĀEe㔨㔪;櫋;把lus;檿arr;楹ƀeiu㔽㕒㕕tƀ;en㔎㕅㕋qĀ;qᇚ㔏eqĀ;q㔫㔨m;櫇Ābp㕚㕜;櫕;櫓c̀;acensᇭ㕬㕲㕹㕻㌦pproø㋺urlyeñᇾñᇳƀaes㖂㖈㌛pproø㌚qñ㌗g;晪ڀ123;Edehlmnps㖩㖬㖯ሜ㖲㖴㗀㗉㗕㗚㗟㗨㗭耻¹䂹耻²䂲耻³䂳;櫆Āos㖹㖼t;檾ub;櫘Ā;dሢ㗅ot;櫄sĀou㗏㗒l;柉b;櫗arr;楻ult;櫂ĀEe㗤㗦;櫌;抋lus;櫀ƀeiu㗴㘉㘌tƀ;enሜ㗼㘂qĀ;qሢ㖲eqĀ;q㗧㗤m;櫈Ābp㘑㘓;櫔;櫖ƀAan㘜㘠㘭rr;懙rĀhr㘦㘨ë∮Ā;oਫwar;椪lig耻ß䃟㙑㙝㙠ዎ㙳㙹\0㙾㛂\0\0\0\0\0㛛㜃\0㜉㝬\0\0\0㞇ɲ㙖\0\0㙛get;挖;䏄rëƀaey㙦㙫㙰ron;䅥dil;䅣;䑂lrec;挕r;쀀𝔱Ȁeiko㚆㚝㚵㚼Dz㚋\0㚑eĀ4fኄኁaƀ;sv㚘㚙㚛䎸ym;䏑Ācn㚢㚲kĀas㚨㚮pproøim»ኬsðኞĀas㚺㚮ðrn耻þ䃾Ǭ̟㛆⋧es膀×;bd㛏㛐㛘䃗Ā;aᤏ㛕r;樱;樰ƀeps㛡㛣㜀á⩍Ȁ;bcf҆㛬㛰㛴ot;挶ir;櫱Ā;o㛹㛼쀀𝕥rk;櫚á㍢rime;怴ƀaip㜏㜒㝤dåቈadempst㜡㝍㝀㝑㝗㝜㝟ngleʀ;dlqr㜰㜱㜶㝀㝂斵own»ᶻeftĀ;e⠀㜾ñम;扜ightĀ;e㊪㝋ñၚot;旬inus;樺lus;樹b;槍ime;樻ezium;揢ƀcht㝲㝽㞁Āry㝷㝻;쀀𝓉;䑆cy;䑛rok;䅧Āio㞋㞎xôheadĀlr㞗㞠eftarro÷ࡏightarrow»ཝऀAHabcdfghlmoprstuw㟐㟓㟗㟤㟰㟼㠎㠜㠣㠴㡑㡝㡫㢩㣌㣒㣪㣶ròϭar;楣Ācr㟜㟢ute耻ú䃺òᅐrǣ㟪\0㟭y;䑞ve;䅭Āiy㟵㟺rc耻û䃻;䑃ƀabh㠃㠆㠋ròᎭlac;䅱aòᏃĀir㠓㠘sht;楾;쀀𝔲rave耻ù䃹š㠧㠱rĀlr㠬㠮»ॗ»ႃlk;斀Āct㠹㡍ɯ㠿\0\0㡊rnĀ;e㡅㡆挜r»㡆op;挏ri;旸Āal㡖㡚cr;䅫肻¨͉Āgp㡢㡦on;䅳f;쀀𝕦̀adhlsuᅋ㡸㡽፲㢑㢠ownáᎳarpoonĀlr㢈㢌efô㠭ighô㠯iƀ;hl㢙㢚㢜䏅»ᏺon»㢚parrows;懈ƀcit㢰㣄㣈ɯ㢶\0\0㣁rnĀ;e㢼㢽挝r»㢽op;挎ng;䅯ri;旹cr;쀀𝓊ƀdir㣙㣝㣢ot;拰lde;䅩iĀ;f㜰㣨»᠓Āam㣯㣲rò㢨l耻ü䃼angle;榧ހABDacdeflnoprsz㤜㤟㤩㤭㦵㦸㦽㧟㧤㧨㧳㧹㧽㨁㨠ròϷarĀ;v㤦㤧櫨;櫩asèϡĀnr㤲㤷grt;榜eknprst㓣㥆㥋㥒㥝㥤㦖appá␕othinçẖƀhir㓫⻈㥙opô⾵Ā;hᎷ㥢ïㆍĀiu㥩㥭gmá㎳Ābp㥲㦄setneqĀ;q㥽㦀쀀⊊︀;쀀⫋︀setneqĀ;q㦏㦒쀀⊋︀;쀀⫌︀Āhr㦛㦟etá㚜iangleĀlr㦪㦯eft»थight»ၑy;䐲ash»ံƀelr㧄㧒㧗ƀ;beⷪ㧋㧏ar;抻q;扚lip;拮Ābt㧜ᑨaòᑩr;쀀𝔳tré㦮suĀbp㧯㧱»ജ»൙pf;쀀𝕧roðtré㦴Ācu㨆㨋r;쀀𝓋Ābp㨐㨘nĀEe㦀㨖»㥾nĀEe㦒㨞»㦐igzag;榚cefoprs㨶㨻㩖㩛㩔㩡㩪irc;䅵Ādi㩀㩑Ābg㩅㩉ar;機eĀ;qᗺ㩏;扙erp;愘r;쀀𝔴pf;쀀𝕨Ā;eᑹ㩦atèᑹcr;쀀𝓌ૣណ㪇\0㪋\0㪐㪛\0\0㪝㪨㪫㪯\0\0㫃㫎\0㫘ៜtré៑r;쀀𝔵ĀAa㪔㪗ròσrò৶;䎾ĀAa㪡㪤ròθrò৫að✓is;拻ƀdptឤ㪵㪾Āfl㪺ឩ;쀀𝕩imåឲĀAa㫇㫊ròώròਁĀcq㫒ីr;쀀𝓍Āpt៖㫜ré។Ѐacefiosu㫰㫽㬈㬌㬑㬕㬛㬡cĀuy㫶㫻te耻ý䃽;䑏Āiy㬂㬆rc;䅷;䑋n耻¥䂥r;쀀𝔶cy;䑗pf;쀀𝕪cr;쀀𝓎Ācm㬦㬩y;䑎l耻ÿ䃿Ԁacdefhiosw㭂㭈㭔㭘㭤㭩㭭㭴㭺㮀cute;䅺Āay㭍㭒ron;䅾;䐷ot;䅼Āet㭝㭡træᕟa;䎶r;쀀𝔷cy;䐶grarr;懝pf;쀀𝕫cr;쀀𝓏Ājn㮅㮇;怍j;怌'.split("").map(e=>e.charCodeAt(0))),O7=new Map([[0,65533],[128,8364],[130,8218],[131,402],[132,8222],[133,8230],[134,8224],[135,8225],[136,710],[137,8240],[138,352],[139,8249],[140,338],[142,381],[145,8216],[146,8217],[147,8220],[148,8221],[149,8226],[150,8211],[151,8212],[152,732],[153,8482],[154,353],[155,8250],[156,339],[158,382],[159,376]]);function N7(e){var t;return e>=55296&&e<=57343||e>1114111?65533:(t=O7.get(e))!==null&&t!==void 0?t:e}var vn;(function(e){e[e.NUM=35]="NUM",e[e.SEMI=59]="SEMI",e[e.EQUALS=61]="EQUALS",e[e.ZERO=48]="ZERO",e[e.NINE=57]="NINE",e[e.LOWER_A=97]="LOWER_A",e[e.LOWER_F=102]="LOWER_F",e[e.LOWER_X=120]="LOWER_X",e[e.LOWER_Z=122]="LOWER_Z",e[e.UPPER_A=65]="UPPER_A",e[e.UPPER_F=70]="UPPER_F",e[e.UPPER_Z=90]="UPPER_Z"})(vn||(vn={}));const k7=32;var Ta;(function(e){e[e.VALUE_LENGTH=49152]="VALUE_LENGTH",e[e.BRANCH_LENGTH=16256]="BRANCH_LENGTH",e[e.JUMP_TABLE=127]="JUMP_TABLE"})(Ta||(Ta={}));function S0(e){return e>=vn.ZERO&&e<=vn.NINE}function L7(e){return e>=vn.UPPER_A&&e<=vn.UPPER_F||e>=vn.LOWER_A&&e<=vn.LOWER_F}function M7(e){return e>=vn.UPPER_A&&e<=vn.UPPER_Z||e>=vn.LOWER_A&&e<=vn.LOWER_Z||S0(e)}function I7(e){return e===vn.EQUALS||M7(e)}var Dn;(function(e){e[e.EntityStart=0]="EntityStart",e[e.NumericStart=1]="NumericStart",e[e.NumericDecimal=2]="NumericDecimal",e[e.NumericHex=3]="NumericHex",e[e.NamedEntity=4]="NamedEntity"})(Dn||(Dn={}));var Bi;(function(e){e[e.Legacy=0]="Legacy",e[e.Strict=1]="Strict",e[e.Attribute=2]="Attribute"})(Bi||(Bi={}));class P7{constructor(t,n,i){this.decodeTree=t,this.emitCodePoint=n,this.errors=i,this.state=Dn.EntityStart,this.consumed=1,this.result=0,this.treeIndex=0,this.excess=1,this.decodeMode=Bi.Strict}startEntity(t){this.decodeMode=t,this.state=Dn.EntityStart,this.result=0,this.treeIndex=0,this.excess=1,this.consumed=1}write(t,n){switch(this.state){case Dn.EntityStart:return t.charCodeAt(n)===vn.NUM?(this.state=Dn.NumericStart,this.consumed+=1,this.stateNumericStart(t,n+1)):(this.state=Dn.NamedEntity,this.stateNamedEntity(t,n));case Dn.NumericStart:return this.stateNumericStart(t,n);case Dn.NumericDecimal:return this.stateNumericDecimal(t,n);case Dn.NumericHex:return this.stateNumericHex(t,n);case Dn.NamedEntity:return this.stateNamedEntity(t,n)}}stateNumericStart(t,n){return n>=t.length?-1:(t.charCodeAt(n)|k7)===vn.LOWER_X?(this.state=Dn.NumericHex,this.consumed+=1,this.stateNumericHex(t,n+1)):(this.state=Dn.NumericDecimal,this.stateNumericDecimal(t,n))}addToNumericResult(t,n,i,u){if(n!==i){const o=i-n;this.result=this.result*Math.pow(u,o)+Number.parseInt(t.substr(n,o),u),this.consumed+=o}}stateNumericHex(t,n){const i=n;for(;n<t.length;){const u=t.charCodeAt(n);if(S0(u)||L7(u))n+=1;else return this.addToNumericResult(t,i,n,16),this.emitNumericEntity(u,3)}return this.addToNumericResult(t,i,n,16),-1}stateNumericDecimal(t,n){const i=n;for(;n<t.length;){const u=t.charCodeAt(n);if(S0(u))n+=1;else return this.addToNumericResult(t,i,n,10),this.emitNumericEntity(u,2)}return this.addToNumericResult(t,i,n,10),-1}emitNumericEntity(t,n){var i;if(this.consumed<=n)return(i=this.errors)===null||i===void 0||i.absenceOfDigitsInNumericCharacterReference(this.consumed),0;if(t===vn.SEMI)this.consumed+=1;else if(this.decodeMode===Bi.Strict)return 0;return this.emitCodePoint(N7(this.result),this.consumed),this.errors&&(t!==vn.SEMI&&this.errors.missingSemicolonAfterCharacterReference(),this.errors.validateNumericCharacterReference(this.result)),this.consumed}stateNamedEntity(t,n){const{decodeTree:i}=this;let u=i[this.treeIndex],o=(u&Ta.VALUE_LENGTH)>>14;for(;n<t.length;n++,this.excess++){const l=t.charCodeAt(n);if(this.treeIndex=F7(i,u,this.treeIndex+Math.max(1,o),l),this.treeIndex<0)return this.result===0||this.decodeMode===Bi.Attribute&&(o===0||I7(l))?0:this.emitNotTerminatedNamedEntity();if(u=i[this.treeIndex],o=(u&Ta.VALUE_LENGTH)>>14,o!==0){if(l===vn.SEMI)return this.emitNamedEntityData(this.treeIndex,o,this.consumed+this.excess);this.decodeMode!==Bi.Strict&&(this.result=this.treeIndex,this.consumed+=this.excess,this.excess=0)}}return-1}emitNotTerminatedNamedEntity(){var t;const{result:n,decodeTree:i}=this,u=(i[n]&Ta.VALUE_LENGTH)>>14;return this.emitNamedEntityData(n,u,this.consumed),(t=this.errors)===null||t===void 0||t.missingSemicolonAfterCharacterReference(),this.consumed}emitNamedEntityData(t,n,i){const{decodeTree:u}=this;return this.emitCodePoint(n===1?u[t]&~Ta.VALUE_LENGTH:u[t+1],i),n===3&&this.emitCodePoint(u[t+2],i),i}end(){var t;switch(this.state){case Dn.NamedEntity:return this.result!==0&&(this.decodeMode!==Bi.Attribute||this.result===this.treeIndex)?this.emitNotTerminatedNamedEntity():0;case Dn.NumericDecimal:return this.emitNumericEntity(0,2);case Dn.NumericHex:return this.emitNumericEntity(0,3);case Dn.NumericStart:return(t=this.errors)===null||t===void 0||t.absenceOfDigitsInNumericCharacterReference(this.consumed),0;case Dn.EntityStart:return 0}}}function F7(e,t,n,i){const u=(t&Ta.BRANCH_LENGTH)>>7,o=t&Ta.JUMP_TABLE;if(u===0)return o!==0&&i===o?n:-1;if(o){const d=i-o;return d<0||d>=u?-1:e[n+d]-1}let l=n,f=l+u-1;for(;l<=f;){const d=l+f>>>1,h=e[d];if(h<i)l=d+1;else if(h>i)f=d-1;else return e[d+u]}return-1}var be;(function(e){e.HTML="http://www.w3.org/1999/xhtml",e.MATHML="http://www.w3.org/1998/Math/MathML",e.SVG="http://www.w3.org/2000/svg",e.XLINK="http://www.w3.org/1999/xlink",e.XML="http://www.w3.org/XML/1998/namespace",e.XMLNS="http://www.w3.org/2000/xmlns/"})(be||(be={}));var ou;(function(e){e.TYPE="type",e.ACTION="action",e.ENCODING="encoding",e.PROMPT="prompt",e.NAME="name",e.COLOR="color",e.FACE="face",e.SIZE="size"})(ou||(ou={}));var Fr;(function(e){e.NO_QUIRKS="no-quirks",e.QUIRKS="quirks",e.LIMITED_QUIRKS="limited-quirks"})(Fr||(Fr={}));var ie;(function(e){e.A="a",e.ADDRESS="address",e.ANNOTATION_XML="annotation-xml",e.APPLET="applet",e.AREA="area",e.ARTICLE="article",e.ASIDE="aside",e.B="b",e.BASE="base",e.BASEFONT="basefont",e.BGSOUND="bgsound",e.BIG="big",e.BLOCKQUOTE="blockquote",e.BODY="body",e.BR="br",e.BUTTON="button",e.CAPTION="caption",e.CENTER="center",e.CODE="code",e.COL="col",e.COLGROUP="colgroup",e.DD="dd",e.DESC="desc",e.DETAILS="details",e.DIALOG="dialog",e.DIR="dir",e.DIV="div",e.DL="dl",e.DT="dt",e.EM="em",e.EMBED="embed",e.FIELDSET="fieldset",e.FIGCAPTION="figcaption",e.FIGURE="figure",e.FONT="font",e.FOOTER="footer",e.FOREIGN_OBJECT="foreignObject",e.FORM="form",e.FRAME="frame",e.FRAMESET="frameset",e.H1="h1",e.H2="h2",e.H3="h3",e.H4="h4",e.H5="h5",e.H6="h6",e.HEAD="head",e.HEADER="header",e.HGROUP="hgroup",e.HR="hr",e.HTML="html",e.I="i",e.IMG="img",e.IMAGE="image",e.INPUT="input",e.IFRAME="iframe",e.KEYGEN="keygen",e.LABEL="label",e.LI="li",e.LINK="link",e.LISTING="listing",e.MAIN="main",e.MALIGNMARK="malignmark",e.MARQUEE="marquee",e.MATH="math",e.MENU="menu",e.META="meta",e.MGLYPH="mglyph",e.MI="mi",e.MO="mo",e.MN="mn",e.MS="ms",e.MTEXT="mtext",e.NAV="nav",e.NOBR="nobr",e.NOFRAMES="noframes",e.NOEMBED="noembed",e.NOSCRIPT="noscript",e.OBJECT="object",e.OL="ol",e.OPTGROUP="optgroup",e.OPTION="option",e.P="p",e.PARAM="param",e.PLAINTEXT="plaintext",e.PRE="pre",e.RB="rb",e.RP="rp",e.RT="rt",e.RTC="rtc",e.RUBY="ruby",e.S="s",e.SCRIPT="script",e.SEARCH="search",e.SECTION="section",e.SELECT="select",e.SOURCE="source",e.SMALL="small",e.SPAN="span",e.STRIKE="strike",e.STRONG="strong",e.STYLE="style",e.SUB="sub",e.SUMMARY="summary",e.SUP="sup",e.TABLE="table",e.TBODY="tbody",e.TEMPLATE="template",e.TEXTAREA="textarea",e.TFOOT="tfoot",e.TD="td",e.TH="th",e.THEAD="thead",e.TITLE="title",e.TR="tr",e.TRACK="track",e.TT="tt",e.U="u",e.UL="ul",e.SVG="svg",e.VAR="var",e.WBR="wbr",e.XMP="xmp"})(ie||(ie={}));var y;(function(e){e[e.UNKNOWN=0]="UNKNOWN",e[e.A=1]="A",e[e.ADDRESS=2]="ADDRESS",e[e.ANNOTATION_XML=3]="ANNOTATION_XML",e[e.APPLET=4]="APPLET",e[e.AREA=5]="AREA",e[e.ARTICLE=6]="ARTICLE",e[e.ASIDE=7]="ASIDE",e[e.B=8]="B",e[e.BASE=9]="BASE",e[e.BASEFONT=10]="BASEFONT",e[e.BGSOUND=11]="BGSOUND",e[e.BIG=12]="BIG",e[e.BLOCKQUOTE=13]="BLOCKQUOTE",e[e.BODY=14]="BODY",e[e.BR=15]="BR",e[e.BUTTON=16]="BUTTON",e[e.CAPTION=17]="CAPTION",e[e.CENTER=18]="CENTER",e[e.CODE=19]="CODE",e[e.COL=20]="COL",e[e.COLGROUP=21]="COLGROUP",e[e.DD=22]="DD",e[e.DESC=23]="DESC",e[e.DETAILS=24]="DETAILS",e[e.DIALOG=25]="DIALOG",e[e.DIR=26]="DIR",e[e.DIV=27]="DIV",e[e.DL=28]="DL",e[e.DT=29]="DT",e[e.EM=30]="EM",e[e.EMBED=31]="EMBED",e[e.FIELDSET=32]="FIELDSET",e[e.FIGCAPTION=33]="FIGCAPTION",e[e.FIGURE=34]="FIGURE",e[e.FONT=35]="FONT",e[e.FOOTER=36]="FOOTER",e[e.FOREIGN_OBJECT=37]="FOREIGN_OBJECT",e[e.FORM=38]="FORM",e[e.FRAME=39]="FRAME",e[e.FRAMESET=40]="FRAMESET",e[e.H1=41]="H1",e[e.H2=42]="H2",e[e.H3=43]="H3",e[e.H4=44]="H4",e[e.H5=45]="H5",e[e.H6=46]="H6",e[e.HEAD=47]="HEAD",e[e.HEADER=48]="HEADER",e[e.HGROUP=49]="HGROUP",e[e.HR=50]="HR",e[e.HTML=51]="HTML",e[e.I=52]="I",e[e.IMG=53]="IMG",e[e.IMAGE=54]="IMAGE",e[e.INPUT=55]="INPUT",e[e.IFRAME=56]="IFRAME",e[e.KEYGEN=57]="KEYGEN",e[e.LABEL=58]="LABEL",e[e.LI=59]="LI",e[e.LINK=60]="LINK",e[e.LISTING=61]="LISTING",e[e.MAIN=62]="MAIN",e[e.MALIGNMARK=63]="MALIGNMARK",e[e.MARQUEE=64]="MARQUEE",e[e.MATH=65]="MATH",e[e.MENU=66]="MENU",e[e.META=67]="META",e[e.MGLYPH=68]="MGLYPH",e[e.MI=69]="MI",e[e.MO=70]="MO",e[e.MN=71]="MN",e[e.MS=72]="MS",e[e.MTEXT=73]="MTEXT",e[e.NAV=74]="NAV",e[e.NOBR=75]="NOBR",e[e.NOFRAMES=76]="NOFRAMES",e[e.NOEMBED=77]="NOEMBED",e[e.NOSCRIPT=78]="NOSCRIPT",e[e.OBJECT=79]="OBJECT",e[e.OL=80]="OL",e[e.OPTGROUP=81]="OPTGROUP",e[e.OPTION=82]="OPTION",e[e.P=83]="P",e[e.PARAM=84]="PARAM",e[e.PLAINTEXT=85]="PLAINTEXT",e[e.PRE=86]="PRE",e[e.RB=87]="RB",e[e.RP=88]="RP",e[e.RT=89]="RT",e[e.RTC=90]="RTC",e[e.RUBY=91]="RUBY",e[e.S=92]="S",e[e.SCRIPT=93]="SCRIPT",e[e.SEARCH=94]="SEARCH",e[e.SECTION=95]="SECTION",e[e.SELECT=96]="SELECT",e[e.SOURCE=97]="SOURCE",e[e.SMALL=98]="SMALL",e[e.SPAN=99]="SPAN",e[e.STRIKE=100]="STRIKE",e[e.STRONG=101]="STRONG",e[e.STYLE=102]="STYLE",e[e.SUB=103]="SUB",e[e.SUMMARY=104]="SUMMARY",e[e.SUP=105]="SUP",e[e.TABLE=106]="TABLE",e[e.TBODY=107]="TBODY",e[e.TEMPLATE=108]="TEMPLATE",e[e.TEXTAREA=109]="TEXTAREA",e[e.TFOOT=110]="TFOOT",e[e.TD=111]="TD",e[e.TH=112]="TH",e[e.THEAD=113]="THEAD",e[e.TITLE=114]="TITLE",e[e.TR=115]="TR",e[e.TRACK=116]="TRACK",e[e.TT=117]="TT",e[e.U=118]="U",e[e.UL=119]="UL",e[e.SVG=120]="SVG",e[e.VAR=121]="VAR",e[e.WBR=122]="WBR",e[e.XMP=123]="XMP"})(y||(y={}));const B7=new Map([[ie.A,y.A],[ie.ADDRESS,y.ADDRESS],[ie.ANNOTATION_XML,y.ANNOTATION_XML],[ie.APPLET,y.APPLET],[ie.AREA,y.AREA],[ie.ARTICLE,y.ARTICLE],[ie.ASIDE,y.ASIDE],[ie.B,y.B],[ie.BASE,y.BASE],[ie.BASEFONT,y.BASEFONT],[ie.BGSOUND,y.BGSOUND],[ie.BIG,y.BIG],[ie.BLOCKQUOTE,y.BLOCKQUOTE],[ie.BODY,y.BODY],[ie.BR,y.BR],[ie.BUTTON,y.BUTTON],[ie.CAPTION,y.CAPTION],[ie.CENTER,y.CENTER],[ie.CODE,y.CODE],[ie.COL,y.COL],[ie.COLGROUP,y.COLGROUP],[ie.DD,y.DD],[ie.DESC,y.DESC],[ie.DETAILS,y.DETAILS],[ie.DIALOG,y.DIALOG],[ie.DIR,y.DIR],[ie.DIV,y.DIV],[ie.DL,y.DL],[ie.DT,y.DT],[ie.EM,y.EM],[ie.EMBED,y.EMBED],[ie.FIELDSET,y.FIELDSET],[ie.FIGCAPTION,y.FIGCAPTION],[ie.FIGURE,y.FIGURE],[ie.FONT,y.FONT],[ie.FOOTER,y.FOOTER],[ie.FOREIGN_OBJECT,y.FOREIGN_OBJECT],[ie.FORM,y.FORM],[ie.FRAME,y.FRAME],[ie.FRAMESET,y.FRAMESET],[ie.H1,y.H1],[ie.H2,y.H2],[ie.H3,y.H3],[ie.H4,y.H4],[ie.H5,y.H5],[ie.H6,y.H6],[ie.HEAD,y.HEAD],[ie.HEADER,y.HEADER],[ie.HGROUP,y.HGROUP],[ie.HR,y.HR],[ie.HTML,y.HTML],[ie.I,y.I],[ie.IMG,y.IMG],[ie.IMAGE,y.IMAGE],[ie.INPUT,y.INPUT],[ie.IFRAME,y.IFRAME],[ie.KEYGEN,y.KEYGEN],[ie.LABEL,y.LABEL],[ie.LI,y.LI],[ie.LINK,y.LINK],[ie.LISTING,y.LISTING],[ie.MAIN,y.MAIN],[ie.MALIGNMARK,y.MALIGNMARK],[ie.MARQUEE,y.MARQUEE],[ie.MATH,y.MATH],[ie.MENU,y.MENU],[ie.META,y.META],[ie.MGLYPH,y.MGLYPH],[ie.MI,y.MI],[ie.MO,y.MO],[ie.MN,y.MN],[ie.MS,y.MS],[ie.MTEXT,y.MTEXT],[ie.NAV,y.NAV],[ie.NOBR,y.NOBR],[ie.NOFRAMES,y.NOFRAMES],[ie.NOEMBED,y.NOEMBED],[ie.NOSCRIPT,y.NOSCRIPT],[ie.OBJECT,y.OBJECT],[ie.OL,y.OL],[ie.OPTGROUP,y.OPTGROUP],[ie.OPTION,y.OPTION],[ie.P,y.P],[ie.PARAM,y.PARAM],[ie.PLAINTEXT,y.PLAINTEXT],[ie.PRE,y.PRE],[ie.RB,y.RB],[ie.RP,y.RP],[ie.RT,y.RT],[ie.RTC,y.RTC],[ie.RUBY,y.RUBY],[ie.S,y.S],[ie.SCRIPT,y.SCRIPT],[ie.SEARCH,y.SEARCH],[ie.SECTION,y.SECTION],[ie.SELECT,y.SELECT],[ie.SOURCE,y.SOURCE],[ie.SMALL,y.SMALL],[ie.SPAN,y.SPAN],[ie.STRIKE,y.STRIKE],[ie.STRONG,y.STRONG],[ie.STYLE,y.STYLE],[ie.SUB,y.SUB],[ie.SUMMARY,y.SUMMARY],[ie.SUP,y.SUP],[ie.TABLE,y.TABLE],[ie.TBODY,y.TBODY],[ie.TEMPLATE,y.TEMPLATE],[ie.TEXTAREA,y.TEXTAREA],[ie.TFOOT,y.TFOOT],[ie.TD,y.TD],[ie.TH,y.TH],[ie.THEAD,y.THEAD],[ie.TITLE,y.TITLE],[ie.TR,y.TR],[ie.TRACK,y.TRACK],[ie.TT,y.TT],[ie.U,y.U],[ie.UL,y.UL],[ie.SVG,y.SVG],[ie.VAR,y.VAR],[ie.WBR,y.WBR],[ie.XMP,y.XMP]]);function _s(e){var t;return(t=B7.get(e))!==null&&t!==void 0?t:y.UNKNOWN}const Ae=y,U7={[be.HTML]:new Set([Ae.ADDRESS,Ae.APPLET,Ae.AREA,Ae.ARTICLE,Ae.ASIDE,Ae.BASE,Ae.BASEFONT,Ae.BGSOUND,Ae.BLOCKQUOTE,Ae.BODY,Ae.BR,Ae.BUTTON,Ae.CAPTION,Ae.CENTER,Ae.COL,Ae.COLGROUP,Ae.DD,Ae.DETAILS,Ae.DIR,Ae.DIV,Ae.DL,Ae.DT,Ae.EMBED,Ae.FIELDSET,Ae.FIGCAPTION,Ae.FIGURE,Ae.FOOTER,Ae.FORM,Ae.FRAME,Ae.FRAMESET,Ae.H1,Ae.H2,Ae.H3,Ae.H4,Ae.H5,Ae.H6,Ae.HEAD,Ae.HEADER,Ae.HGROUP,Ae.HR,Ae.HTML,Ae.IFRAME,Ae.IMG,Ae.INPUT,Ae.LI,Ae.LINK,Ae.LISTING,Ae.MAIN,Ae.MARQUEE,Ae.MENU,Ae.META,Ae.NAV,Ae.NOEMBED,Ae.NOFRAMES,Ae.NOSCRIPT,Ae.OBJECT,Ae.OL,Ae.P,Ae.PARAM,Ae.PLAINTEXT,Ae.PRE,Ae.SCRIPT,Ae.SECTION,Ae.SELECT,Ae.SOURCE,Ae.STYLE,Ae.SUMMARY,Ae.TABLE,Ae.TBODY,Ae.TD,Ae.TEMPLATE,Ae.TEXTAREA,Ae.TFOOT,Ae.TH,Ae.THEAD,Ae.TITLE,Ae.TR,Ae.TRACK,Ae.UL,Ae.WBR,Ae.XMP]),[be.MATHML]:new Set([Ae.MI,Ae.MO,Ae.MN,Ae.MS,Ae.MTEXT,Ae.ANNOTATION_XML]),[be.SVG]:new Set([Ae.TITLE,Ae.FOREIGN_OBJECT,Ae.DESC]),[be.XLINK]:new Set,[be.XML]:new Set,[be.XMLNS]:new Set},D0=new Set([Ae.H1,Ae.H2,Ae.H3,Ae.H4,Ae.H5,Ae.H6]);ie.STYLE,ie.SCRIPT,ie.XMP,ie.IFRAME,ie.NOEMBED,ie.NOFRAMES,ie.PLAINTEXT;var I;(function(e){e[e.DATA=0]="DATA",e[e.RCDATA=1]="RCDATA",e[e.RAWTEXT=2]="RAWTEXT",e[e.SCRIPT_DATA=3]="SCRIPT_DATA",e[e.PLAINTEXT=4]="PLAINTEXT",e[e.TAG_OPEN=5]="TAG_OPEN",e[e.END_TAG_OPEN=6]="END_TAG_OPEN",e[e.TAG_NAME=7]="TAG_NAME",e[e.RCDATA_LESS_THAN_SIGN=8]="RCDATA_LESS_THAN_SIGN",e[e.RCDATA_END_TAG_OPEN=9]="RCDATA_END_TAG_OPEN",e[e.RCDATA_END_TAG_NAME=10]="RCDATA_END_TAG_NAME",e[e.RAWTEXT_LESS_THAN_SIGN=11]="RAWTEXT_LESS_THAN_SIGN",e[e.RAWTEXT_END_TAG_OPEN=12]="RAWTEXT_END_TAG_OPEN",e[e.RAWTEXT_END_TAG_NAME=13]="RAWTEXT_END_TAG_NAME",e[e.SCRIPT_DATA_LESS_THAN_SIGN=14]="SCRIPT_DATA_LESS_THAN_SIGN",e[e.SCRIPT_DATA_END_TAG_OPEN=15]="SCRIPT_DATA_END_TAG_OPEN",e[e.SCRIPT_DATA_END_TAG_NAME=16]="SCRIPT_DATA_END_TAG_NAME",e[e.SCRIPT_DATA_ESCAPE_START=17]="SCRIPT_DATA_ESCAPE_START",e[e.SCRIPT_DATA_ESCAPE_START_DASH=18]="SCRIPT_DATA_ESCAPE_START_DASH",e[e.SCRIPT_DATA_ESCAPED=19]="SCRIPT_DATA_ESCAPED",e[e.SCRIPT_DATA_ESCAPED_DASH=20]="SCRIPT_DATA_ESCAPED_DASH",e[e.SCRIPT_DATA_ESCAPED_DASH_DASH=21]="SCRIPT_DATA_ESCAPED_DASH_DASH",e[e.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN=22]="SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN",e[e.SCRIPT_DATA_ESCAPED_END_TAG_OPEN=23]="SCRIPT_DATA_ESCAPED_END_TAG_OPEN",e[e.SCRIPT_DATA_ESCAPED_END_TAG_NAME=24]="SCRIPT_DATA_ESCAPED_END_TAG_NAME",e[e.SCRIPT_DATA_DOUBLE_ESCAPE_START=25]="SCRIPT_DATA_DOUBLE_ESCAPE_START",e[e.SCRIPT_DATA_DOUBLE_ESCAPED=26]="SCRIPT_DATA_DOUBLE_ESCAPED",e[e.SCRIPT_DATA_DOUBLE_ESCAPED_DASH=27]="SCRIPT_DATA_DOUBLE_ESCAPED_DASH",e[e.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH=28]="SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH",e[e.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN=29]="SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN",e[e.SCRIPT_DATA_DOUBLE_ESCAPE_END=30]="SCRIPT_DATA_DOUBLE_ESCAPE_END",e[e.BEFORE_ATTRIBUTE_NAME=31]="BEFORE_ATTRIBUTE_NAME",e[e.ATTRIBUTE_NAME=32]="ATTRIBUTE_NAME",e[e.AFTER_ATTRIBUTE_NAME=33]="AFTER_ATTRIBUTE_NAME",e[e.BEFORE_ATTRIBUTE_VALUE=34]="BEFORE_ATTRIBUTE_VALUE",e[e.ATTRIBUTE_VALUE_DOUBLE_QUOTED=35]="ATTRIBUTE_VALUE_DOUBLE_QUOTED",e[e.ATTRIBUTE_VALUE_SINGLE_QUOTED=36]="ATTRIBUTE_VALUE_SINGLE_QUOTED",e[e.ATTRIBUTE_VALUE_UNQUOTED=37]="ATTRIBUTE_VALUE_UNQUOTED",e[e.AFTER_ATTRIBUTE_VALUE_QUOTED=38]="AFTER_ATTRIBUTE_VALUE_QUOTED",e[e.SELF_CLOSING_START_TAG=39]="SELF_CLOSING_START_TAG",e[e.BOGUS_COMMENT=40]="BOGUS_COMMENT",e[e.MARKUP_DECLARATION_OPEN=41]="MARKUP_DECLARATION_OPEN",e[e.COMMENT_START=42]="COMMENT_START",e[e.COMMENT_START_DASH=43]="COMMENT_START_DASH",e[e.COMMENT=44]="COMMENT",e[e.COMMENT_LESS_THAN_SIGN=45]="COMMENT_LESS_THAN_SIGN",e[e.COMMENT_LESS_THAN_SIGN_BANG=46]="COMMENT_LESS_THAN_SIGN_BANG",e[e.COMMENT_LESS_THAN_SIGN_BANG_DASH=47]="COMMENT_LESS_THAN_SIGN_BANG_DASH",e[e.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH=48]="COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH",e[e.COMMENT_END_DASH=49]="COMMENT_END_DASH",e[e.COMMENT_END=50]="COMMENT_END",e[e.COMMENT_END_BANG=51]="COMMENT_END_BANG",e[e.DOCTYPE=52]="DOCTYPE",e[e.BEFORE_DOCTYPE_NAME=53]="BEFORE_DOCTYPE_NAME",e[e.DOCTYPE_NAME=54]="DOCTYPE_NAME",e[e.AFTER_DOCTYPE_NAME=55]="AFTER_DOCTYPE_NAME",e[e.AFTER_DOCTYPE_PUBLIC_KEYWORD=56]="AFTER_DOCTYPE_PUBLIC_KEYWORD",e[e.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER=57]="BEFORE_DOCTYPE_PUBLIC_IDENTIFIER",e[e.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED=58]="DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED",e[e.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED=59]="DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED",e[e.AFTER_DOCTYPE_PUBLIC_IDENTIFIER=60]="AFTER_DOCTYPE_PUBLIC_IDENTIFIER",e[e.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS=61]="BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS",e[e.AFTER_DOCTYPE_SYSTEM_KEYWORD=62]="AFTER_DOCTYPE_SYSTEM_KEYWORD",e[e.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER=63]="BEFORE_DOCTYPE_SYSTEM_IDENTIFIER",e[e.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED=64]="DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED",e[e.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED=65]="DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED",e[e.AFTER_DOCTYPE_SYSTEM_IDENTIFIER=66]="AFTER_DOCTYPE_SYSTEM_IDENTIFIER",e[e.BOGUS_DOCTYPE=67]="BOGUS_DOCTYPE",e[e.CDATA_SECTION=68]="CDATA_SECTION",e[e.CDATA_SECTION_BRACKET=69]="CDATA_SECTION_BRACKET",e[e.CDATA_SECTION_END=70]="CDATA_SECTION_END",e[e.CHARACTER_REFERENCE=71]="CHARACTER_REFERENCE",e[e.AMBIGUOUS_AMPERSAND=72]="AMBIGUOUS_AMPERSAND"})(I||(I={}));const sn={DATA:I.DATA,RCDATA:I.RCDATA,RAWTEXT:I.RAWTEXT,SCRIPT_DATA:I.SCRIPT_DATA,PLAINTEXT:I.PLAINTEXT,CDATA_SECTION:I.CDATA_SECTION};function H7(e){return e>=k.DIGIT_0&&e<=k.DIGIT_9}function el(e){return e>=k.LATIN_CAPITAL_A&&e<=k.LATIN_CAPITAL_Z}function z7(e){return e>=k.LATIN_SMALL_A&&e<=k.LATIN_SMALL_Z}function ga(e){return z7(e)||el(e)}function $S(e){return ga(e)||H7(e)}function pf(e){return e+32}function w_(e){return e===k.SPACE||e===k.LINE_FEED||e===k.TABULATION||e===k.FORM_FEED}function ZS(e){return w_(e)||e===k.SOLIDUS||e===k.GREATER_THAN_SIGN}function V7(e){return e===k.NULL?fe.nullCharacterReference:e>1114111?fe.characterReferenceOutsideUnicodeRange:C_(e)?fe.surrogateCharacterReference:x_(e)?fe.noncharacterCharacterReference:__(e)||e===k.CARRIAGE_RETURN?fe.controlCharacterReference:null}class j7{constructor(t,n){this.options=t,this.handler=n,this.paused=!1,this.inLoop=!1,this.inForeignNode=!1,this.lastStartTagName="",this.active=!1,this.state=I.DATA,this.returnState=I.DATA,this.entityStartPos=0,this.consumedAfterSnapshot=-1,this.currentCharacterToken=null,this.currentToken=null,this.currentAttr={name:"",value:""},this.preprocessor=new R7(n),this.currentLocation=this.getCurrentLocation(-1),this.entityDecoder=new P7(w7,(i,u)=>{this.preprocessor.pos=this.entityStartPos+u-1,this._flushCodePointConsumedAsCharacterReference(i)},n.onParseError?{missingSemicolonAfterCharacterReference:()=>{this._err(fe.missingSemicolonAfterCharacterReference,1)},absenceOfDigitsInNumericCharacterReference:i=>{this._err(fe.absenceOfDigitsInNumericCharacterReference,this.entityStartPos-this.preprocessor.pos+i)},validateNumericCharacterReference:i=>{const u=V7(i);u&&this._err(u,1)}}:void 0)}_err(t,n=0){var i,u;(u=(i=this.handler).onParseError)===null||u===void 0||u.call(i,this.preprocessor.getError(t,n))}getCurrentLocation(t){return this.options.sourceCodeLocationInfo?{startLine:this.preprocessor.line,startCol:this.preprocessor.col-t,startOffset:this.preprocessor.offset-t,endLine:-1,endCol:-1,endOffset:-1}:null}_runParsingLoop(){if(!this.inLoop){for(this.inLoop=!0;this.active&&!this.paused;){this.consumedAfterSnapshot=0;const t=this._consume();this._ensureHibernation()||this._callState(t)}this.inLoop=!1}}pause(){this.paused=!0}resume(t){if(!this.paused)throw new Error("Parser was already resumed");this.paused=!1,!this.inLoop&&(this._runParsingLoop(),this.paused||t?.())}write(t,n,i){this.active=!0,this.preprocessor.write(t,n),this._runParsingLoop(),this.paused||i?.()}insertHtmlAtCurrentPos(t){this.active=!0,this.preprocessor.insertHtmlAtCurrentPos(t),this._runParsingLoop()}_ensureHibernation(){return this.preprocessor.endOfChunkHit?(this.preprocessor.retreat(this.consumedAfterSnapshot),this.consumedAfterSnapshot=0,this.active=!1,!0):!1}_consume(){return this.consumedAfterSnapshot++,this.preprocessor.advance()}_advanceBy(t){this.consumedAfterSnapshot+=t;for(let n=0;n<t;n++)this.preprocessor.advance()}_consumeSequenceIfMatch(t,n){return this.preprocessor.startsWith(t,n)?(this._advanceBy(t.length-1),!0):!1}_createStartTagToken(){this.currentToken={type:st.START_TAG,tagName:"",tagID:y.UNKNOWN,selfClosing:!1,ackSelfClosing:!1,attrs:[],location:this.getCurrentLocation(1)}}_createEndTagToken(){this.currentToken={type:st.END_TAG,tagName:"",tagID:y.UNKNOWN,selfClosing:!1,ackSelfClosing:!1,attrs:[],location:this.getCurrentLocation(2)}}_createCommentToken(t){this.currentToken={type:st.COMMENT,data:"",location:this.getCurrentLocation(t)}}_createDoctypeToken(t){this.currentToken={type:st.DOCTYPE,name:t,forceQuirks:!1,publicId:null,systemId:null,location:this.currentLocation}}_createCharacterToken(t,n){this.currentCharacterToken={type:t,chars:n,location:this.currentLocation}}_createAttr(t){this.currentAttr={name:t,value:""},this.currentLocation=this.getCurrentLocation(0)}_leaveAttrName(){var t,n;const i=this.currentToken;if(R_(i,this.currentAttr.name)===null){if(i.attrs.push(this.currentAttr),i.location&&this.currentLocation){const u=(t=(n=i.location).attrs)!==null&&t!==void 0?t:n.attrs=Object.create(null);u[this.currentAttr.name]=this.currentLocation,this._leaveAttrValue()}}else this._err(fe.duplicateAttribute)}_leaveAttrValue(){this.currentLocation&&(this.currentLocation.endLine=this.preprocessor.line,this.currentLocation.endCol=this.preprocessor.col,this.currentLocation.endOffset=this.preprocessor.offset)}prepareToken(t){this._emitCurrentCharacterToken(t.location),this.currentToken=null,t.location&&(t.location.endLine=this.preprocessor.line,t.location.endCol=this.preprocessor.col+1,t.location.endOffset=this.preprocessor.offset+1),this.currentLocation=this.getCurrentLocation(-1)}emitCurrentTagToken(){const t=this.currentToken;this.prepareToken(t),t.tagID=_s(t.tagName),t.type===st.START_TAG?(this.lastStartTagName=t.tagName,this.handler.onStartTag(t)):(t.attrs.length>0&&this._err(fe.endTagWithAttributes),t.selfClosing&&this._err(fe.endTagWithTrailingSolidus),this.handler.onEndTag(t)),this.preprocessor.dropParsedChunk()}emitCurrentComment(t){this.prepareToken(t),this.handler.onComment(t),this.preprocessor.dropParsedChunk()}emitCurrentDoctype(t){this.prepareToken(t),this.handler.onDoctype(t),this.preprocessor.dropParsedChunk()}_emitCurrentCharacterToken(t){if(this.currentCharacterToken){switch(t&&this.currentCharacterToken.location&&(this.currentCharacterToken.location.endLine=t.startLine,this.currentCharacterToken.location.endCol=t.startCol,this.currentCharacterToken.location.endOffset=t.startOffset),this.currentCharacterToken.type){case st.CHARACTER:{this.handler.onCharacter(this.currentCharacterToken);break}case st.NULL_CHARACTER:{this.handler.onNullCharacter(this.currentCharacterToken);break}case st.WHITESPACE_CHARACTER:{this.handler.onWhitespaceCharacter(this.currentCharacterToken);break}}this.currentCharacterToken=null}}_emitEOFToken(){const t=this.getCurrentLocation(0);t&&(t.endLine=t.startLine,t.endCol=t.startCol,t.endOffset=t.startOffset),this._emitCurrentCharacterToken(t),this.handler.onEof({type:st.EOF,location:t}),this.active=!1}_appendCharToCurrentCharacterToken(t,n){if(this.currentCharacterToken)if(this.currentCharacterToken.type===t){this.currentCharacterToken.chars+=n;return}else this.currentLocation=this.getCurrentLocation(0),this._emitCurrentCharacterToken(this.currentLocation),this.preprocessor.dropParsedChunk();this._createCharacterToken(t,n)}_emitCodePoint(t){const n=w_(t)?st.WHITESPACE_CHARACTER:t===k.NULL?st.NULL_CHARACTER:st.CHARACTER;this._appendCharToCurrentCharacterToken(n,String.fromCodePoint(t))}_emitChars(t){this._appendCharToCurrentCharacterToken(st.CHARACTER,t)}_startCharacterReference(){this.returnState=this.state,this.state=I.CHARACTER_REFERENCE,this.entityStartPos=this.preprocessor.pos,this.entityDecoder.startEntity(this._isCharacterReferenceInAttribute()?Bi.Attribute:Bi.Legacy)}_isCharacterReferenceInAttribute(){return this.returnState===I.ATTRIBUTE_VALUE_DOUBLE_QUOTED||this.returnState===I.ATTRIBUTE_VALUE_SINGLE_QUOTED||this.returnState===I.ATTRIBUTE_VALUE_UNQUOTED}_flushCodePointConsumedAsCharacterReference(t){this._isCharacterReferenceInAttribute()?this.currentAttr.value+=String.fromCodePoint(t):this._emitCodePoint(t)}_callState(t){switch(this.state){case I.DATA:{this._stateData(t);break}case I.RCDATA:{this._stateRcdata(t);break}case I.RAWTEXT:{this._stateRawtext(t);break}case I.SCRIPT_DATA:{this._stateScriptData(t);break}case I.PLAINTEXT:{this._statePlaintext(t);break}case I.TAG_OPEN:{this._stateTagOpen(t);break}case I.END_TAG_OPEN:{this._stateEndTagOpen(t);break}case I.TAG_NAME:{this._stateTagName(t);break}case I.RCDATA_LESS_THAN_SIGN:{this._stateRcdataLessThanSign(t);break}case I.RCDATA_END_TAG_OPEN:{this._stateRcdataEndTagOpen(t);break}case I.RCDATA_END_TAG_NAME:{this._stateRcdataEndTagName(t);break}case I.RAWTEXT_LESS_THAN_SIGN:{this._stateRawtextLessThanSign(t);break}case I.RAWTEXT_END_TAG_OPEN:{this._stateRawtextEndTagOpen(t);break}case I.RAWTEXT_END_TAG_NAME:{this._stateRawtextEndTagName(t);break}case I.SCRIPT_DATA_LESS_THAN_SIGN:{this._stateScriptDataLessThanSign(t);break}case I.SCRIPT_DATA_END_TAG_OPEN:{this._stateScriptDataEndTagOpen(t);break}case I.SCRIPT_DATA_END_TAG_NAME:{this._stateScriptDataEndTagName(t);break}case I.SCRIPT_DATA_ESCAPE_START:{this._stateScriptDataEscapeStart(t);break}case I.SCRIPT_DATA_ESCAPE_START_DASH:{this._stateScriptDataEscapeStartDash(t);break}case I.SCRIPT_DATA_ESCAPED:{this._stateScriptDataEscaped(t);break}case I.SCRIPT_DATA_ESCAPED_DASH:{this._stateScriptDataEscapedDash(t);break}case I.SCRIPT_DATA_ESCAPED_DASH_DASH:{this._stateScriptDataEscapedDashDash(t);break}case I.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:{this._stateScriptDataEscapedLessThanSign(t);break}case I.SCRIPT_DATA_ESCAPED_END_TAG_OPEN:{this._stateScriptDataEscapedEndTagOpen(t);break}case I.SCRIPT_DATA_ESCAPED_END_TAG_NAME:{this._stateScriptDataEscapedEndTagName(t);break}case I.SCRIPT_DATA_DOUBLE_ESCAPE_START:{this._stateScriptDataDoubleEscapeStart(t);break}case I.SCRIPT_DATA_DOUBLE_ESCAPED:{this._stateScriptDataDoubleEscaped(t);break}case I.SCRIPT_DATA_DOUBLE_ESCAPED_DASH:{this._stateScriptDataDoubleEscapedDash(t);break}case I.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:{this._stateScriptDataDoubleEscapedDashDash(t);break}case I.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:{this._stateScriptDataDoubleEscapedLessThanSign(t);break}case I.SCRIPT_DATA_DOUBLE_ESCAPE_END:{this._stateScriptDataDoubleEscapeEnd(t);break}case I.BEFORE_ATTRIBUTE_NAME:{this._stateBeforeAttributeName(t);break}case I.ATTRIBUTE_NAME:{this._stateAttributeName(t);break}case I.AFTER_ATTRIBUTE_NAME:{this._stateAfterAttributeName(t);break}case I.BEFORE_ATTRIBUTE_VALUE:{this._stateBeforeAttributeValue(t);break}case I.ATTRIBUTE_VALUE_DOUBLE_QUOTED:{this._stateAttributeValueDoubleQuoted(t);break}case I.ATTRIBUTE_VALUE_SINGLE_QUOTED:{this._stateAttributeValueSingleQuoted(t);break}case I.ATTRIBUTE_VALUE_UNQUOTED:{this._stateAttributeValueUnquoted(t);break}case I.AFTER_ATTRIBUTE_VALUE_QUOTED:{this._stateAfterAttributeValueQuoted(t);break}case I.SELF_CLOSING_START_TAG:{this._stateSelfClosingStartTag(t);break}case I.BOGUS_COMMENT:{this._stateBogusComment(t);break}case I.MARKUP_DECLARATION_OPEN:{this._stateMarkupDeclarationOpen(t);break}case I.COMMENT_START:{this._stateCommentStart(t);break}case I.COMMENT_START_DASH:{this._stateCommentStartDash(t);break}case I.COMMENT:{this._stateComment(t);break}case I.COMMENT_LESS_THAN_SIGN:{this._stateCommentLessThanSign(t);break}case I.COMMENT_LESS_THAN_SIGN_BANG:{this._stateCommentLessThanSignBang(t);break}case I.COMMENT_LESS_THAN_SIGN_BANG_DASH:{this._stateCommentLessThanSignBangDash(t);break}case I.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH:{this._stateCommentLessThanSignBangDashDash(t);break}case I.COMMENT_END_DASH:{this._stateCommentEndDash(t);break}case I.COMMENT_END:{this._stateCommentEnd(t);break}case I.COMMENT_END_BANG:{this._stateCommentEndBang(t);break}case I.DOCTYPE:{this._stateDoctype(t);break}case I.BEFORE_DOCTYPE_NAME:{this._stateBeforeDoctypeName(t);break}case I.DOCTYPE_NAME:{this._stateDoctypeName(t);break}case I.AFTER_DOCTYPE_NAME:{this._stateAfterDoctypeName(t);break}case I.AFTER_DOCTYPE_PUBLIC_KEYWORD:{this._stateAfterDoctypePublicKeyword(t);break}case I.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:{this._stateBeforeDoctypePublicIdentifier(t);break}case I.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:{this._stateDoctypePublicIdentifierDoubleQuoted(t);break}case I.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:{this._stateDoctypePublicIdentifierSingleQuoted(t);break}case I.AFTER_DOCTYPE_PUBLIC_IDENTIFIER:{this._stateAfterDoctypePublicIdentifier(t);break}case I.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:{this._stateBetweenDoctypePublicAndSystemIdentifiers(t);break}case I.AFTER_DOCTYPE_SYSTEM_KEYWORD:{this._stateAfterDoctypeSystemKeyword(t);break}case I.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:{this._stateBeforeDoctypeSystemIdentifier(t);break}case I.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:{this._stateDoctypeSystemIdentifierDoubleQuoted(t);break}case I.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:{this._stateDoctypeSystemIdentifierSingleQuoted(t);break}case I.AFTER_DOCTYPE_SYSTEM_IDENTIFIER:{this._stateAfterDoctypeSystemIdentifier(t);break}case I.BOGUS_DOCTYPE:{this._stateBogusDoctype(t);break}case I.CDATA_SECTION:{this._stateCdataSection(t);break}case I.CDATA_SECTION_BRACKET:{this._stateCdataSectionBracket(t);break}case I.CDATA_SECTION_END:{this._stateCdataSectionEnd(t);break}case I.CHARACTER_REFERENCE:{this._stateCharacterReference();break}case I.AMBIGUOUS_AMPERSAND:{this._stateAmbiguousAmpersand(t);break}default:throw new Error("Unknown state")}}_stateData(t){switch(t){case k.LESS_THAN_SIGN:{this.state=I.TAG_OPEN;break}case k.AMPERSAND:{this._startCharacterReference();break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this._emitCodePoint(t);break}case k.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(t)}}_stateRcdata(t){switch(t){case k.AMPERSAND:{this._startCharacterReference();break}case k.LESS_THAN_SIGN:{this.state=I.RCDATA_LESS_THAN_SIGN;break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this._emitChars(Vt);break}case k.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(t)}}_stateRawtext(t){switch(t){case k.LESS_THAN_SIGN:{this.state=I.RAWTEXT_LESS_THAN_SIGN;break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this._emitChars(Vt);break}case k.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(t)}}_stateScriptData(t){switch(t){case k.LESS_THAN_SIGN:{this.state=I.SCRIPT_DATA_LESS_THAN_SIGN;break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this._emitChars(Vt);break}case k.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(t)}}_statePlaintext(t){switch(t){case k.NULL:{this._err(fe.unexpectedNullCharacter),this._emitChars(Vt);break}case k.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(t)}}_stateTagOpen(t){if(ga(t))this._createStartTagToken(),this.state=I.TAG_NAME,this._stateTagName(t);else switch(t){case k.EXCLAMATION_MARK:{this.state=I.MARKUP_DECLARATION_OPEN;break}case k.SOLIDUS:{this.state=I.END_TAG_OPEN;break}case k.QUESTION_MARK:{this._err(fe.unexpectedQuestionMarkInsteadOfTagName),this._createCommentToken(1),this.state=I.BOGUS_COMMENT,this._stateBogusComment(t);break}case k.EOF:{this._err(fe.eofBeforeTagName),this._emitChars("<"),this._emitEOFToken();break}default:this._err(fe.invalidFirstCharacterOfTagName),this._emitChars("<"),this.state=I.DATA,this._stateData(t)}}_stateEndTagOpen(t){if(ga(t))this._createEndTagToken(),this.state=I.TAG_NAME,this._stateTagName(t);else switch(t){case k.GREATER_THAN_SIGN:{this._err(fe.missingEndTagName),this.state=I.DATA;break}case k.EOF:{this._err(fe.eofBeforeTagName),this._emitChars("</"),this._emitEOFToken();break}default:this._err(fe.invalidFirstCharacterOfTagName),this._createCommentToken(2),this.state=I.BOGUS_COMMENT,this._stateBogusComment(t)}}_stateTagName(t){const n=this.currentToken;switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:{this.state=I.BEFORE_ATTRIBUTE_NAME;break}case k.SOLIDUS:{this.state=I.SELF_CLOSING_START_TAG;break}case k.GREATER_THAN_SIGN:{this.state=I.DATA,this.emitCurrentTagToken();break}case k.NULL:{this._err(fe.unexpectedNullCharacter),n.tagName+=Vt;break}case k.EOF:{this._err(fe.eofInTag),this._emitEOFToken();break}default:n.tagName+=String.fromCodePoint(el(t)?pf(t):t)}}_stateRcdataLessThanSign(t){t===k.SOLIDUS?this.state=I.RCDATA_END_TAG_OPEN:(this._emitChars("<"),this.state=I.RCDATA,this._stateRcdata(t))}_stateRcdataEndTagOpen(t){ga(t)?(this.state=I.RCDATA_END_TAG_NAME,this._stateRcdataEndTagName(t)):(this._emitChars("</"),this.state=I.RCDATA,this._stateRcdata(t))}handleSpecialEndTag(t){if(!this.preprocessor.startsWith(this.lastStartTagName,!1))return!this._ensureHibernation();this._createEndTagToken();const n=this.currentToken;switch(n.tagName=this.lastStartTagName,this.preprocessor.peek(this.lastStartTagName.length)){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:return this._advanceBy(this.lastStartTagName.length),this.state=I.BEFORE_ATTRIBUTE_NAME,!1;case k.SOLIDUS:return this._advanceBy(this.lastStartTagName.length),this.state=I.SELF_CLOSING_START_TAG,!1;case k.GREATER_THAN_SIGN:return this._advanceBy(this.lastStartTagName.length),this.emitCurrentTagToken(),this.state=I.DATA,!1;default:return!this._ensureHibernation()}}_stateRcdataEndTagName(t){this.handleSpecialEndTag(t)&&(this._emitChars("</"),this.state=I.RCDATA,this._stateRcdata(t))}_stateRawtextLessThanSign(t){t===k.SOLIDUS?this.state=I.RAWTEXT_END_TAG_OPEN:(this._emitChars("<"),this.state=I.RAWTEXT,this._stateRawtext(t))}_stateRawtextEndTagOpen(t){ga(t)?(this.state=I.RAWTEXT_END_TAG_NAME,this._stateRawtextEndTagName(t)):(this._emitChars("</"),this.state=I.RAWTEXT,this._stateRawtext(t))}_stateRawtextEndTagName(t){this.handleSpecialEndTag(t)&&(this._emitChars("</"),this.state=I.RAWTEXT,this._stateRawtext(t))}_stateScriptDataLessThanSign(t){switch(t){case k.SOLIDUS:{this.state=I.SCRIPT_DATA_END_TAG_OPEN;break}case k.EXCLAMATION_MARK:{this.state=I.SCRIPT_DATA_ESCAPE_START,this._emitChars("<!");break}default:this._emitChars("<"),this.state=I.SCRIPT_DATA,this._stateScriptData(t)}}_stateScriptDataEndTagOpen(t){ga(t)?(this.state=I.SCRIPT_DATA_END_TAG_NAME,this._stateScriptDataEndTagName(t)):(this._emitChars("</"),this.state=I.SCRIPT_DATA,this._stateScriptData(t))}_stateScriptDataEndTagName(t){this.handleSpecialEndTag(t)&&(this._emitChars("</"),this.state=I.SCRIPT_DATA,this._stateScriptData(t))}_stateScriptDataEscapeStart(t){t===k.HYPHEN_MINUS?(this.state=I.SCRIPT_DATA_ESCAPE_START_DASH,this._emitChars("-")):(this.state=I.SCRIPT_DATA,this._stateScriptData(t))}_stateScriptDataEscapeStartDash(t){t===k.HYPHEN_MINUS?(this.state=I.SCRIPT_DATA_ESCAPED_DASH_DASH,this._emitChars("-")):(this.state=I.SCRIPT_DATA,this._stateScriptData(t))}_stateScriptDataEscaped(t){switch(t){case k.HYPHEN_MINUS:{this.state=I.SCRIPT_DATA_ESCAPED_DASH,this._emitChars("-");break}case k.LESS_THAN_SIGN:{this.state=I.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this._emitChars(Vt);break}case k.EOF:{this._err(fe.eofInScriptHtmlCommentLikeText),this._emitEOFToken();break}default:this._emitCodePoint(t)}}_stateScriptDataEscapedDash(t){switch(t){case k.HYPHEN_MINUS:{this.state=I.SCRIPT_DATA_ESCAPED_DASH_DASH,this._emitChars("-");break}case k.LESS_THAN_SIGN:{this.state=I.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this.state=I.SCRIPT_DATA_ESCAPED,this._emitChars(Vt);break}case k.EOF:{this._err(fe.eofInScriptHtmlCommentLikeText),this._emitEOFToken();break}default:this.state=I.SCRIPT_DATA_ESCAPED,this._emitCodePoint(t)}}_stateScriptDataEscapedDashDash(t){switch(t){case k.HYPHEN_MINUS:{this._emitChars("-");break}case k.LESS_THAN_SIGN:{this.state=I.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;break}case k.GREATER_THAN_SIGN:{this.state=I.SCRIPT_DATA,this._emitChars(">");break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this.state=I.SCRIPT_DATA_ESCAPED,this._emitChars(Vt);break}case k.EOF:{this._err(fe.eofInScriptHtmlCommentLikeText),this._emitEOFToken();break}default:this.state=I.SCRIPT_DATA_ESCAPED,this._emitCodePoint(t)}}_stateScriptDataEscapedLessThanSign(t){t===k.SOLIDUS?this.state=I.SCRIPT_DATA_ESCAPED_END_TAG_OPEN:ga(t)?(this._emitChars("<"),this.state=I.SCRIPT_DATA_DOUBLE_ESCAPE_START,this._stateScriptDataDoubleEscapeStart(t)):(this._emitChars("<"),this.state=I.SCRIPT_DATA_ESCAPED,this._stateScriptDataEscaped(t))}_stateScriptDataEscapedEndTagOpen(t){ga(t)?(this.state=I.SCRIPT_DATA_ESCAPED_END_TAG_NAME,this._stateScriptDataEscapedEndTagName(t)):(this._emitChars("</"),this.state=I.SCRIPT_DATA_ESCAPED,this._stateScriptDataEscaped(t))}_stateScriptDataEscapedEndTagName(t){this.handleSpecialEndTag(t)&&(this._emitChars("</"),this.state=I.SCRIPT_DATA_ESCAPED,this._stateScriptDataEscaped(t))}_stateScriptDataDoubleEscapeStart(t){if(this.preprocessor.startsWith(er.SCRIPT,!1)&&ZS(this.preprocessor.peek(er.SCRIPT.length))){this._emitCodePoint(t);for(let n=0;n<er.SCRIPT.length;n++)this._emitCodePoint(this._consume());this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED}else this._ensureHibernation()||(this.state=I.SCRIPT_DATA_ESCAPED,this._stateScriptDataEscaped(t))}_stateScriptDataDoubleEscaped(t){switch(t){case k.HYPHEN_MINUS:{this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED_DASH,this._emitChars("-");break}case k.LESS_THAN_SIGN:{this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,this._emitChars("<");break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this._emitChars(Vt);break}case k.EOF:{this._err(fe.eofInScriptHtmlCommentLikeText),this._emitEOFToken();break}default:this._emitCodePoint(t)}}_stateScriptDataDoubleEscapedDash(t){switch(t){case k.HYPHEN_MINUS:{this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH,this._emitChars("-");break}case k.LESS_THAN_SIGN:{this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,this._emitChars("<");break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED,this._emitChars(Vt);break}case k.EOF:{this._err(fe.eofInScriptHtmlCommentLikeText),this._emitEOFToken();break}default:this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED,this._emitCodePoint(t)}}_stateScriptDataDoubleEscapedDashDash(t){switch(t){case k.HYPHEN_MINUS:{this._emitChars("-");break}case k.LESS_THAN_SIGN:{this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,this._emitChars("<");break}case k.GREATER_THAN_SIGN:{this.state=I.SCRIPT_DATA,this._emitChars(">");break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED,this._emitChars(Vt);break}case k.EOF:{this._err(fe.eofInScriptHtmlCommentLikeText),this._emitEOFToken();break}default:this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED,this._emitCodePoint(t)}}_stateScriptDataDoubleEscapedLessThanSign(t){t===k.SOLIDUS?(this.state=I.SCRIPT_DATA_DOUBLE_ESCAPE_END,this._emitChars("/")):(this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED,this._stateScriptDataDoubleEscaped(t))}_stateScriptDataDoubleEscapeEnd(t){if(this.preprocessor.startsWith(er.SCRIPT,!1)&&ZS(this.preprocessor.peek(er.SCRIPT.length))){this._emitCodePoint(t);for(let n=0;n<er.SCRIPT.length;n++)this._emitCodePoint(this._consume());this.state=I.SCRIPT_DATA_ESCAPED}else this._ensureHibernation()||(this.state=I.SCRIPT_DATA_DOUBLE_ESCAPED,this._stateScriptDataDoubleEscaped(t))}_stateBeforeAttributeName(t){switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:break;case k.SOLIDUS:case k.GREATER_THAN_SIGN:case k.EOF:{this.state=I.AFTER_ATTRIBUTE_NAME,this._stateAfterAttributeName(t);break}case k.EQUALS_SIGN:{this._err(fe.unexpectedEqualsSignBeforeAttributeName),this._createAttr("="),this.state=I.ATTRIBUTE_NAME;break}default:this._createAttr(""),this.state=I.ATTRIBUTE_NAME,this._stateAttributeName(t)}}_stateAttributeName(t){switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:case k.SOLIDUS:case k.GREATER_THAN_SIGN:case k.EOF:{this._leaveAttrName(),this.state=I.AFTER_ATTRIBUTE_NAME,this._stateAfterAttributeName(t);break}case k.EQUALS_SIGN:{this._leaveAttrName(),this.state=I.BEFORE_ATTRIBUTE_VALUE;break}case k.QUOTATION_MARK:case k.APOSTROPHE:case k.LESS_THAN_SIGN:{this._err(fe.unexpectedCharacterInAttributeName),this.currentAttr.name+=String.fromCodePoint(t);break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this.currentAttr.name+=Vt;break}default:this.currentAttr.name+=String.fromCodePoint(el(t)?pf(t):t)}}_stateAfterAttributeName(t){switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:break;case k.SOLIDUS:{this.state=I.SELF_CLOSING_START_TAG;break}case k.EQUALS_SIGN:{this.state=I.BEFORE_ATTRIBUTE_VALUE;break}case k.GREATER_THAN_SIGN:{this.state=I.DATA,this.emitCurrentTagToken();break}case k.EOF:{this._err(fe.eofInTag),this._emitEOFToken();break}default:this._createAttr(""),this.state=I.ATTRIBUTE_NAME,this._stateAttributeName(t)}}_stateBeforeAttributeValue(t){switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:break;case k.QUOTATION_MARK:{this.state=I.ATTRIBUTE_VALUE_DOUBLE_QUOTED;break}case k.APOSTROPHE:{this.state=I.ATTRIBUTE_VALUE_SINGLE_QUOTED;break}case k.GREATER_THAN_SIGN:{this._err(fe.missingAttributeValue),this.state=I.DATA,this.emitCurrentTagToken();break}default:this.state=I.ATTRIBUTE_VALUE_UNQUOTED,this._stateAttributeValueUnquoted(t)}}_stateAttributeValueDoubleQuoted(t){switch(t){case k.QUOTATION_MARK:{this.state=I.AFTER_ATTRIBUTE_VALUE_QUOTED;break}case k.AMPERSAND:{this._startCharacterReference();break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this.currentAttr.value+=Vt;break}case k.EOF:{this._err(fe.eofInTag),this._emitEOFToken();break}default:this.currentAttr.value+=String.fromCodePoint(t)}}_stateAttributeValueSingleQuoted(t){switch(t){case k.APOSTROPHE:{this.state=I.AFTER_ATTRIBUTE_VALUE_QUOTED;break}case k.AMPERSAND:{this._startCharacterReference();break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this.currentAttr.value+=Vt;break}case k.EOF:{this._err(fe.eofInTag),this._emitEOFToken();break}default:this.currentAttr.value+=String.fromCodePoint(t)}}_stateAttributeValueUnquoted(t){switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:{this._leaveAttrValue(),this.state=I.BEFORE_ATTRIBUTE_NAME;break}case k.AMPERSAND:{this._startCharacterReference();break}case k.GREATER_THAN_SIGN:{this._leaveAttrValue(),this.state=I.DATA,this.emitCurrentTagToken();break}case k.NULL:{this._err(fe.unexpectedNullCharacter),this.currentAttr.value+=Vt;break}case k.QUOTATION_MARK:case k.APOSTROPHE:case k.LESS_THAN_SIGN:case k.EQUALS_SIGN:case k.GRAVE_ACCENT:{this._err(fe.unexpectedCharacterInUnquotedAttributeValue),this.currentAttr.value+=String.fromCodePoint(t);break}case k.EOF:{this._err(fe.eofInTag),this._emitEOFToken();break}default:this.currentAttr.value+=String.fromCodePoint(t)}}_stateAfterAttributeValueQuoted(t){switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:{this._leaveAttrValue(),this.state=I.BEFORE_ATTRIBUTE_NAME;break}case k.SOLIDUS:{this._leaveAttrValue(),this.state=I.SELF_CLOSING_START_TAG;break}case k.GREATER_THAN_SIGN:{this._leaveAttrValue(),this.state=I.DATA,this.emitCurrentTagToken();break}case k.EOF:{this._err(fe.eofInTag),this._emitEOFToken();break}default:this._err(fe.missingWhitespaceBetweenAttributes),this.state=I.BEFORE_ATTRIBUTE_NAME,this._stateBeforeAttributeName(t)}}_stateSelfClosingStartTag(t){switch(t){case k.GREATER_THAN_SIGN:{const n=this.currentToken;n.selfClosing=!0,this.state=I.DATA,this.emitCurrentTagToken();break}case k.EOF:{this._err(fe.eofInTag),this._emitEOFToken();break}default:this._err(fe.unexpectedSolidusInTag),this.state=I.BEFORE_ATTRIBUTE_NAME,this._stateBeforeAttributeName(t)}}_stateBogusComment(t){const n=this.currentToken;switch(t){case k.GREATER_THAN_SIGN:{this.state=I.DATA,this.emitCurrentComment(n);break}case k.EOF:{this.emitCurrentComment(n),this._emitEOFToken();break}case k.NULL:{this._err(fe.unexpectedNullCharacter),n.data+=Vt;break}default:n.data+=String.fromCodePoint(t)}}_stateMarkupDeclarationOpen(t){this._consumeSequenceIfMatch(er.DASH_DASH,!0)?(this._createCommentToken(er.DASH_DASH.length+1),this.state=I.COMMENT_START):this._consumeSequenceIfMatch(er.DOCTYPE,!1)?(this.currentLocation=this.getCurrentLocation(er.DOCTYPE.length+1),this.state=I.DOCTYPE):this._consumeSequenceIfMatch(er.CDATA_START,!0)?this.inForeignNode?this.state=I.CDATA_SECTION:(this._err(fe.cdataInHtmlContent),this._createCommentToken(er.CDATA_START.length+1),this.currentToken.data="[CDATA[",this.state=I.BOGUS_COMMENT):this._ensureHibernation()||(this._err(fe.incorrectlyOpenedComment),this._createCommentToken(2),this.state=I.BOGUS_COMMENT,this._stateBogusComment(t))}_stateCommentStart(t){switch(t){case k.HYPHEN_MINUS:{this.state=I.COMMENT_START_DASH;break}case k.GREATER_THAN_SIGN:{this._err(fe.abruptClosingOfEmptyComment),this.state=I.DATA;const n=this.currentToken;this.emitCurrentComment(n);break}default:this.state=I.COMMENT,this._stateComment(t)}}_stateCommentStartDash(t){const n=this.currentToken;switch(t){case k.HYPHEN_MINUS:{this.state=I.COMMENT_END;break}case k.GREATER_THAN_SIGN:{this._err(fe.abruptClosingOfEmptyComment),this.state=I.DATA,this.emitCurrentComment(n);break}case k.EOF:{this._err(fe.eofInComment),this.emitCurrentComment(n),this._emitEOFToken();break}default:n.data+="-",this.state=I.COMMENT,this._stateComment(t)}}_stateComment(t){const n=this.currentToken;switch(t){case k.HYPHEN_MINUS:{this.state=I.COMMENT_END_DASH;break}case k.LESS_THAN_SIGN:{n.data+="<",this.state=I.COMMENT_LESS_THAN_SIGN;break}case k.NULL:{this._err(fe.unexpectedNullCharacter),n.data+=Vt;break}case k.EOF:{this._err(fe.eofInComment),this.emitCurrentComment(n),this._emitEOFToken();break}default:n.data+=String.fromCodePoint(t)}}_stateCommentLessThanSign(t){const n=this.currentToken;switch(t){case k.EXCLAMATION_MARK:{n.data+="!",this.state=I.COMMENT_LESS_THAN_SIGN_BANG;break}case k.LESS_THAN_SIGN:{n.data+="<";break}default:this.state=I.COMMENT,this._stateComment(t)}}_stateCommentLessThanSignBang(t){t===k.HYPHEN_MINUS?this.state=I.COMMENT_LESS_THAN_SIGN_BANG_DASH:(this.state=I.COMMENT,this._stateComment(t))}_stateCommentLessThanSignBangDash(t){t===k.HYPHEN_MINUS?this.state=I.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH:(this.state=I.COMMENT_END_DASH,this._stateCommentEndDash(t))}_stateCommentLessThanSignBangDashDash(t){t!==k.GREATER_THAN_SIGN&&t!==k.EOF&&this._err(fe.nestedComment),this.state=I.COMMENT_END,this._stateCommentEnd(t)}_stateCommentEndDash(t){const n=this.currentToken;switch(t){case k.HYPHEN_MINUS:{this.state=I.COMMENT_END;break}case k.EOF:{this._err(fe.eofInComment),this.emitCurrentComment(n),this._emitEOFToken();break}default:n.data+="-",this.state=I.COMMENT,this._stateComment(t)}}_stateCommentEnd(t){const n=this.currentToken;switch(t){case k.GREATER_THAN_SIGN:{this.state=I.DATA,this.emitCurrentComment(n);break}case k.EXCLAMATION_MARK:{this.state=I.COMMENT_END_BANG;break}case k.HYPHEN_MINUS:{n.data+="-";break}case k.EOF:{this._err(fe.eofInComment),this.emitCurrentComment(n),this._emitEOFToken();break}default:n.data+="--",this.state=I.COMMENT,this._stateComment(t)}}_stateCommentEndBang(t){const n=this.currentToken;switch(t){case k.HYPHEN_MINUS:{n.data+="--!",this.state=I.COMMENT_END_DASH;break}case k.GREATER_THAN_SIGN:{this._err(fe.incorrectlyClosedComment),this.state=I.DATA,this.emitCurrentComment(n);break}case k.EOF:{this._err(fe.eofInComment),this.emitCurrentComment(n),this._emitEOFToken();break}default:n.data+="--!",this.state=I.COMMENT,this._stateComment(t)}}_stateDoctype(t){switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:{this.state=I.BEFORE_DOCTYPE_NAME;break}case k.GREATER_THAN_SIGN:{this.state=I.BEFORE_DOCTYPE_NAME,this._stateBeforeDoctypeName(t);break}case k.EOF:{this._err(fe.eofInDoctype),this._createDoctypeToken(null);const n=this.currentToken;n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:this._err(fe.missingWhitespaceBeforeDoctypeName),this.state=I.BEFORE_DOCTYPE_NAME,this._stateBeforeDoctypeName(t)}}_stateBeforeDoctypeName(t){if(el(t))this._createDoctypeToken(String.fromCharCode(pf(t))),this.state=I.DOCTYPE_NAME;else switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:break;case k.NULL:{this._err(fe.unexpectedNullCharacter),this._createDoctypeToken(Vt),this.state=I.DOCTYPE_NAME;break}case k.GREATER_THAN_SIGN:{this._err(fe.missingDoctypeName),this._createDoctypeToken(null);const n=this.currentToken;n.forceQuirks=!0,this.emitCurrentDoctype(n),this.state=I.DATA;break}case k.EOF:{this._err(fe.eofInDoctype),this._createDoctypeToken(null);const n=this.currentToken;n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:this._createDoctypeToken(String.fromCodePoint(t)),this.state=I.DOCTYPE_NAME}}_stateDoctypeName(t){const n=this.currentToken;switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:{this.state=I.AFTER_DOCTYPE_NAME;break}case k.GREATER_THAN_SIGN:{this.state=I.DATA,this.emitCurrentDoctype(n);break}case k.NULL:{this._err(fe.unexpectedNullCharacter),n.name+=Vt;break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:n.name+=String.fromCodePoint(el(t)?pf(t):t)}}_stateAfterDoctypeName(t){const n=this.currentToken;switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:break;case k.GREATER_THAN_SIGN:{this.state=I.DATA,this.emitCurrentDoctype(n);break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:this._consumeSequenceIfMatch(er.PUBLIC,!1)?this.state=I.AFTER_DOCTYPE_PUBLIC_KEYWORD:this._consumeSequenceIfMatch(er.SYSTEM,!1)?this.state=I.AFTER_DOCTYPE_SYSTEM_KEYWORD:this._ensureHibernation()||(this._err(fe.invalidCharacterSequenceAfterDoctypeName),n.forceQuirks=!0,this.state=I.BOGUS_DOCTYPE,this._stateBogusDoctype(t))}}_stateAfterDoctypePublicKeyword(t){const n=this.currentToken;switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:{this.state=I.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER;break}case k.QUOTATION_MARK:{this._err(fe.missingWhitespaceAfterDoctypePublicKeyword),n.publicId="",this.state=I.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;break}case k.APOSTROPHE:{this._err(fe.missingWhitespaceAfterDoctypePublicKeyword),n.publicId="",this.state=I.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;break}case k.GREATER_THAN_SIGN:{this._err(fe.missingDoctypePublicIdentifier),n.forceQuirks=!0,this.state=I.DATA,this.emitCurrentDoctype(n);break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:this._err(fe.missingQuoteBeforeDoctypePublicIdentifier),n.forceQuirks=!0,this.state=I.BOGUS_DOCTYPE,this._stateBogusDoctype(t)}}_stateBeforeDoctypePublicIdentifier(t){const n=this.currentToken;switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:break;case k.QUOTATION_MARK:{n.publicId="",this.state=I.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;break}case k.APOSTROPHE:{n.publicId="",this.state=I.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;break}case k.GREATER_THAN_SIGN:{this._err(fe.missingDoctypePublicIdentifier),n.forceQuirks=!0,this.state=I.DATA,this.emitCurrentDoctype(n);break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:this._err(fe.missingQuoteBeforeDoctypePublicIdentifier),n.forceQuirks=!0,this.state=I.BOGUS_DOCTYPE,this._stateBogusDoctype(t)}}_stateDoctypePublicIdentifierDoubleQuoted(t){const n=this.currentToken;switch(t){case k.QUOTATION_MARK:{this.state=I.AFTER_DOCTYPE_PUBLIC_IDENTIFIER;break}case k.NULL:{this._err(fe.unexpectedNullCharacter),n.publicId+=Vt;break}case k.GREATER_THAN_SIGN:{this._err(fe.abruptDoctypePublicIdentifier),n.forceQuirks=!0,this.emitCurrentDoctype(n),this.state=I.DATA;break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:n.publicId+=String.fromCodePoint(t)}}_stateDoctypePublicIdentifierSingleQuoted(t){const n=this.currentToken;switch(t){case k.APOSTROPHE:{this.state=I.AFTER_DOCTYPE_PUBLIC_IDENTIFIER;break}case k.NULL:{this._err(fe.unexpectedNullCharacter),n.publicId+=Vt;break}case k.GREATER_THAN_SIGN:{this._err(fe.abruptDoctypePublicIdentifier),n.forceQuirks=!0,this.emitCurrentDoctype(n),this.state=I.DATA;break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:n.publicId+=String.fromCodePoint(t)}}_stateAfterDoctypePublicIdentifier(t){const n=this.currentToken;switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:{this.state=I.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS;break}case k.GREATER_THAN_SIGN:{this.state=I.DATA,this.emitCurrentDoctype(n);break}case k.QUOTATION_MARK:{this._err(fe.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers),n.systemId="",this.state=I.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;break}case k.APOSTROPHE:{this._err(fe.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers),n.systemId="",this.state=I.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:this._err(fe.missingQuoteBeforeDoctypeSystemIdentifier),n.forceQuirks=!0,this.state=I.BOGUS_DOCTYPE,this._stateBogusDoctype(t)}}_stateBetweenDoctypePublicAndSystemIdentifiers(t){const n=this.currentToken;switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:break;case k.GREATER_THAN_SIGN:{this.emitCurrentDoctype(n),this.state=I.DATA;break}case k.QUOTATION_MARK:{n.systemId="",this.state=I.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;break}case k.APOSTROPHE:{n.systemId="",this.state=I.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:this._err(fe.missingQuoteBeforeDoctypeSystemIdentifier),n.forceQuirks=!0,this.state=I.BOGUS_DOCTYPE,this._stateBogusDoctype(t)}}_stateAfterDoctypeSystemKeyword(t){const n=this.currentToken;switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:{this.state=I.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER;break}case k.QUOTATION_MARK:{this._err(fe.missingWhitespaceAfterDoctypeSystemKeyword),n.systemId="",this.state=I.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;break}case k.APOSTROPHE:{this._err(fe.missingWhitespaceAfterDoctypeSystemKeyword),n.systemId="",this.state=I.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;break}case k.GREATER_THAN_SIGN:{this._err(fe.missingDoctypeSystemIdentifier),n.forceQuirks=!0,this.state=I.DATA,this.emitCurrentDoctype(n);break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:this._err(fe.missingQuoteBeforeDoctypeSystemIdentifier),n.forceQuirks=!0,this.state=I.BOGUS_DOCTYPE,this._stateBogusDoctype(t)}}_stateBeforeDoctypeSystemIdentifier(t){const n=this.currentToken;switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:break;case k.QUOTATION_MARK:{n.systemId="",this.state=I.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;break}case k.APOSTROPHE:{n.systemId="",this.state=I.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;break}case k.GREATER_THAN_SIGN:{this._err(fe.missingDoctypeSystemIdentifier),n.forceQuirks=!0,this.state=I.DATA,this.emitCurrentDoctype(n);break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:this._err(fe.missingQuoteBeforeDoctypeSystemIdentifier),n.forceQuirks=!0,this.state=I.BOGUS_DOCTYPE,this._stateBogusDoctype(t)}}_stateDoctypeSystemIdentifierDoubleQuoted(t){const n=this.currentToken;switch(t){case k.QUOTATION_MARK:{this.state=I.AFTER_DOCTYPE_SYSTEM_IDENTIFIER;break}case k.NULL:{this._err(fe.unexpectedNullCharacter),n.systemId+=Vt;break}case k.GREATER_THAN_SIGN:{this._err(fe.abruptDoctypeSystemIdentifier),n.forceQuirks=!0,this.emitCurrentDoctype(n),this.state=I.DATA;break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:n.systemId+=String.fromCodePoint(t)}}_stateDoctypeSystemIdentifierSingleQuoted(t){const n=this.currentToken;switch(t){case k.APOSTROPHE:{this.state=I.AFTER_DOCTYPE_SYSTEM_IDENTIFIER;break}case k.NULL:{this._err(fe.unexpectedNullCharacter),n.systemId+=Vt;break}case k.GREATER_THAN_SIGN:{this._err(fe.abruptDoctypeSystemIdentifier),n.forceQuirks=!0,this.emitCurrentDoctype(n),this.state=I.DATA;break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:n.systemId+=String.fromCodePoint(t)}}_stateAfterDoctypeSystemIdentifier(t){const n=this.currentToken;switch(t){case k.SPACE:case k.LINE_FEED:case k.TABULATION:case k.FORM_FEED:break;case k.GREATER_THAN_SIGN:{this.emitCurrentDoctype(n),this.state=I.DATA;break}case k.EOF:{this._err(fe.eofInDoctype),n.forceQuirks=!0,this.emitCurrentDoctype(n),this._emitEOFToken();break}default:this._err(fe.unexpectedCharacterAfterDoctypeSystemIdentifier),this.state=I.BOGUS_DOCTYPE,this._stateBogusDoctype(t)}}_stateBogusDoctype(t){const n=this.currentToken;switch(t){case k.GREATER_THAN_SIGN:{this.emitCurrentDoctype(n),this.state=I.DATA;break}case k.NULL:{this._err(fe.unexpectedNullCharacter);break}case k.EOF:{this.emitCurrentDoctype(n),this._emitEOFToken();break}}}_stateCdataSection(t){switch(t){case k.RIGHT_SQUARE_BRACKET:{this.state=I.CDATA_SECTION_BRACKET;break}case k.EOF:{this._err(fe.eofInCdata),this._emitEOFToken();break}default:this._emitCodePoint(t)}}_stateCdataSectionBracket(t){t===k.RIGHT_SQUARE_BRACKET?this.state=I.CDATA_SECTION_END:(this._emitChars("]"),this.state=I.CDATA_SECTION,this._stateCdataSection(t))}_stateCdataSectionEnd(t){switch(t){case k.GREATER_THAN_SIGN:{this.state=I.DATA;break}case k.RIGHT_SQUARE_BRACKET:{this._emitChars("]");break}default:this._emitChars("]]"),this.state=I.CDATA_SECTION,this._stateCdataSection(t)}}_stateCharacterReference(){let t=this.entityDecoder.write(this.preprocessor.html,this.preprocessor.pos);if(t<0)if(this.preprocessor.lastChunkWritten)t=this.entityDecoder.end();else{this.active=!1,this.preprocessor.pos=this.preprocessor.html.length-1,this.consumedAfterSnapshot=0,this.preprocessor.endOfChunkHit=!0;return}t===0?(this.preprocessor.pos=this.entityStartPos,this._flushCodePointConsumedAsCharacterReference(k.AMPERSAND),this.state=!this._isCharacterReferenceInAttribute()&&$S(this.preprocessor.peek(1))?I.AMBIGUOUS_AMPERSAND:this.returnState):this.state=this.returnState}_stateAmbiguousAmpersand(t){$S(t)?this._flushCodePointConsumedAsCharacterReference(t):(t===k.SEMICOLON&&this._err(fe.unknownNamedCharacterReference),this.state=this.returnState,this._callState(t))}}const O_=new Set([y.DD,y.DT,y.LI,y.OPTGROUP,y.OPTION,y.P,y.RB,y.RP,y.RT,y.RTC]),JS=new Set([...O_,y.CAPTION,y.COLGROUP,y.TBODY,y.TD,y.TFOOT,y.TH,y.THEAD,y.TR]),Gf=new Set([y.APPLET,y.CAPTION,y.HTML,y.MARQUEE,y.OBJECT,y.TABLE,y.TD,y.TEMPLATE,y.TH]),q7=new Set([...Gf,y.OL,y.UL]),Y7=new Set([...Gf,y.BUTTON]),e2=new Set([y.ANNOTATION_XML,y.MI,y.MN,y.MO,y.MS,y.MTEXT]),t2=new Set([y.DESC,y.FOREIGN_OBJECT,y.TITLE]),G7=new Set([y.TR,y.TEMPLATE,y.HTML]),X7=new Set([y.TBODY,y.TFOOT,y.THEAD,y.TEMPLATE,y.HTML]),K7=new Set([y.TABLE,y.TEMPLATE,y.HTML]),W7=new Set([y.TD,y.TH]);class Q7{get currentTmplContentOrNode(){return this._isInTemplate()?this.treeAdapter.getTemplateContent(this.current):this.current}constructor(t,n,i){this.treeAdapter=n,this.handler=i,this.items=[],this.tagIDs=[],this.stackTop=-1,this.tmplCount=0,this.currentTagId=y.UNKNOWN,this.current=t}_indexOf(t){return this.items.lastIndexOf(t,this.stackTop)}_isInTemplate(){return this.currentTagId===y.TEMPLATE&&this.treeAdapter.getNamespaceURI(this.current)===be.HTML}_updateCurrentElement(){this.current=this.items[this.stackTop],this.currentTagId=this.tagIDs[this.stackTop]}push(t,n){this.stackTop++,this.items[this.stackTop]=t,this.current=t,this.tagIDs[this.stackTop]=n,this.currentTagId=n,this._isInTemplate()&&this.tmplCount++,this.handler.onItemPush(t,n,!0)}pop(){const t=this.current;this.tmplCount>0&&this._isInTemplate()&&this.tmplCount--,this.stackTop--,this._updateCurrentElement(),this.handler.onItemPop(t,!0)}replace(t,n){const i=this._indexOf(t);this.items[i]=n,i===this.stackTop&&(this.current=n)}insertAfter(t,n,i){const u=this._indexOf(t)+1;this.items.splice(u,0,n),this.tagIDs.splice(u,0,i),this.stackTop++,u===this.stackTop&&this._updateCurrentElement(),this.current&&this.currentTagId!==void 0&&this.handler.onItemPush(this.current,this.currentTagId,u===this.stackTop)}popUntilTagNamePopped(t){let n=this.stackTop+1;do n=this.tagIDs.lastIndexOf(t,n-1);while(n>0&&this.treeAdapter.getNamespaceURI(this.items[n])!==be.HTML);this.shortenToLength(Math.max(n,0))}shortenToLength(t){for(;this.stackTop>=t;){const n=this.current;this.tmplCount>0&&this._isInTemplate()&&(this.tmplCount-=1),this.stackTop--,this._updateCurrentElement(),this.handler.onItemPop(n,this.stackTop<t)}}popUntilElementPopped(t){const n=this._indexOf(t);this.shortenToLength(Math.max(n,0))}popUntilPopped(t,n){const i=this._indexOfTagNames(t,n);this.shortenToLength(Math.max(i,0))}popUntilNumberedHeaderPopped(){this.popUntilPopped(D0,be.HTML)}popUntilTableCellPopped(){this.popUntilPopped(W7,be.HTML)}popAllUpToHtmlElement(){this.tmplCount=0,this.shortenToLength(1)}_indexOfTagNames(t,n){for(let i=this.stackTop;i>=0;i--)if(t.has(this.tagIDs[i])&&this.treeAdapter.getNamespaceURI(this.items[i])===n)return i;return-1}clearBackTo(t,n){const i=this._indexOfTagNames(t,n);this.shortenToLength(i+1)}clearBackToTableContext(){this.clearBackTo(K7,be.HTML)}clearBackToTableBodyContext(){this.clearBackTo(X7,be.HTML)}clearBackToTableRowContext(){this.clearBackTo(G7,be.HTML)}remove(t){const n=this._indexOf(t);n>=0&&(n===this.stackTop?this.pop():(this.items.splice(n,1),this.tagIDs.splice(n,1),this.stackTop--,this._updateCurrentElement(),this.handler.onItemPop(t,!1)))}tryPeekProperlyNestedBodyElement(){return this.stackTop>=1&&this.tagIDs[1]===y.BODY?this.items[1]:null}contains(t){return this._indexOf(t)>-1}getCommonAncestor(t){const n=this._indexOf(t)-1;return n>=0?this.items[n]:null}isRootHtmlElementCurrent(){return this.stackTop===0&&this.tagIDs[0]===y.HTML}hasInDynamicScope(t,n){for(let i=this.stackTop;i>=0;i--){const u=this.tagIDs[i];switch(this.treeAdapter.getNamespaceURI(this.items[i])){case be.HTML:{if(u===t)return!0;if(n.has(u))return!1;break}case be.SVG:{if(t2.has(u))return!1;break}case be.MATHML:{if(e2.has(u))return!1;break}}}return!0}hasInScope(t){return this.hasInDynamicScope(t,Gf)}hasInListItemScope(t){return this.hasInDynamicScope(t,q7)}hasInButtonScope(t){return this.hasInDynamicScope(t,Y7)}hasNumberedHeaderInScope(){for(let t=this.stackTop;t>=0;t--){const n=this.tagIDs[t];switch(this.treeAdapter.getNamespaceURI(this.items[t])){case be.HTML:{if(D0.has(n))return!0;if(Gf.has(n))return!1;break}case be.SVG:{if(t2.has(n))return!1;break}case be.MATHML:{if(e2.has(n))return!1;break}}}return!0}hasInTableScope(t){for(let n=this.stackTop;n>=0;n--)if(this.treeAdapter.getNamespaceURI(this.items[n])===be.HTML)switch(this.tagIDs[n]){case t:return!0;case y.TABLE:case y.HTML:return!1}return!0}hasTableBodyContextInTableScope(){for(let t=this.stackTop;t>=0;t--)if(this.treeAdapter.getNamespaceURI(this.items[t])===be.HTML)switch(this.tagIDs[t]){case y.TBODY:case y.THEAD:case y.TFOOT:return!0;case y.TABLE:case y.HTML:return!1}return!0}hasInSelectScope(t){for(let n=this.stackTop;n>=0;n--)if(this.treeAdapter.getNamespaceURI(this.items[n])===be.HTML)switch(this.tagIDs[n]){case t:return!0;case y.OPTION:case y.OPTGROUP:break;default:return!1}return!0}generateImpliedEndTags(){for(;this.currentTagId!==void 0&&O_.has(this.currentTagId);)this.pop()}generateImpliedEndTagsThoroughly(){for(;this.currentTagId!==void 0&&JS.has(this.currentTagId);)this.pop()}generateImpliedEndTagsWithExclusion(t){for(;this.currentTagId!==void 0&&this.currentTagId!==t&&JS.has(this.currentTagId);)this.pop()}}const Dp=3;var hi;(function(e){e[e.Marker=0]="Marker",e[e.Element=1]="Element"})(hi||(hi={}));const n2={type:hi.Marker};class $7{constructor(t){this.treeAdapter=t,this.entries=[],this.bookmark=null}_getNoahArkConditionCandidates(t,n){const i=[],u=n.length,o=this.treeAdapter.getTagName(t),l=this.treeAdapter.getNamespaceURI(t);for(let f=0;f<this.entries.length;f++){const d=this.entries[f];if(d.type===hi.Marker)break;const{element:h}=d;if(this.treeAdapter.getTagName(h)===o&&this.treeAdapter.getNamespaceURI(h)===l){const p=this.treeAdapter.getAttrList(h);p.length===u&&i.push({idx:f,attrs:p})}}return i}_ensureNoahArkCondition(t){if(this.entries.length<Dp)return;const n=this.treeAdapter.getAttrList(t),i=this._getNoahArkConditionCandidates(t,n);if(i.length<Dp)return;const u=new Map(n.map(l=>[l.name,l.value]));let o=0;for(let l=0;l<i.length;l++){const f=i[l];f.attrs.every(d=>u.get(d.name)===d.value)&&(o+=1,o>=Dp&&this.entries.splice(f.idx,1))}}insertMarker(){this.entries.unshift(n2)}pushElement(t,n){this._ensureNoahArkCondition(t),this.entries.unshift({type:hi.Element,element:t,token:n})}insertElementAfterBookmark(t,n){const i=this.entries.indexOf(this.bookmark);this.entries.splice(i,0,{type:hi.Element,element:t,token:n})}removeEntry(t){const n=this.entries.indexOf(t);n!==-1&&this.entries.splice(n,1)}clearToLastMarker(){const t=this.entries.indexOf(n2);t===-1?this.entries.length=0:this.entries.splice(0,t+1)}getElementEntryInScopeWithTagName(t){const n=this.entries.find(i=>i.type===hi.Marker||this.treeAdapter.getTagName(i.element)===t);return n&&n.type===hi.Element?n:null}getElementEntry(t){return this.entries.find(n=>n.type===hi.Element&&n.element===t)}}const Ea={createDocument(){return{nodeName:"#document",mode:Fr.NO_QUIRKS,childNodes:[]}},createDocumentFragment(){return{nodeName:"#document-fragment",childNodes:[]}},createElement(e,t,n){return{nodeName:e,tagName:e,attrs:n,namespaceURI:t,childNodes:[],parentNode:null}},createCommentNode(e){return{nodeName:"#comment",data:e,parentNode:null}},createTextNode(e){return{nodeName:"#text",value:e,parentNode:null}},appendChild(e,t){e.childNodes.push(t),t.parentNode=e},insertBefore(e,t,n){const i=e.childNodes.indexOf(n);e.childNodes.splice(i,0,t),t.parentNode=e},setTemplateContent(e,t){e.content=t},getTemplateContent(e){return e.content},setDocumentType(e,t,n,i){const u=e.childNodes.find(o=>o.nodeName==="#documentType");if(u)u.name=t,u.publicId=n,u.systemId=i;else{const o={nodeName:"#documentType",name:t,publicId:n,systemId:i,parentNode:null};Ea.appendChild(e,o)}},setDocumentMode(e,t){e.mode=t},getDocumentMode(e){return e.mode},detachNode(e){if(e.parentNode){const t=e.parentNode.childNodes.indexOf(e);e.parentNode.childNodes.splice(t,1),e.parentNode=null}},insertText(e,t){if(e.childNodes.length>0){const n=e.childNodes[e.childNodes.length-1];if(Ea.isTextNode(n)){n.value+=t;return}}Ea.appendChild(e,Ea.createTextNode(t))},insertTextBefore(e,t,n){const i=e.childNodes[e.childNodes.indexOf(n)-1];i&&Ea.isTextNode(i)?i.value+=t:Ea.insertBefore(e,Ea.createTextNode(t),n)},adoptAttributes(e,t){const n=new Set(e.attrs.map(i=>i.name));for(let i=0;i<t.length;i++)n.has(t[i].name)||e.attrs.push(t[i])},getFirstChild(e){return e.childNodes[0]},getChildNodes(e){return e.childNodes},getParentNode(e){return e.parentNode},getAttrList(e){return e.attrs},getTagName(e){return e.tagName},getNamespaceURI(e){return e.namespaceURI},getTextNodeContent(e){return e.value},getCommentNodeContent(e){return e.data},getDocumentTypeNodeName(e){return e.name},getDocumentTypeNodePublicId(e){return e.publicId},getDocumentTypeNodeSystemId(e){return e.systemId},isTextNode(e){return e.nodeName==="#text"},isCommentNode(e){return e.nodeName==="#comment"},isDocumentTypeNode(e){return e.nodeName==="#documentType"},isElementNode(e){return Object.prototype.hasOwnProperty.call(e,"tagName")},setNodeSourceCodeLocation(e,t){e.sourceCodeLocation=t},getNodeSourceCodeLocation(e){return e.sourceCodeLocation},updateNodeSourceCodeLocation(e,t){e.sourceCodeLocation={...e.sourceCodeLocation,...t}}},N_="html",Z7="about:legacy-compat",J7="http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd",k_=["+//silmaril//dtd html pro v0r11 19970101//","-//as//dtd html 3.0 aswedit + extensions//","-//advasoft ltd//dtd html 3.0 aswedit + extensions//","-//ietf//dtd html 2.0 level 1//","-//ietf//dtd html 2.0 level 2//","-//ietf//dtd html 2.0 strict level 1//","-//ietf//dtd html 2.0 strict level 2//","-//ietf//dtd html 2.0 strict//","-//ietf//dtd html 2.0//","-//ietf//dtd html 2.1e//","-//ietf//dtd html 3.0//","-//ietf//dtd html 3.2 final//","-//ietf//dtd html 3.2//","-//ietf//dtd html 3//","-//ietf//dtd html level 0//","-//ietf//dtd html level 1//","-//ietf//dtd html level 2//","-//ietf//dtd html level 3//","-//ietf//dtd html strict level 0//","-//ietf//dtd html strict level 1//","-//ietf//dtd html strict level 2//","-//ietf//dtd html strict level 3//","-//ietf//dtd html strict//","-//ietf//dtd html//","-//metrius//dtd metrius presentational//","-//microsoft//dtd internet explorer 2.0 html strict//","-//microsoft//dtd internet explorer 2.0 html//","-//microsoft//dtd internet explorer 2.0 tables//","-//microsoft//dtd internet explorer 3.0 html strict//","-//microsoft//dtd internet explorer 3.0 html//","-//microsoft//dtd internet explorer 3.0 tables//","-//netscape comm. corp.//dtd html//","-//netscape comm. corp.//dtd strict html//","-//o'reilly and associates//dtd html 2.0//","-//o'reilly and associates//dtd html extended 1.0//","-//o'reilly and associates//dtd html extended relaxed 1.0//","-//sq//dtd html 2.0 hotmetal + extensions//","-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//","-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//","-//spyglass//dtd html 2.0 extended//","-//sun microsystems corp.//dtd hotjava html//","-//sun microsystems corp.//dtd hotjava strict html//","-//w3c//dtd html 3 1995-03-24//","-//w3c//dtd html 3.2 draft//","-//w3c//dtd html 3.2 final//","-//w3c//dtd html 3.2//","-//w3c//dtd html 3.2s draft//","-//w3c//dtd html 4.0 frameset//","-//w3c//dtd html 4.0 transitional//","-//w3c//dtd html experimental 19960712//","-//w3c//dtd html experimental 970421//","-//w3c//dtd w3 html//","-//w3o//dtd w3 html 3.0//","-//webtechs//dtd mozilla html 2.0//","-//webtechs//dtd mozilla html//"],eU=[...k_,"-//w3c//dtd html 4.01 frameset//","-//w3c//dtd html 4.01 transitional//"],tU=new Set(["-//w3o//dtd w3 html strict 3.0//en//","-/w3c/dtd html 4.0 transitional/en","html"]),L_=["-//w3c//dtd xhtml 1.0 frameset//","-//w3c//dtd xhtml 1.0 transitional//"],nU=[...L_,"-//w3c//dtd html 4.01 frameset//","-//w3c//dtd html 4.01 transitional//"];function r2(e,t){return t.some(n=>e.startsWith(n))}function rU(e){return e.name===N_&&e.publicId===null&&(e.systemId===null||e.systemId===Z7)}function iU(e){if(e.name!==N_)return Fr.QUIRKS;const{systemId:t}=e;if(t&&t.toLowerCase()===J7)return Fr.QUIRKS;let{publicId:n}=e;if(n!==null){if(n=n.toLowerCase(),tU.has(n))return Fr.QUIRKS;let i=t===null?eU:k_;if(r2(n,i))return Fr.QUIRKS;if(i=t===null?L_:nU,r2(n,i))return Fr.LIMITED_QUIRKS}return Fr.NO_QUIRKS}const i2={TEXT_HTML:"text/html",APPLICATION_XML:"application/xhtml+xml"},aU="definitionurl",uU="definitionURL",sU=new Map(["attributeName","attributeType","baseFrequency","baseProfile","calcMode","clipPathUnits","diffuseConstant","edgeMode","filterUnits","glyphRef","gradientTransform","gradientUnits","kernelMatrix","kernelUnitLength","keyPoints","keySplines","keyTimes","lengthAdjust","limitingConeAngle","markerHeight","markerUnits","markerWidth","maskContentUnits","maskUnits","numOctaves","pathLength","patternContentUnits","patternTransform","patternUnits","pointsAtX","pointsAtY","pointsAtZ","preserveAlpha","preserveAspectRatio","primitiveUnits","refX","refY","repeatCount","repeatDur","requiredExtensions","requiredFeatures","specularConstant","specularExponent","spreadMethod","startOffset","stdDeviation","stitchTiles","surfaceScale","systemLanguage","tableValues","targetX","targetY","textLength","viewBox","viewTarget","xChannelSelector","yChannelSelector","zoomAndPan"].map(e=>[e.toLowerCase(),e])),oU=new Map([["xlink:actuate",{prefix:"xlink",name:"actuate",namespace:be.XLINK}],["xlink:arcrole",{prefix:"xlink",name:"arcrole",namespace:be.XLINK}],["xlink:href",{prefix:"xlink",name:"href",namespace:be.XLINK}],["xlink:role",{prefix:"xlink",name:"role",namespace:be.XLINK}],["xlink:show",{prefix:"xlink",name:"show",namespace:be.XLINK}],["xlink:title",{prefix:"xlink",name:"title",namespace:be.XLINK}],["xlink:type",{prefix:"xlink",name:"type",namespace:be.XLINK}],["xml:lang",{prefix:"xml",name:"lang",namespace:be.XML}],["xml:space",{prefix:"xml",name:"space",namespace:be.XML}],["xmlns",{prefix:"",name:"xmlns",namespace:be.XMLNS}],["xmlns:xlink",{prefix:"xmlns",name:"xlink",namespace:be.XMLNS}]]),lU=new Map(["altGlyph","altGlyphDef","altGlyphItem","animateColor","animateMotion","animateTransform","clipPath","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","foreignObject","glyphRef","linearGradient","radialGradient","textPath"].map(e=>[e.toLowerCase(),e])),cU=new Set([y.B,y.BIG,y.BLOCKQUOTE,y.BODY,y.BR,y.CENTER,y.CODE,y.DD,y.DIV,y.DL,y.DT,y.EM,y.EMBED,y.H1,y.H2,y.H3,y.H4,y.H5,y.H6,y.HEAD,y.HR,y.I,y.IMG,y.LI,y.LISTING,y.MENU,y.META,y.NOBR,y.OL,y.P,y.PRE,y.RUBY,y.S,y.SMALL,y.SPAN,y.STRONG,y.STRIKE,y.SUB,y.SUP,y.TABLE,y.TT,y.U,y.UL,y.VAR]);function fU(e){const t=e.tagID;return t===y.FONT&&e.attrs.some(({name:i})=>i===ou.COLOR||i===ou.SIZE||i===ou.FACE)||cU.has(t)}function M_(e){for(let t=0;t<e.attrs.length;t++)if(e.attrs[t].name===aU){e.attrs[t].name=uU;break}}function I_(e){for(let t=0;t<e.attrs.length;t++){const n=sU.get(e.attrs[t].name);n!=null&&(e.attrs[t].name=n)}}function Yg(e){for(let t=0;t<e.attrs.length;t++){const n=oU.get(e.attrs[t].name);n&&(e.attrs[t].prefix=n.prefix,e.attrs[t].name=n.name,e.attrs[t].namespace=n.namespace)}}function dU(e){const t=lU.get(e.tagName);t!=null&&(e.tagName=t,e.tagID=_s(e.tagName))}function hU(e,t){return t===be.MATHML&&(e===y.MI||e===y.MO||e===y.MN||e===y.MS||e===y.MTEXT)}function mU(e,t,n){if(t===be.MATHML&&e===y.ANNOTATION_XML){for(let i=0;i<n.length;i++)if(n[i].name===ou.ENCODING){const u=n[i].value.toLowerCase();return u===i2.TEXT_HTML||u===i2.APPLICATION_XML}}return t===be.SVG&&(e===y.FOREIGN_OBJECT||e===y.DESC||e===y.TITLE)}function pU(e,t,n,i){return(!i||i===be.HTML)&&mU(e,t,n)||(!i||i===be.MATHML)&&hU(e,t)}const gU="hidden",EU=8,yU=3;var U;(function(e){e[e.INITIAL=0]="INITIAL",e[e.BEFORE_HTML=1]="BEFORE_HTML",e[e.BEFORE_HEAD=2]="BEFORE_HEAD",e[e.IN_HEAD=3]="IN_HEAD",e[e.IN_HEAD_NO_SCRIPT=4]="IN_HEAD_NO_SCRIPT",e[e.AFTER_HEAD=5]="AFTER_HEAD",e[e.IN_BODY=6]="IN_BODY",e[e.TEXT=7]="TEXT",e[e.IN_TABLE=8]="IN_TABLE",e[e.IN_TABLE_TEXT=9]="IN_TABLE_TEXT",e[e.IN_CAPTION=10]="IN_CAPTION",e[e.IN_COLUMN_GROUP=11]="IN_COLUMN_GROUP",e[e.IN_TABLE_BODY=12]="IN_TABLE_BODY",e[e.IN_ROW=13]="IN_ROW",e[e.IN_CELL=14]="IN_CELL",e[e.IN_SELECT=15]="IN_SELECT",e[e.IN_SELECT_IN_TABLE=16]="IN_SELECT_IN_TABLE",e[e.IN_TEMPLATE=17]="IN_TEMPLATE",e[e.AFTER_BODY=18]="AFTER_BODY",e[e.IN_FRAMESET=19]="IN_FRAMESET",e[e.AFTER_FRAMESET=20]="AFTER_FRAMESET",e[e.AFTER_AFTER_BODY=21]="AFTER_AFTER_BODY",e[e.AFTER_AFTER_FRAMESET=22]="AFTER_AFTER_FRAMESET"})(U||(U={}));const bU={startLine:-1,startCol:-1,startOffset:-1,endLine:-1,endCol:-1,endOffset:-1},P_=new Set([y.TABLE,y.TBODY,y.TFOOT,y.THEAD,y.TR]),a2={scriptingEnabled:!0,sourceCodeLocationInfo:!1,treeAdapter:Ea,onParseError:null};class u2{constructor(t,n,i=null,u=null){this.fragmentContext=i,this.scriptHandler=u,this.currentToken=null,this.stopped=!1,this.insertionMode=U.INITIAL,this.originalInsertionMode=U.INITIAL,this.headElement=null,this.formElement=null,this.currentNotInHTML=!1,this.tmplInsertionModeStack=[],this.pendingCharacterTokens=[],this.hasNonWhitespacePendingCharacterToken=!1,this.framesetOk=!0,this.skipNextNewLine=!1,this.fosterParentingEnabled=!1,this.options={...a2,...t},this.treeAdapter=this.options.treeAdapter,this.onParseError=this.options.onParseError,this.onParseError&&(this.options.sourceCodeLocationInfo=!0),this.document=n??this.treeAdapter.createDocument(),this.tokenizer=new j7(this.options,this),this.activeFormattingElements=new $7(this.treeAdapter),this.fragmentContextID=i?_s(this.treeAdapter.getTagName(i)):y.UNKNOWN,this._setContextModes(i??this.document,this.fragmentContextID),this.openElements=new Q7(this.document,this.treeAdapter,this)}static parse(t,n){const i=new this(n);return i.tokenizer.write(t,!0),i.document}static getFragmentParser(t,n){const i={...a2,...n};t??(t=i.treeAdapter.createElement(ie.TEMPLATE,be.HTML,[]));const u=i.treeAdapter.createElement("documentmock",be.HTML,[]),o=new this(i,u,t);return o.fragmentContextID===y.TEMPLATE&&o.tmplInsertionModeStack.unshift(U.IN_TEMPLATE),o._initTokenizerForFragmentParsing(),o._insertFakeRootElement(),o._resetInsertionMode(),o._findFormInFragmentContext(),o}getFragment(){const t=this.treeAdapter.getFirstChild(this.document),n=this.treeAdapter.createDocumentFragment();return this._adoptNodes(t,n),n}_err(t,n,i){var u;if(!this.onParseError)return;const o=(u=t.location)!==null&&u!==void 0?u:bU,l={code:n,startLine:o.startLine,startCol:o.startCol,startOffset:o.startOffset,endLine:i?o.startLine:o.endLine,endCol:i?o.startCol:o.endCol,endOffset:i?o.startOffset:o.endOffset};this.onParseError(l)}onItemPush(t,n,i){var u,o;(o=(u=this.treeAdapter).onItemPush)===null||o===void 0||o.call(u,t),i&&this.openElements.stackTop>0&&this._setContextModes(t,n)}onItemPop(t,n){var i,u;if(this.options.sourceCodeLocationInfo&&this._setEndLocation(t,this.currentToken),(u=(i=this.treeAdapter).onItemPop)===null||u===void 0||u.call(i,t,this.openElements.current),n){let o,l;this.openElements.stackTop===0&&this.fragmentContext?(o=this.fragmentContext,l=this.fragmentContextID):{current:o,currentTagId:l}=this.openElements,this._setContextModes(o,l)}}_setContextModes(t,n){const i=t===this.document||t&&this.treeAdapter.getNamespaceURI(t)===be.HTML;this.currentNotInHTML=!i,this.tokenizer.inForeignNode=!i&&t!==void 0&&n!==void 0&&!this._isIntegrationPoint(n,t)}_switchToTextParsing(t,n){this._insertElement(t,be.HTML),this.tokenizer.state=n,this.originalInsertionMode=this.insertionMode,this.insertionMode=U.TEXT}switchToPlaintextParsing(){this.insertionMode=U.TEXT,this.originalInsertionMode=U.IN_BODY,this.tokenizer.state=sn.PLAINTEXT}_getAdjustedCurrentElement(){return this.openElements.stackTop===0&&this.fragmentContext?this.fragmentContext:this.openElements.current}_findFormInFragmentContext(){let t=this.fragmentContext;for(;t;){if(this.treeAdapter.getTagName(t)===ie.FORM){this.formElement=t;break}t=this.treeAdapter.getParentNode(t)}}_initTokenizerForFragmentParsing(){if(!(!this.fragmentContext||this.treeAdapter.getNamespaceURI(this.fragmentContext)!==be.HTML))switch(this.fragmentContextID){case y.TITLE:case y.TEXTAREA:{this.tokenizer.state=sn.RCDATA;break}case y.STYLE:case y.XMP:case y.IFRAME:case y.NOEMBED:case y.NOFRAMES:case y.NOSCRIPT:{this.tokenizer.state=sn.RAWTEXT;break}case y.SCRIPT:{this.tokenizer.state=sn.SCRIPT_DATA;break}case y.PLAINTEXT:{this.tokenizer.state=sn.PLAINTEXT;break}}}_setDocumentType(t){const n=t.name||"",i=t.publicId||"",u=t.systemId||"";if(this.treeAdapter.setDocumentType(this.document,n,i,u),t.location){const l=this.treeAdapter.getChildNodes(this.document).find(f=>this.treeAdapter.isDocumentTypeNode(f));l&&this.treeAdapter.setNodeSourceCodeLocation(l,t.location)}}_attachElementToTree(t,n){if(this.options.sourceCodeLocationInfo){const i=n&&{...n,startTag:n};this.treeAdapter.setNodeSourceCodeLocation(t,i)}if(this._shouldFosterParentOnInsertion())this._fosterParentElement(t);else{const i=this.openElements.currentTmplContentOrNode;this.treeAdapter.appendChild(i??this.document,t)}}_appendElement(t,n){const i=this.treeAdapter.createElement(t.tagName,n,t.attrs);this._attachElementToTree(i,t.location)}_insertElement(t,n){const i=this.treeAdapter.createElement(t.tagName,n,t.attrs);this._attachElementToTree(i,t.location),this.openElements.push(i,t.tagID)}_insertFakeElement(t,n){const i=this.treeAdapter.createElement(t,be.HTML,[]);this._attachElementToTree(i,null),this.openElements.push(i,n)}_insertTemplate(t){const n=this.treeAdapter.createElement(t.tagName,be.HTML,t.attrs),i=this.treeAdapter.createDocumentFragment();this.treeAdapter.setTemplateContent(n,i),this._attachElementToTree(n,t.location),this.openElements.push(n,t.tagID),this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(i,null)}_insertFakeRootElement(){const t=this.treeAdapter.createElement(ie.HTML,be.HTML,[]);this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(t,null),this.treeAdapter.appendChild(this.openElements.current,t),this.openElements.push(t,y.HTML)}_appendCommentNode(t,n){const i=this.treeAdapter.createCommentNode(t.data);this.treeAdapter.appendChild(n,i),this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(i,t.location)}_insertCharacters(t){let n,i;if(this._shouldFosterParentOnInsertion()?({parent:n,beforeElement:i}=this._findFosterParentingLocation(),i?this.treeAdapter.insertTextBefore(n,t.chars,i):this.treeAdapter.insertText(n,t.chars)):(n=this.openElements.currentTmplContentOrNode,this.treeAdapter.insertText(n,t.chars)),!t.location)return;const u=this.treeAdapter.getChildNodes(n),o=i?u.lastIndexOf(i):u.length,l=u[o-1];if(this.treeAdapter.getNodeSourceCodeLocation(l)){const{endLine:d,endCol:h,endOffset:p}=t.location;this.treeAdapter.updateNodeSourceCodeLocation(l,{endLine:d,endCol:h,endOffset:p})}else this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(l,t.location)}_adoptNodes(t,n){for(let i=this.treeAdapter.getFirstChild(t);i;i=this.treeAdapter.getFirstChild(t))this.treeAdapter.detachNode(i),this.treeAdapter.appendChild(n,i)}_setEndLocation(t,n){if(this.treeAdapter.getNodeSourceCodeLocation(t)&&n.location){const i=n.location,u=this.treeAdapter.getTagName(t),o=n.type===st.END_TAG&&u===n.tagName?{endTag:{...i},endLine:i.endLine,endCol:i.endCol,endOffset:i.endOffset}:{endLine:i.startLine,endCol:i.startCol,endOffset:i.startOffset};this.treeAdapter.updateNodeSourceCodeLocation(t,o)}}shouldProcessStartTagTokenInForeignContent(t){if(!this.currentNotInHTML)return!1;let n,i;return this.openElements.stackTop===0&&this.fragmentContext?(n=this.fragmentContext,i=this.fragmentContextID):{current:n,currentTagId:i}=this.openElements,t.tagID===y.SVG&&this.treeAdapter.getTagName(n)===ie.ANNOTATION_XML&&this.treeAdapter.getNamespaceURI(n)===be.MATHML?!1:this.tokenizer.inForeignNode||(t.tagID===y.MGLYPH||t.tagID===y.MALIGNMARK)&&i!==void 0&&!this._isIntegrationPoint(i,n,be.HTML)}_processToken(t){switch(t.type){case st.CHARACTER:{this.onCharacter(t);break}case st.NULL_CHARACTER:{this.onNullCharacter(t);break}case st.COMMENT:{this.onComment(t);break}case st.DOCTYPE:{this.onDoctype(t);break}case st.START_TAG:{this._processStartTag(t);break}case st.END_TAG:{this.onEndTag(t);break}case st.EOF:{this.onEof(t);break}case st.WHITESPACE_CHARACTER:{this.onWhitespaceCharacter(t);break}}}_isIntegrationPoint(t,n,i){const u=this.treeAdapter.getNamespaceURI(n),o=this.treeAdapter.getAttrList(n);return pU(t,u,o,i)}_reconstructActiveFormattingElements(){const t=this.activeFormattingElements.entries.length;if(t){const n=this.activeFormattingElements.entries.findIndex(u=>u.type===hi.Marker||this.openElements.contains(u.element)),i=n===-1?t-1:n-1;for(let u=i;u>=0;u--){const o=this.activeFormattingElements.entries[u];this._insertElement(o.token,this.treeAdapter.getNamespaceURI(o.element)),o.element=this.openElements.current}}}_closeTableCell(){this.openElements.generateImpliedEndTags(),this.openElements.popUntilTableCellPopped(),this.activeFormattingElements.clearToLastMarker(),this.insertionMode=U.IN_ROW}_closePElement(){this.openElements.generateImpliedEndTagsWithExclusion(y.P),this.openElements.popUntilTagNamePopped(y.P)}_resetInsertionMode(){for(let t=this.openElements.stackTop;t>=0;t--)switch(t===0&&this.fragmentContext?this.fragmentContextID:this.openElements.tagIDs[t]){case y.TR:{this.insertionMode=U.IN_ROW;return}case y.TBODY:case y.THEAD:case y.TFOOT:{this.insertionMode=U.IN_TABLE_BODY;return}case y.CAPTION:{this.insertionMode=U.IN_CAPTION;return}case y.COLGROUP:{this.insertionMode=U.IN_COLUMN_GROUP;return}case y.TABLE:{this.insertionMode=U.IN_TABLE;return}case y.BODY:{this.insertionMode=U.IN_BODY;return}case y.FRAMESET:{this.insertionMode=U.IN_FRAMESET;return}case y.SELECT:{this._resetInsertionModeForSelect(t);return}case y.TEMPLATE:{this.insertionMode=this.tmplInsertionModeStack[0];return}case y.HTML:{this.insertionMode=this.headElement?U.AFTER_HEAD:U.BEFORE_HEAD;return}case y.TD:case y.TH:{if(t>0){this.insertionMode=U.IN_CELL;return}break}case y.HEAD:{if(t>0){this.insertionMode=U.IN_HEAD;return}break}}this.insertionMode=U.IN_BODY}_resetInsertionModeForSelect(t){if(t>0)for(let n=t-1;n>0;n--){const i=this.openElements.tagIDs[n];if(i===y.TEMPLATE)break;if(i===y.TABLE){this.insertionMode=U.IN_SELECT_IN_TABLE;return}}this.insertionMode=U.IN_SELECT}_isElementCausesFosterParenting(t){return P_.has(t)}_shouldFosterParentOnInsertion(){return this.fosterParentingEnabled&&this.openElements.currentTagId!==void 0&&this._isElementCausesFosterParenting(this.openElements.currentTagId)}_findFosterParentingLocation(){for(let t=this.openElements.stackTop;t>=0;t--){const n=this.openElements.items[t];switch(this.openElements.tagIDs[t]){case y.TEMPLATE:{if(this.treeAdapter.getNamespaceURI(n)===be.HTML)return{parent:this.treeAdapter.getTemplateContent(n),beforeElement:null};break}case y.TABLE:{const i=this.treeAdapter.getParentNode(n);return i?{parent:i,beforeElement:n}:{parent:this.openElements.items[t-1],beforeElement:null}}}}return{parent:this.openElements.items[0],beforeElement:null}}_fosterParentElement(t){const n=this._findFosterParentingLocation();n.beforeElement?this.treeAdapter.insertBefore(n.parent,t,n.beforeElement):this.treeAdapter.appendChild(n.parent,t)}_isSpecialElement(t,n){const i=this.treeAdapter.getNamespaceURI(t);return U7[i].has(n)}onCharacter(t){if(this.skipNextNewLine=!1,this.tokenizer.inForeignNode){WH(this,t);return}switch(this.insertionMode){case U.INITIAL:{jo(this,t);break}case U.BEFORE_HTML:{ll(this,t);break}case U.BEFORE_HEAD:{cl(this,t);break}case U.IN_HEAD:{fl(this,t);break}case U.IN_HEAD_NO_SCRIPT:{dl(this,t);break}case U.AFTER_HEAD:{hl(this,t);break}case U.IN_BODY:case U.IN_CAPTION:case U.IN_CELL:case U.IN_TEMPLATE:{B_(this,t);break}case U.TEXT:case U.IN_SELECT:case U.IN_SELECT_IN_TABLE:{this._insertCharacters(t);break}case U.IN_TABLE:case U.IN_TABLE_BODY:case U.IN_ROW:{vp(this,t);break}case U.IN_TABLE_TEXT:{q_(this,t);break}case U.IN_COLUMN_GROUP:{Xf(this,t);break}case U.AFTER_BODY:{Kf(this,t);break}case U.AFTER_AFTER_BODY:{wf(this,t);break}}}onNullCharacter(t){if(this.skipNextNewLine=!1,this.tokenizer.inForeignNode){KH(this,t);return}switch(this.insertionMode){case U.INITIAL:{jo(this,t);break}case U.BEFORE_HTML:{ll(this,t);break}case U.BEFORE_HEAD:{cl(this,t);break}case U.IN_HEAD:{fl(this,t);break}case U.IN_HEAD_NO_SCRIPT:{dl(this,t);break}case U.AFTER_HEAD:{hl(this,t);break}case U.TEXT:{this._insertCharacters(t);break}case U.IN_TABLE:case U.IN_TABLE_BODY:case U.IN_ROW:{vp(this,t);break}case U.IN_COLUMN_GROUP:{Xf(this,t);break}case U.AFTER_BODY:{Kf(this,t);break}case U.AFTER_AFTER_BODY:{wf(this,t);break}}}onComment(t){if(this.skipNextNewLine=!1,this.currentNotInHTML){v0(this,t);return}switch(this.insertionMode){case U.INITIAL:case U.BEFORE_HTML:case U.BEFORE_HEAD:case U.IN_HEAD:case U.IN_HEAD_NO_SCRIPT:case U.AFTER_HEAD:case U.IN_BODY:case U.IN_TABLE:case U.IN_CAPTION:case U.IN_COLUMN_GROUP:case U.IN_TABLE_BODY:case U.IN_ROW:case U.IN_CELL:case U.IN_SELECT:case U.IN_SELECT_IN_TABLE:case U.IN_TEMPLATE:case U.IN_FRAMESET:case U.AFTER_FRAMESET:{v0(this,t);break}case U.IN_TABLE_TEXT:{qo(this,t);break}case U.AFTER_BODY:{_U(this,t);break}case U.AFTER_AFTER_BODY:case U.AFTER_AFTER_FRAMESET:{xU(this,t);break}}}onDoctype(t){switch(this.skipNextNewLine=!1,this.insertionMode){case U.INITIAL:{RU(this,t);break}case U.BEFORE_HEAD:case U.IN_HEAD:case U.IN_HEAD_NO_SCRIPT:case U.AFTER_HEAD:{this._err(t,fe.misplacedDoctype);break}case U.IN_TABLE_TEXT:{qo(this,t);break}}}onStartTag(t){this.skipNextNewLine=!1,this.currentToken=t,this._processStartTag(t),t.selfClosing&&!t.ackSelfClosing&&this._err(t,fe.nonVoidHtmlElementStartTagWithTrailingSolidus)}_processStartTag(t){this.shouldProcessStartTagTokenInForeignContent(t)?QH(this,t):this._startTagOutsideForeignContent(t)}_startTagOutsideForeignContent(t){switch(this.insertionMode){case U.INITIAL:{jo(this,t);break}case U.BEFORE_HTML:{wU(this,t);break}case U.BEFORE_HEAD:{NU(this,t);break}case U.IN_HEAD:{ei(this,t);break}case U.IN_HEAD_NO_SCRIPT:{MU(this,t);break}case U.AFTER_HEAD:{PU(this,t);break}case U.IN_BODY:{Fn(this,t);break}case U.IN_TABLE:{hs(this,t);break}case U.IN_TABLE_TEXT:{qo(this,t);break}case U.IN_CAPTION:{kH(this,t);break}case U.IN_COLUMN_GROUP:{Kg(this,t);break}case U.IN_TABLE_BODY:{pd(this,t);break}case U.IN_ROW:{gd(this,t);break}case U.IN_CELL:{IH(this,t);break}case U.IN_SELECT:{X_(this,t);break}case U.IN_SELECT_IN_TABLE:{FH(this,t);break}case U.IN_TEMPLATE:{UH(this,t);break}case U.AFTER_BODY:{zH(this,t);break}case U.IN_FRAMESET:{VH(this,t);break}case U.AFTER_FRAMESET:{qH(this,t);break}case U.AFTER_AFTER_BODY:{GH(this,t);break}case U.AFTER_AFTER_FRAMESET:{XH(this,t);break}}}onEndTag(t){this.skipNextNewLine=!1,this.currentToken=t,this.currentNotInHTML?$H(this,t):this._endTagOutsideForeignContent(t)}_endTagOutsideForeignContent(t){switch(this.insertionMode){case U.INITIAL:{jo(this,t);break}case U.BEFORE_HTML:{OU(this,t);break}case U.BEFORE_HEAD:{kU(this,t);break}case U.IN_HEAD:{LU(this,t);break}case U.IN_HEAD_NO_SCRIPT:{IU(this,t);break}case U.AFTER_HEAD:{FU(this,t);break}case U.IN_BODY:{md(this,t);break}case U.TEXT:{SH(this,t);break}case U.IN_TABLE:{_l(this,t);break}case U.IN_TABLE_TEXT:{qo(this,t);break}case U.IN_CAPTION:{LH(this,t);break}case U.IN_COLUMN_GROUP:{MH(this,t);break}case U.IN_TABLE_BODY:{C0(this,t);break}case U.IN_ROW:{G_(this,t);break}case U.IN_CELL:{PH(this,t);break}case U.IN_SELECT:{K_(this,t);break}case U.IN_SELECT_IN_TABLE:{BH(this,t);break}case U.IN_TEMPLATE:{HH(this,t);break}case U.AFTER_BODY:{Q_(this,t);break}case U.IN_FRAMESET:{jH(this,t);break}case U.AFTER_FRAMESET:{YH(this,t);break}case U.AFTER_AFTER_BODY:{wf(this,t);break}}}onEof(t){switch(this.insertionMode){case U.INITIAL:{jo(this,t);break}case U.BEFORE_HTML:{ll(this,t);break}case U.BEFORE_HEAD:{cl(this,t);break}case U.IN_HEAD:{fl(this,t);break}case U.IN_HEAD_NO_SCRIPT:{dl(this,t);break}case U.AFTER_HEAD:{hl(this,t);break}case U.IN_BODY:case U.IN_TABLE:case U.IN_CAPTION:case U.IN_COLUMN_GROUP:case U.IN_TABLE_BODY:case U.IN_ROW:case U.IN_CELL:case U.IN_SELECT:case U.IN_SELECT_IN_TABLE:{V_(this,t);break}case U.TEXT:{DH(this,t);break}case U.IN_TABLE_TEXT:{qo(this,t);break}case U.IN_TEMPLATE:{W_(this,t);break}case U.AFTER_BODY:case U.IN_FRAMESET:case U.AFTER_FRAMESET:case U.AFTER_AFTER_BODY:case U.AFTER_AFTER_FRAMESET:{Xg(this,t);break}}}onWhitespaceCharacter(t){if(this.skipNextNewLine&&(this.skipNextNewLine=!1,t.chars.charCodeAt(0)===k.LINE_FEED)){if(t.chars.length===1)return;t.chars=t.chars.substr(1)}if(this.tokenizer.inForeignNode){this._insertCharacters(t);return}switch(this.insertionMode){case U.IN_HEAD:case U.IN_HEAD_NO_SCRIPT:case U.AFTER_HEAD:case U.TEXT:case U.IN_COLUMN_GROUP:case U.IN_SELECT:case U.IN_SELECT_IN_TABLE:case U.IN_FRAMESET:case U.AFTER_FRAMESET:{this._insertCharacters(t);break}case U.IN_BODY:case U.IN_CAPTION:case U.IN_CELL:case U.IN_TEMPLATE:case U.AFTER_BODY:case U.AFTER_AFTER_BODY:case U.AFTER_AFTER_FRAMESET:{F_(this,t);break}case U.IN_TABLE:case U.IN_TABLE_BODY:case U.IN_ROW:{vp(this,t);break}case U.IN_TABLE_TEXT:{j_(this,t);break}}}}function TU(e,t){let n=e.activeFormattingElements.getElementEntryInScopeWithTagName(t.tagName);return n?e.openElements.contains(n.element)?e.openElements.hasInScope(t.tagID)||(n=null):(e.activeFormattingElements.removeEntry(n),n=null):z_(e,t),n}function AU(e,t){let n=null,i=e.openElements.stackTop;for(;i>=0;i--){const u=e.openElements.items[i];if(u===t.element)break;e._isSpecialElement(u,e.openElements.tagIDs[i])&&(n=u)}return n||(e.openElements.shortenToLength(Math.max(i,0)),e.activeFormattingElements.removeEntry(t)),n}function SU(e,t,n){let i=t,u=e.openElements.getCommonAncestor(t);for(let o=0,l=u;l!==n;o++,l=u){u=e.openElements.getCommonAncestor(l);const f=e.activeFormattingElements.getElementEntry(l),d=f&&o>=yU;!f||d?(d&&e.activeFormattingElements.removeEntry(f),e.openElements.remove(l)):(l=DU(e,f),i===t&&(e.activeFormattingElements.bookmark=f),e.treeAdapter.detachNode(i),e.treeAdapter.appendChild(l,i),i=l)}return i}function DU(e,t){const n=e.treeAdapter.getNamespaceURI(t.element),i=e.treeAdapter.createElement(t.token.tagName,n,t.token.attrs);return e.openElements.replace(t.element,i),t.element=i,i}function vU(e,t,n){const i=e.treeAdapter.getTagName(t),u=_s(i);if(e._isElementCausesFosterParenting(u))e._fosterParentElement(n);else{const o=e.treeAdapter.getNamespaceURI(t);u===y.TEMPLATE&&o===be.HTML&&(t=e.treeAdapter.getTemplateContent(t)),e.treeAdapter.appendChild(t,n)}}function CU(e,t,n){const i=e.treeAdapter.getNamespaceURI(n.element),{token:u}=n,o=e.treeAdapter.createElement(u.tagName,i,u.attrs);e._adoptNodes(t,o),e.treeAdapter.appendChild(t,o),e.activeFormattingElements.insertElementAfterBookmark(o,u),e.activeFormattingElements.removeEntry(n),e.openElements.remove(n.element),e.openElements.insertAfter(t,o,u.tagID)}function Gg(e,t){for(let n=0;n<EU;n++){const i=TU(e,t);if(!i)break;const u=AU(e,i);if(!u)break;e.activeFormattingElements.bookmark=i;const o=SU(e,u,i.element),l=e.openElements.getCommonAncestor(i.element);e.treeAdapter.detachNode(o),l&&vU(e,l,o),CU(e,u,i)}}function v0(e,t){e._appendCommentNode(t,e.openElements.currentTmplContentOrNode)}function _U(e,t){e._appendCommentNode(t,e.openElements.items[0])}function xU(e,t){e._appendCommentNode(t,e.document)}function Xg(e,t){if(e.stopped=!0,t.location){const n=e.fragmentContext?0:2;for(let i=e.openElements.stackTop;i>=n;i--)e._setEndLocation(e.openElements.items[i],t);if(!e.fragmentContext&&e.openElements.stackTop>=0){const i=e.openElements.items[0],u=e.treeAdapter.getNodeSourceCodeLocation(i);if(u&&!u.endTag&&(e._setEndLocation(i,t),e.openElements.stackTop>=1)){const o=e.openElements.items[1],l=e.treeAdapter.getNodeSourceCodeLocation(o);l&&!l.endTag&&e._setEndLocation(o,t)}}}}function RU(e,t){e._setDocumentType(t);const n=t.forceQuirks?Fr.QUIRKS:iU(t);rU(t)||e._err(t,fe.nonConformingDoctype),e.treeAdapter.setDocumentMode(e.document,n),e.insertionMode=U.BEFORE_HTML}function jo(e,t){e._err(t,fe.missingDoctype,!0),e.treeAdapter.setDocumentMode(e.document,Fr.QUIRKS),e.insertionMode=U.BEFORE_HTML,e._processToken(t)}function wU(e,t){t.tagID===y.HTML?(e._insertElement(t,be.HTML),e.insertionMode=U.BEFORE_HEAD):ll(e,t)}function OU(e,t){const n=t.tagID;(n===y.HTML||n===y.HEAD||n===y.BODY||n===y.BR)&&ll(e,t)}function ll(e,t){e._insertFakeRootElement(),e.insertionMode=U.BEFORE_HEAD,e._processToken(t)}function NU(e,t){switch(t.tagID){case y.HTML:{Fn(e,t);break}case y.HEAD:{e._insertElement(t,be.HTML),e.headElement=e.openElements.current,e.insertionMode=U.IN_HEAD;break}default:cl(e,t)}}function kU(e,t){const n=t.tagID;n===y.HEAD||n===y.BODY||n===y.HTML||n===y.BR?cl(e,t):e._err(t,fe.endTagWithoutMatchingOpenElement)}function cl(e,t){e._insertFakeElement(ie.HEAD,y.HEAD),e.headElement=e.openElements.current,e.insertionMode=U.IN_HEAD,e._processToken(t)}function ei(e,t){switch(t.tagID){case y.HTML:{Fn(e,t);break}case y.BASE:case y.BASEFONT:case y.BGSOUND:case y.LINK:case y.META:{e._appendElement(t,be.HTML),t.ackSelfClosing=!0;break}case y.TITLE:{e._switchToTextParsing(t,sn.RCDATA);break}case y.NOSCRIPT:{e.options.scriptingEnabled?e._switchToTextParsing(t,sn.RAWTEXT):(e._insertElement(t,be.HTML),e.insertionMode=U.IN_HEAD_NO_SCRIPT);break}case y.NOFRAMES:case y.STYLE:{e._switchToTextParsing(t,sn.RAWTEXT);break}case y.SCRIPT:{e._switchToTextParsing(t,sn.SCRIPT_DATA);break}case y.TEMPLATE:{e._insertTemplate(t),e.activeFormattingElements.insertMarker(),e.framesetOk=!1,e.insertionMode=U.IN_TEMPLATE,e.tmplInsertionModeStack.unshift(U.IN_TEMPLATE);break}case y.HEAD:{e._err(t,fe.misplacedStartTagForHeadElement);break}default:fl(e,t)}}function LU(e,t){switch(t.tagID){case y.HEAD:{e.openElements.pop(),e.insertionMode=U.AFTER_HEAD;break}case y.BODY:case y.BR:case y.HTML:{fl(e,t);break}case y.TEMPLATE:{pu(e,t);break}default:e._err(t,fe.endTagWithoutMatchingOpenElement)}}function pu(e,t){e.openElements.tmplCount>0?(e.openElements.generateImpliedEndTagsThoroughly(),e.openElements.currentTagId!==y.TEMPLATE&&e._err(t,fe.closingOfElementWithOpenChildElements),e.openElements.popUntilTagNamePopped(y.TEMPLATE),e.activeFormattingElements.clearToLastMarker(),e.tmplInsertionModeStack.shift(),e._resetInsertionMode()):e._err(t,fe.endTagWithoutMatchingOpenElement)}function fl(e,t){e.openElements.pop(),e.insertionMode=U.AFTER_HEAD,e._processToken(t)}function MU(e,t){switch(t.tagID){case y.HTML:{Fn(e,t);break}case y.BASEFONT:case y.BGSOUND:case y.HEAD:case y.LINK:case y.META:case y.NOFRAMES:case y.STYLE:{ei(e,t);break}case y.NOSCRIPT:{e._err(t,fe.nestedNoscriptInHead);break}default:dl(e,t)}}function IU(e,t){switch(t.tagID){case y.NOSCRIPT:{e.openElements.pop(),e.insertionMode=U.IN_HEAD;break}case y.BR:{dl(e,t);break}default:e._err(t,fe.endTagWithoutMatchingOpenElement)}}function dl(e,t){const n=t.type===st.EOF?fe.openElementsLeftAfterEof:fe.disallowedContentInNoscriptInHead;e._err(t,n),e.openElements.pop(),e.insertionMode=U.IN_HEAD,e._processToken(t)}function PU(e,t){switch(t.tagID){case y.HTML:{Fn(e,t);break}case y.BODY:{e._insertElement(t,be.HTML),e.framesetOk=!1,e.insertionMode=U.IN_BODY;break}case y.FRAMESET:{e._insertElement(t,be.HTML),e.insertionMode=U.IN_FRAMESET;break}case y.BASE:case y.BASEFONT:case y.BGSOUND:case y.LINK:case y.META:case y.NOFRAMES:case y.SCRIPT:case y.STYLE:case y.TEMPLATE:case y.TITLE:{e._err(t,fe.abandonedHeadElementChild),e.openElements.push(e.headElement,y.HEAD),ei(e,t),e.openElements.remove(e.headElement);break}case y.HEAD:{e._err(t,fe.misplacedStartTagForHeadElement);break}default:hl(e,t)}}function FU(e,t){switch(t.tagID){case y.BODY:case y.HTML:case y.BR:{hl(e,t);break}case y.TEMPLATE:{pu(e,t);break}default:e._err(t,fe.endTagWithoutMatchingOpenElement)}}function hl(e,t){e._insertFakeElement(ie.BODY,y.BODY),e.insertionMode=U.IN_BODY,hd(e,t)}function hd(e,t){switch(t.type){case st.CHARACTER:{B_(e,t);break}case st.WHITESPACE_CHARACTER:{F_(e,t);break}case st.COMMENT:{v0(e,t);break}case st.START_TAG:{Fn(e,t);break}case st.END_TAG:{md(e,t);break}case st.EOF:{V_(e,t);break}}}function F_(e,t){e._reconstructActiveFormattingElements(),e._insertCharacters(t)}function B_(e,t){e._reconstructActiveFormattingElements(),e._insertCharacters(t),e.framesetOk=!1}function BU(e,t){e.openElements.tmplCount===0&&e.treeAdapter.adoptAttributes(e.openElements.items[0],t.attrs)}function UU(e,t){const n=e.openElements.tryPeekProperlyNestedBodyElement();n&&e.openElements.tmplCount===0&&(e.framesetOk=!1,e.treeAdapter.adoptAttributes(n,t.attrs))}function HU(e,t){const n=e.openElements.tryPeekProperlyNestedBodyElement();e.framesetOk&&n&&(e.treeAdapter.detachNode(n),e.openElements.popAllUpToHtmlElement(),e._insertElement(t,be.HTML),e.insertionMode=U.IN_FRAMESET)}function zU(e,t){e.openElements.hasInButtonScope(y.P)&&e._closePElement(),e._insertElement(t,be.HTML)}function VU(e,t){e.openElements.hasInButtonScope(y.P)&&e._closePElement(),e.openElements.currentTagId!==void 0&&D0.has(e.openElements.currentTagId)&&e.openElements.pop(),e._insertElement(t,be.HTML)}function jU(e,t){e.openElements.hasInButtonScope(y.P)&&e._closePElement(),e._insertElement(t,be.HTML),e.skipNextNewLine=!0,e.framesetOk=!1}function qU(e,t){const n=e.openElements.tmplCount>0;(!e.formElement||n)&&(e.openElements.hasInButtonScope(y.P)&&e._closePElement(),e._insertElement(t,be.HTML),n||(e.formElement=e.openElements.current))}function YU(e,t){e.framesetOk=!1;const n=t.tagID;for(let i=e.openElements.stackTop;i>=0;i--){const u=e.openElements.tagIDs[i];if(n===y.LI&&u===y.LI||(n===y.DD||n===y.DT)&&(u===y.DD||u===y.DT)){e.openElements.generateImpliedEndTagsWithExclusion(u),e.openElements.popUntilTagNamePopped(u);break}if(u!==y.ADDRESS&&u!==y.DIV&&u!==y.P&&e._isSpecialElement(e.openElements.items[i],u))break}e.openElements.hasInButtonScope(y.P)&&e._closePElement(),e._insertElement(t,be.HTML)}function GU(e,t){e.openElements.hasInButtonScope(y.P)&&e._closePElement(),e._insertElement(t,be.HTML),e.tokenizer.state=sn.PLAINTEXT}function XU(e,t){e.openElements.hasInScope(y.BUTTON)&&(e.openElements.generateImpliedEndTags(),e.openElements.popUntilTagNamePopped(y.BUTTON)),e._reconstructActiveFormattingElements(),e._insertElement(t,be.HTML),e.framesetOk=!1}function KU(e,t){const n=e.activeFormattingElements.getElementEntryInScopeWithTagName(ie.A);n&&(Gg(e,t),e.openElements.remove(n.element),e.activeFormattingElements.removeEntry(n)),e._reconstructActiveFormattingElements(),e._insertElement(t,be.HTML),e.activeFormattingElements.pushElement(e.openElements.current,t)}function WU(e,t){e._reconstructActiveFormattingElements(),e._insertElement(t,be.HTML),e.activeFormattingElements.pushElement(e.openElements.current,t)}function QU(e,t){e._reconstructActiveFormattingElements(),e.openElements.hasInScope(y.NOBR)&&(Gg(e,t),e._reconstructActiveFormattingElements()),e._insertElement(t,be.HTML),e.activeFormattingElements.pushElement(e.openElements.current,t)}function $U(e,t){e._reconstructActiveFormattingElements(),e._insertElement(t,be.HTML),e.activeFormattingElements.insertMarker(),e.framesetOk=!1}function ZU(e,t){e.treeAdapter.getDocumentMode(e.document)!==Fr.QUIRKS&&e.openElements.hasInButtonScope(y.P)&&e._closePElement(),e._insertElement(t,be.HTML),e.framesetOk=!1,e.insertionMode=U.IN_TABLE}function U_(e,t){e._reconstructActiveFormattingElements(),e._appendElement(t,be.HTML),e.framesetOk=!1,t.ackSelfClosing=!0}function H_(e){const t=R_(e,ou.TYPE);return t!=null&&t.toLowerCase()===gU}function JU(e,t){e._reconstructActiveFormattingElements(),e._appendElement(t,be.HTML),H_(t)||(e.framesetOk=!1),t.ackSelfClosing=!0}function eH(e,t){e._appendElement(t,be.HTML),t.ackSelfClosing=!0}function tH(e,t){e.openElements.hasInButtonScope(y.P)&&e._closePElement(),e._appendElement(t,be.HTML),e.framesetOk=!1,t.ackSelfClosing=!0}function nH(e,t){t.tagName=ie.IMG,t.tagID=y.IMG,U_(e,t)}function rH(e,t){e._insertElement(t,be.HTML),e.skipNextNewLine=!0,e.tokenizer.state=sn.RCDATA,e.originalInsertionMode=e.insertionMode,e.framesetOk=!1,e.insertionMode=U.TEXT}function iH(e,t){e.openElements.hasInButtonScope(y.P)&&e._closePElement(),e._reconstructActiveFormattingElements(),e.framesetOk=!1,e._switchToTextParsing(t,sn.RAWTEXT)}function aH(e,t){e.framesetOk=!1,e._switchToTextParsing(t,sn.RAWTEXT)}function s2(e,t){e._switchToTextParsing(t,sn.RAWTEXT)}function uH(e,t){e._reconstructActiveFormattingElements(),e._insertElement(t,be.HTML),e.framesetOk=!1,e.insertionMode=e.insertionMode===U.IN_TABLE||e.insertionMode===U.IN_CAPTION||e.insertionMode===U.IN_TABLE_BODY||e.insertionMode===U.IN_ROW||e.insertionMode===U.IN_CELL?U.IN_SELECT_IN_TABLE:U.IN_SELECT}function sH(e,t){e.openElements.currentTagId===y.OPTION&&e.openElements.pop(),e._reconstructActiveFormattingElements(),e._insertElement(t,be.HTML)}function oH(e,t){e.openElements.hasInScope(y.RUBY)&&e.openElements.generateImpliedEndTags(),e._insertElement(t,be.HTML)}function lH(e,t){e.openElements.hasInScope(y.RUBY)&&e.openElements.generateImpliedEndTagsWithExclusion(y.RTC),e._insertElement(t,be.HTML)}function cH(e,t){e._reconstructActiveFormattingElements(),M_(t),Yg(t),t.selfClosing?e._appendElement(t,be.MATHML):e._insertElement(t,be.MATHML),t.ackSelfClosing=!0}function fH(e,t){e._reconstructActiveFormattingElements(),I_(t),Yg(t),t.selfClosing?e._appendElement(t,be.SVG):e._insertElement(t,be.SVG),t.ackSelfClosing=!0}function o2(e,t){e._reconstructActiveFormattingElements(),e._insertElement(t,be.HTML)}function Fn(e,t){switch(t.tagID){case y.I:case y.S:case y.B:case y.U:case y.EM:case y.TT:case y.BIG:case y.CODE:case y.FONT:case y.SMALL:case y.STRIKE:case y.STRONG:{WU(e,t);break}case y.A:{KU(e,t);break}case y.H1:case y.H2:case y.H3:case y.H4:case y.H5:case y.H6:{VU(e,t);break}case y.P:case y.DL:case y.OL:case y.UL:case y.DIV:case y.DIR:case y.NAV:case y.MAIN:case y.MENU:case y.ASIDE:case y.CENTER:case y.FIGURE:case y.FOOTER:case y.HEADER:case y.HGROUP:case y.DIALOG:case y.DETAILS:case y.ADDRESS:case y.ARTICLE:case y.SEARCH:case y.SECTION:case y.SUMMARY:case y.FIELDSET:case y.BLOCKQUOTE:case y.FIGCAPTION:{zU(e,t);break}case y.LI:case y.DD:case y.DT:{YU(e,t);break}case y.BR:case y.IMG:case y.WBR:case y.AREA:case y.EMBED:case y.KEYGEN:{U_(e,t);break}case y.HR:{tH(e,t);break}case y.RB:case y.RTC:{oH(e,t);break}case y.RT:case y.RP:{lH(e,t);break}case y.PRE:case y.LISTING:{jU(e,t);break}case y.XMP:{iH(e,t);break}case y.SVG:{fH(e,t);break}case y.HTML:{BU(e,t);break}case y.BASE:case y.LINK:case y.META:case y.STYLE:case y.TITLE:case y.SCRIPT:case y.BGSOUND:case y.BASEFONT:case y.TEMPLATE:{ei(e,t);break}case y.BODY:{UU(e,t);break}case y.FORM:{qU(e,t);break}case y.NOBR:{QU(e,t);break}case y.MATH:{cH(e,t);break}case y.TABLE:{ZU(e,t);break}case y.INPUT:{JU(e,t);break}case y.PARAM:case y.TRACK:case y.SOURCE:{eH(e,t);break}case y.IMAGE:{nH(e,t);break}case y.BUTTON:{XU(e,t);break}case y.APPLET:case y.OBJECT:case y.MARQUEE:{$U(e,t);break}case y.IFRAME:{aH(e,t);break}case y.SELECT:{uH(e,t);break}case y.OPTION:case y.OPTGROUP:{sH(e,t);break}case y.NOEMBED:case y.NOFRAMES:{s2(e,t);break}case y.FRAMESET:{HU(e,t);break}case y.TEXTAREA:{rH(e,t);break}case y.NOSCRIPT:{e.options.scriptingEnabled?s2(e,t):o2(e,t);break}case y.PLAINTEXT:{GU(e,t);break}case y.COL:case y.TH:case y.TD:case y.TR:case y.HEAD:case y.FRAME:case y.TBODY:case y.TFOOT:case y.THEAD:case y.CAPTION:case y.COLGROUP:break;default:o2(e,t)}}function dH(e,t){if(e.openElements.hasInScope(y.BODY)&&(e.insertionMode=U.AFTER_BODY,e.options.sourceCodeLocationInfo)){const n=e.openElements.tryPeekProperlyNestedBodyElement();n&&e._setEndLocation(n,t)}}function hH(e,t){e.openElements.hasInScope(y.BODY)&&(e.insertionMode=U.AFTER_BODY,Q_(e,t))}function mH(e,t){const n=t.tagID;e.openElements.hasInScope(n)&&(e.openElements.generateImpliedEndTags(),e.openElements.popUntilTagNamePopped(n))}function pH(e){const t=e.openElements.tmplCount>0,{formElement:n}=e;t||(e.formElement=null),(n||t)&&e.openElements.hasInScope(y.FORM)&&(e.openElements.generateImpliedEndTags(),t?e.openElements.popUntilTagNamePopped(y.FORM):n&&e.openElements.remove(n))}function gH(e){e.openElements.hasInButtonScope(y.P)||e._insertFakeElement(ie.P,y.P),e._closePElement()}function EH(e){e.openElements.hasInListItemScope(y.LI)&&(e.openElements.generateImpliedEndTagsWithExclusion(y.LI),e.openElements.popUntilTagNamePopped(y.LI))}function yH(e,t){const n=t.tagID;e.openElements.hasInScope(n)&&(e.openElements.generateImpliedEndTagsWithExclusion(n),e.openElements.popUntilTagNamePopped(n))}function bH(e){e.openElements.hasNumberedHeaderInScope()&&(e.openElements.generateImpliedEndTags(),e.openElements.popUntilNumberedHeaderPopped())}function TH(e,t){const n=t.tagID;e.openElements.hasInScope(n)&&(e.openElements.generateImpliedEndTags(),e.openElements.popUntilTagNamePopped(n),e.activeFormattingElements.clearToLastMarker())}function AH(e){e._reconstructActiveFormattingElements(),e._insertFakeElement(ie.BR,y.BR),e.openElements.pop(),e.framesetOk=!1}function z_(e,t){const n=t.tagName,i=t.tagID;for(let u=e.openElements.stackTop;u>0;u--){const o=e.openElements.items[u],l=e.openElements.tagIDs[u];if(i===l&&(i!==y.UNKNOWN||e.treeAdapter.getTagName(o)===n)){e.openElements.generateImpliedEndTagsWithExclusion(i),e.openElements.stackTop>=u&&e.openElements.shortenToLength(u);break}if(e._isSpecialElement(o,l))break}}function md(e,t){switch(t.tagID){case y.A:case y.B:case y.I:case y.S:case y.U:case y.EM:case y.TT:case y.BIG:case y.CODE:case y.FONT:case y.NOBR:case y.SMALL:case y.STRIKE:case y.STRONG:{Gg(e,t);break}case y.P:{gH(e);break}case y.DL:case y.UL:case y.OL:case y.DIR:case y.DIV:case y.NAV:case y.PRE:case y.MAIN:case y.MENU:case y.ASIDE:case y.BUTTON:case y.CENTER:case y.FIGURE:case y.FOOTER:case y.HEADER:case y.HGROUP:case y.DIALOG:case y.ADDRESS:case y.ARTICLE:case y.DETAILS:case y.SEARCH:case y.SECTION:case y.SUMMARY:case y.LISTING:case y.FIELDSET:case y.BLOCKQUOTE:case y.FIGCAPTION:{mH(e,t);break}case y.LI:{EH(e);break}case y.DD:case y.DT:{yH(e,t);break}case y.H1:case y.H2:case y.H3:case y.H4:case y.H5:case y.H6:{bH(e);break}case y.BR:{AH(e);break}case y.BODY:{dH(e,t);break}case y.HTML:{hH(e,t);break}case y.FORM:{pH(e);break}case y.APPLET:case y.OBJECT:case y.MARQUEE:{TH(e,t);break}case y.TEMPLATE:{pu(e,t);break}default:z_(e,t)}}function V_(e,t){e.tmplInsertionModeStack.length>0?W_(e,t):Xg(e,t)}function SH(e,t){var n;t.tagID===y.SCRIPT&&((n=e.scriptHandler)===null||n===void 0||n.call(e,e.openElements.current)),e.openElements.pop(),e.insertionMode=e.originalInsertionMode}function DH(e,t){e._err(t,fe.eofInElementThatCanContainOnlyText),e.openElements.pop(),e.insertionMode=e.originalInsertionMode,e.onEof(t)}function vp(e,t){if(e.openElements.currentTagId!==void 0&&P_.has(e.openElements.currentTagId))switch(e.pendingCharacterTokens.length=0,e.hasNonWhitespacePendingCharacterToken=!1,e.originalInsertionMode=e.insertionMode,e.insertionMode=U.IN_TABLE_TEXT,t.type){case st.CHARACTER:{q_(e,t);break}case st.WHITESPACE_CHARACTER:{j_(e,t);break}}else Ul(e,t)}function vH(e,t){e.openElements.clearBackToTableContext(),e.activeFormattingElements.insertMarker(),e._insertElement(t,be.HTML),e.insertionMode=U.IN_CAPTION}function CH(e,t){e.openElements.clearBackToTableContext(),e._insertElement(t,be.HTML),e.insertionMode=U.IN_COLUMN_GROUP}function _H(e,t){e.openElements.clearBackToTableContext(),e._insertFakeElement(ie.COLGROUP,y.COLGROUP),e.insertionMode=U.IN_COLUMN_GROUP,Kg(e,t)}function xH(e,t){e.openElements.clearBackToTableContext(),e._insertElement(t,be.HTML),e.insertionMode=U.IN_TABLE_BODY}function RH(e,t){e.openElements.clearBackToTableContext(),e._insertFakeElement(ie.TBODY,y.TBODY),e.insertionMode=U.IN_TABLE_BODY,pd(e,t)}function wH(e,t){e.openElements.hasInTableScope(y.TABLE)&&(e.openElements.popUntilTagNamePopped(y.TABLE),e._resetInsertionMode(),e._processStartTag(t))}function OH(e,t){H_(t)?e._appendElement(t,be.HTML):Ul(e,t),t.ackSelfClosing=!0}function NH(e,t){!e.formElement&&e.openElements.tmplCount===0&&(e._insertElement(t,be.HTML),e.formElement=e.openElements.current,e.openElements.pop())}function hs(e,t){switch(t.tagID){case y.TD:case y.TH:case y.TR:{RH(e,t);break}case y.STYLE:case y.SCRIPT:case y.TEMPLATE:{ei(e,t);break}case y.COL:{_H(e,t);break}case y.FORM:{NH(e,t);break}case y.TABLE:{wH(e,t);break}case y.TBODY:case y.TFOOT:case y.THEAD:{xH(e,t);break}case y.INPUT:{OH(e,t);break}case y.CAPTION:{vH(e,t);break}case y.COLGROUP:{CH(e,t);break}default:Ul(e,t)}}function _l(e,t){switch(t.tagID){case y.TABLE:{e.openElements.hasInTableScope(y.TABLE)&&(e.openElements.popUntilTagNamePopped(y.TABLE),e._resetInsertionMode());break}case y.TEMPLATE:{pu(e,t);break}case y.BODY:case y.CAPTION:case y.COL:case y.COLGROUP:case y.HTML:case y.TBODY:case y.TD:case y.TFOOT:case y.TH:case y.THEAD:case y.TR:break;default:Ul(e,t)}}function Ul(e,t){const n=e.fosterParentingEnabled;e.fosterParentingEnabled=!0,hd(e,t),e.fosterParentingEnabled=n}function j_(e,t){e.pendingCharacterTokens.push(t)}function q_(e,t){e.pendingCharacterTokens.push(t),e.hasNonWhitespacePendingCharacterToken=!0}function qo(e,t){let n=0;if(e.hasNonWhitespacePendingCharacterToken)for(;n<e.pendingCharacterTokens.length;n++)Ul(e,e.pendingCharacterTokens[n]);else for(;n<e.pendingCharacterTokens.length;n++)e._insertCharacters(e.pendingCharacterTokens[n]);e.insertionMode=e.originalInsertionMode,e._processToken(t)}const Y_=new Set([y.CAPTION,y.COL,y.COLGROUP,y.TBODY,y.TD,y.TFOOT,y.TH,y.THEAD,y.TR]);function kH(e,t){const n=t.tagID;Y_.has(n)?e.openElements.hasInTableScope(y.CAPTION)&&(e.openElements.generateImpliedEndTags(),e.openElements.popUntilTagNamePopped(y.CAPTION),e.activeFormattingElements.clearToLastMarker(),e.insertionMode=U.IN_TABLE,hs(e,t)):Fn(e,t)}function LH(e,t){const n=t.tagID;switch(n){case y.CAPTION:case y.TABLE:{e.openElements.hasInTableScope(y.CAPTION)&&(e.openElements.generateImpliedEndTags(),e.openElements.popUntilTagNamePopped(y.CAPTION),e.activeFormattingElements.clearToLastMarker(),e.insertionMode=U.IN_TABLE,n===y.TABLE&&_l(e,t));break}case y.BODY:case y.COL:case y.COLGROUP:case y.HTML:case y.TBODY:case y.TD:case y.TFOOT:case y.TH:case y.THEAD:case y.TR:break;default:md(e,t)}}function Kg(e,t){switch(t.tagID){case y.HTML:{Fn(e,t);break}case y.COL:{e._appendElement(t,be.HTML),t.ackSelfClosing=!0;break}case y.TEMPLATE:{ei(e,t);break}default:Xf(e,t)}}function MH(e,t){switch(t.tagID){case y.COLGROUP:{e.openElements.currentTagId===y.COLGROUP&&(e.openElements.pop(),e.insertionMode=U.IN_TABLE);break}case y.TEMPLATE:{pu(e,t);break}case y.COL:break;default:Xf(e,t)}}function Xf(e,t){e.openElements.currentTagId===y.COLGROUP&&(e.openElements.pop(),e.insertionMode=U.IN_TABLE,e._processToken(t))}function pd(e,t){switch(t.tagID){case y.TR:{e.openElements.clearBackToTableBodyContext(),e._insertElement(t,be.HTML),e.insertionMode=U.IN_ROW;break}case y.TH:case y.TD:{e.openElements.clearBackToTableBodyContext(),e._insertFakeElement(ie.TR,y.TR),e.insertionMode=U.IN_ROW,gd(e,t);break}case y.CAPTION:case y.COL:case y.COLGROUP:case y.TBODY:case y.TFOOT:case y.THEAD:{e.openElements.hasTableBodyContextInTableScope()&&(e.openElements.clearBackToTableBodyContext(),e.openElements.pop(),e.insertionMode=U.IN_TABLE,hs(e,t));break}default:hs(e,t)}}function C0(e,t){const n=t.tagID;switch(t.tagID){case y.TBODY:case y.TFOOT:case y.THEAD:{e.openElements.hasInTableScope(n)&&(e.openElements.clearBackToTableBodyContext(),e.openElements.pop(),e.insertionMode=U.IN_TABLE);break}case y.TABLE:{e.openElements.hasTableBodyContextInTableScope()&&(e.openElements.clearBackToTableBodyContext(),e.openElements.pop(),e.insertionMode=U.IN_TABLE,_l(e,t));break}case y.BODY:case y.CAPTION:case y.COL:case y.COLGROUP:case y.HTML:case y.TD:case y.TH:case y.TR:break;default:_l(e,t)}}function gd(e,t){switch(t.tagID){case y.TH:case y.TD:{e.openElements.clearBackToTableRowContext(),e._insertElement(t,be.HTML),e.insertionMode=U.IN_CELL,e.activeFormattingElements.insertMarker();break}case y.CAPTION:case y.COL:case y.COLGROUP:case y.TBODY:case y.TFOOT:case y.THEAD:case y.TR:{e.openElements.hasInTableScope(y.TR)&&(e.openElements.clearBackToTableRowContext(),e.openElements.pop(),e.insertionMode=U.IN_TABLE_BODY,pd(e,t));break}default:hs(e,t)}}function G_(e,t){switch(t.tagID){case y.TR:{e.openElements.hasInTableScope(y.TR)&&(e.openElements.clearBackToTableRowContext(),e.openElements.pop(),e.insertionMode=U.IN_TABLE_BODY);break}case y.TABLE:{e.openElements.hasInTableScope(y.TR)&&(e.openElements.clearBackToTableRowContext(),e.openElements.pop(),e.insertionMode=U.IN_TABLE_BODY,C0(e,t));break}case y.TBODY:case y.TFOOT:case y.THEAD:{(e.openElements.hasInTableScope(t.tagID)||e.openElements.hasInTableScope(y.TR))&&(e.openElements.clearBackToTableRowContext(),e.openElements.pop(),e.insertionMode=U.IN_TABLE_BODY,C0(e,t));break}case y.BODY:case y.CAPTION:case y.COL:case y.COLGROUP:case y.HTML:case y.TD:case y.TH:break;default:_l(e,t)}}function IH(e,t){const n=t.tagID;Y_.has(n)?(e.openElements.hasInTableScope(y.TD)||e.openElements.hasInTableScope(y.TH))&&(e._closeTableCell(),gd(e,t)):Fn(e,t)}function PH(e,t){const n=t.tagID;switch(n){case y.TD:case y.TH:{e.openElements.hasInTableScope(n)&&(e.openElements.generateImpliedEndTags(),e.openElements.popUntilTagNamePopped(n),e.activeFormattingElements.clearToLastMarker(),e.insertionMode=U.IN_ROW);break}case y.TABLE:case y.TBODY:case y.TFOOT:case y.THEAD:case y.TR:{e.openElements.hasInTableScope(n)&&(e._closeTableCell(),G_(e,t));break}case y.BODY:case y.CAPTION:case y.COL:case y.COLGROUP:case y.HTML:break;default:md(e,t)}}function X_(e,t){switch(t.tagID){case y.HTML:{Fn(e,t);break}case y.OPTION:{e.openElements.currentTagId===y.OPTION&&e.openElements.pop(),e._insertElement(t,be.HTML);break}case y.OPTGROUP:{e.openElements.currentTagId===y.OPTION&&e.openElements.pop(),e.openElements.currentTagId===y.OPTGROUP&&e.openElements.pop(),e._insertElement(t,be.HTML);break}case y.HR:{e.openElements.currentTagId===y.OPTION&&e.openElements.pop(),e.openElements.currentTagId===y.OPTGROUP&&e.openElements.pop(),e._appendElement(t,be.HTML),t.ackSelfClosing=!0;break}case y.INPUT:case y.KEYGEN:case y.TEXTAREA:case y.SELECT:{e.openElements.hasInSelectScope(y.SELECT)&&(e.openElements.popUntilTagNamePopped(y.SELECT),e._resetInsertionMode(),t.tagID!==y.SELECT&&e._processStartTag(t));break}case y.SCRIPT:case y.TEMPLATE:{ei(e,t);break}}}function K_(e,t){switch(t.tagID){case y.OPTGROUP:{e.openElements.stackTop>0&&e.openElements.currentTagId===y.OPTION&&e.openElements.tagIDs[e.openElements.stackTop-1]===y.OPTGROUP&&e.openElements.pop(),e.openElements.currentTagId===y.OPTGROUP&&e.openElements.pop();break}case y.OPTION:{e.openElements.currentTagId===y.OPTION&&e.openElements.pop();break}case y.SELECT:{e.openElements.hasInSelectScope(y.SELECT)&&(e.openElements.popUntilTagNamePopped(y.SELECT),e._resetInsertionMode());break}case y.TEMPLATE:{pu(e,t);break}}}function FH(e,t){const n=t.tagID;n===y.CAPTION||n===y.TABLE||n===y.TBODY||n===y.TFOOT||n===y.THEAD||n===y.TR||n===y.TD||n===y.TH?(e.openElements.popUntilTagNamePopped(y.SELECT),e._resetInsertionMode(),e._processStartTag(t)):X_(e,t)}function BH(e,t){const n=t.tagID;n===y.CAPTION||n===y.TABLE||n===y.TBODY||n===y.TFOOT||n===y.THEAD||n===y.TR||n===y.TD||n===y.TH?e.openElements.hasInTableScope(n)&&(e.openElements.popUntilTagNamePopped(y.SELECT),e._resetInsertionMode(),e.onEndTag(t)):K_(e,t)}function UH(e,t){switch(t.tagID){case y.BASE:case y.BASEFONT:case y.BGSOUND:case y.LINK:case y.META:case y.NOFRAMES:case y.SCRIPT:case y.STYLE:case y.TEMPLATE:case y.TITLE:{ei(e,t);break}case y.CAPTION:case y.COLGROUP:case y.TBODY:case y.TFOOT:case y.THEAD:{e.tmplInsertionModeStack[0]=U.IN_TABLE,e.insertionMode=U.IN_TABLE,hs(e,t);break}case y.COL:{e.tmplInsertionModeStack[0]=U.IN_COLUMN_GROUP,e.insertionMode=U.IN_COLUMN_GROUP,Kg(e,t);break}case y.TR:{e.tmplInsertionModeStack[0]=U.IN_TABLE_BODY,e.insertionMode=U.IN_TABLE_BODY,pd(e,t);break}case y.TD:case y.TH:{e.tmplInsertionModeStack[0]=U.IN_ROW,e.insertionMode=U.IN_ROW,gd(e,t);break}default:e.tmplInsertionModeStack[0]=U.IN_BODY,e.insertionMode=U.IN_BODY,Fn(e,t)}}function HH(e,t){t.tagID===y.TEMPLATE&&pu(e,t)}function W_(e,t){e.openElements.tmplCount>0?(e.openElements.popUntilTagNamePopped(y.TEMPLATE),e.activeFormattingElements.clearToLastMarker(),e.tmplInsertionModeStack.shift(),e._resetInsertionMode(),e.onEof(t)):Xg(e,t)}function zH(e,t){t.tagID===y.HTML?Fn(e,t):Kf(e,t)}function Q_(e,t){var n;if(t.tagID===y.HTML){if(e.fragmentContext||(e.insertionMode=U.AFTER_AFTER_BODY),e.options.sourceCodeLocationInfo&&e.openElements.tagIDs[0]===y.HTML){e._setEndLocation(e.openElements.items[0],t);const i=e.openElements.items[1];i&&!(!((n=e.treeAdapter.getNodeSourceCodeLocation(i))===null||n===void 0)&&n.endTag)&&e._setEndLocation(i,t)}}else Kf(e,t)}function Kf(e,t){e.insertionMode=U.IN_BODY,hd(e,t)}function VH(e,t){switch(t.tagID){case y.HTML:{Fn(e,t);break}case y.FRAMESET:{e._insertElement(t,be.HTML);break}case y.FRAME:{e._appendElement(t,be.HTML),t.ackSelfClosing=!0;break}case y.NOFRAMES:{ei(e,t);break}}}function jH(e,t){t.tagID===y.FRAMESET&&!e.openElements.isRootHtmlElementCurrent()&&(e.openElements.pop(),!e.fragmentContext&&e.openElements.currentTagId!==y.FRAMESET&&(e.insertionMode=U.AFTER_FRAMESET))}function qH(e,t){switch(t.tagID){case y.HTML:{Fn(e,t);break}case y.NOFRAMES:{ei(e,t);break}}}function YH(e,t){t.tagID===y.HTML&&(e.insertionMode=U.AFTER_AFTER_FRAMESET)}function GH(e,t){t.tagID===y.HTML?Fn(e,t):wf(e,t)}function wf(e,t){e.insertionMode=U.IN_BODY,hd(e,t)}function XH(e,t){switch(t.tagID){case y.HTML:{Fn(e,t);break}case y.NOFRAMES:{ei(e,t);break}}}function KH(e,t){t.chars=Vt,e._insertCharacters(t)}function WH(e,t){e._insertCharacters(t),e.framesetOk=!1}function $_(e){for(;e.treeAdapter.getNamespaceURI(e.openElements.current)!==be.HTML&&e.openElements.currentTagId!==void 0&&!e._isIntegrationPoint(e.openElements.currentTagId,e.openElements.current);)e.openElements.pop()}function QH(e,t){if(fU(t))$_(e),e._startTagOutsideForeignContent(t);else{const n=e._getAdjustedCurrentElement(),i=e.treeAdapter.getNamespaceURI(n);i===be.MATHML?M_(t):i===be.SVG&&(dU(t),I_(t)),Yg(t),t.selfClosing?e._appendElement(t,i):e._insertElement(t,i),t.ackSelfClosing=!0}}function $H(e,t){if(t.tagID===y.P||t.tagID===y.BR){$_(e),e._endTagOutsideForeignContent(t);return}for(let n=e.openElements.stackTop;n>0;n--){const i=e.openElements.items[n];if(e.treeAdapter.getNamespaceURI(i)===be.HTML){e._endTagOutsideForeignContent(t);break}const u=e.treeAdapter.getTagName(i);if(u.toLowerCase()===t.tagName){t.tagName=u,e.openElements.shortenToLength(n);break}}}ie.AREA,ie.BASE,ie.BASEFONT,ie.BGSOUND,ie.BR,ie.COL,ie.EMBED,ie.FRAME,ie.HR,ie.IMG,ie.INPUT,ie.KEYGEN,ie.LINK,ie.META,ie.PARAM,ie.SOURCE,ie.TRACK,ie.WBR;const ZH=/<(\/?)(iframe|noembed|noframes|plaintext|script|style|textarea|title|xmp)(?=[\t\n\f\r />])/gi,JH=new Set(["mdxFlowExpression","mdxJsxFlowElement","mdxJsxTextElement","mdxTextExpression","mdxjsEsm"]),l2={sourceCodeLocationInfo:!0,scriptingEnabled:!1};function Z_(e,t){const n=lz(e),i=YC("type",{handlers:{root:ez,element:tz,text:nz,comment:ex,doctype:rz,raw:az},unknown:uz}),u={parser:n?new u2(l2):u2.getFragmentParser(void 0,l2),handle(f){i(f,u)},stitches:!1,options:t||{}};i(e,u),xs(u,yi());const o=n?u.parser.document:u.parser.getFragment(),l=e7(o,{file:u.options.file});return u.stitches&&Ds(l,"comment",function(f,d,h){const p=f;if(p.value.stitch&&h&&d!==void 0){const g=h.children;return g[d]=p.value.stitch,d}}),l.type==="root"&&l.children.length===1&&l.children[0].type===e.type?l.children[0]:l}function J_(e,t){let n=-1;if(e)for(;++n<e.length;)t.handle(e[n])}function ez(e,t){J_(e.children,t)}function tz(e,t){sz(e,t),J_(e.children,t),oz(e,t)}function nz(e,t){t.parser.tokenizer.state>4&&(t.parser.tokenizer.state=0);const n={type:st.CHARACTER,chars:e.value,location:Hl(e)};xs(t,yi(e)),t.parser.currentToken=n,t.parser._processToken(t.parser.currentToken)}function rz(e,t){const n={type:st.DOCTYPE,name:"html",forceQuirks:!1,publicId:"",systemId:"",location:Hl(e)};xs(t,yi(e)),t.parser.currentToken=n,t.parser._processToken(t.parser.currentToken)}function iz(e,t){t.stitches=!0;const n=cz(e);if("children"in e&&"children"in n){const i=Z_({type:"root",children:e.children},t.options);n.children=i.children}ex({type:"comment",value:{stitch:n}},t)}function ex(e,t){const n=e.value,i={type:st.COMMENT,data:n,location:Hl(e)};xs(t,yi(e)),t.parser.currentToken=i,t.parser._processToken(t.parser.currentToken)}function az(e,t){if(t.parser.tokenizer.preprocessor.html="",t.parser.tokenizer.preprocessor.pos=-1,t.parser.tokenizer.preprocessor.lastGapPos=-2,t.parser.tokenizer.preprocessor.gapStack=[],t.parser.tokenizer.preprocessor.skipNextNewLine=!1,t.parser.tokenizer.preprocessor.lastChunkWritten=!1,t.parser.tokenizer.preprocessor.endOfChunkHit=!1,t.parser.tokenizer.preprocessor.isEol=!1,tx(t,yi(e)),t.parser.tokenizer.write(t.options.tagfilter?e.value.replace(ZH,"<$1$2"):e.value,!1),t.parser.tokenizer._runParsingLoop(),t.parser.tokenizer.state===72||t.parser.tokenizer.state===78){t.parser.tokenizer.preprocessor.lastChunkWritten=!0;const n=t.parser.tokenizer._consume();t.parser.tokenizer._callState(n)}}function uz(e,t){const n=e;if(t.options.passThrough&&t.options.passThrough.includes(n.type))iz(n,t);else{let i="";throw JH.has(n.type)&&(i=". It looks like you are using MDX nodes with `hast-util-raw` (or `rehype-raw`). If you use this because you are using remark or rehype plugins that inject `'html'` nodes, then please raise an issue with that plugin, as its a bad and slow idea. If you use this because you are using markdown syntax, then you have to configure this utility (or plugin) to pass through these nodes (see `passThrough` in docs), but you can also migrate to use the MDX syntax"),new Error("Cannot compile `"+n.type+"` node"+i)}}function xs(e,t){tx(e,t);const n=e.parser.tokenizer.currentCharacterToken;n&&n.location&&(n.location.endLine=e.parser.tokenizer.preprocessor.line,n.location.endCol=e.parser.tokenizer.preprocessor.col+1,n.location.endOffset=e.parser.tokenizer.preprocessor.offset+1,e.parser.currentToken=n,e.parser._processToken(e.parser.currentToken)),e.parser.tokenizer.paused=!1,e.parser.tokenizer.inLoop=!1,e.parser.tokenizer.active=!1,e.parser.tokenizer.returnState=sn.DATA,e.parser.tokenizer.charRefCode=-1,e.parser.tokenizer.consumedAfterSnapshot=-1,e.parser.tokenizer.currentLocation=null,e.parser.tokenizer.currentCharacterToken=null,e.parser.tokenizer.currentToken=null,e.parser.tokenizer.currentAttr={name:"",value:""}}function tx(e,t){if(t&&t.offset!==void 0){const n={startLine:t.line,startCol:t.column,startOffset:t.offset,endLine:-1,endCol:-1,endOffset:-1};e.parser.tokenizer.preprocessor.lineStartPos=-t.column+1,e.parser.tokenizer.preprocessor.droppedBufferSize=t.offset,e.parser.tokenizer.preprocessor.line=t.line,e.parser.tokenizer.currentLocation=n}}function sz(e,t){const n=e.tagName.toLowerCase();if(t.parser.tokenizer.state===sn.PLAINTEXT)return;xs(t,yi(e));const i=t.parser.openElements.current;let u="namespaceURI"in i?i.namespaceURI:iu.html;u===iu.html&&n==="svg"&&(u=iu.svg);const o=p7({...e,children:[]},{space:u===iu.svg?"svg":"html"}),l={type:st.START_TAG,tagName:n,tagID:_s(n),selfClosing:!1,ackSelfClosing:!1,attrs:"attrs"in o?o.attrs:[],location:Hl(e)};t.parser.currentToken=l,t.parser._processToken(t.parser.currentToken),t.parser.tokenizer.lastStartTagName=n}function oz(e,t){const n=e.tagName.toLowerCase();if(!t.parser.tokenizer.inForeignNode&&D7.includes(n)||t.parser.tokenizer.state===sn.PLAINTEXT)return;xs(t,ud(e));const i={type:st.END_TAG,tagName:n,tagID:_s(n),selfClosing:!1,ackSelfClosing:!1,attrs:[],location:Hl(e)};t.parser.currentToken=i,t.parser._processToken(t.parser.currentToken),n===t.parser.tokenizer.lastStartTagName&&(t.parser.tokenizer.state===sn.RCDATA||t.parser.tokenizer.state===sn.RAWTEXT||t.parser.tokenizer.state===sn.SCRIPT_DATA)&&(t.parser.tokenizer.state=sn.DATA)}function lz(e){const t=e.type==="root"?e.children[0]:e;return!!(t&&(t.type==="doctype"||t.type==="element"&&t.tagName.toLowerCase()==="html"))}function Hl(e){const t=yi(e)||{line:void 0,column:void 0,offset:void 0},n=ud(e)||{line:void 0,column:void 0,offset:void 0};return{startLine:t.line,startCol:t.column,startOffset:t.offset,endLine:n.line,endCol:n.column,endOffset:n.offset}}function cz(e){return"children"in e?va({...e,children:[]}):va(e)}function Aq(e){return function(t,n){return Z_(t,{...e,file:n})}}const fz=/[\0-\x1F!-,\.\/:-@\[-\^`\{-\xA9\xAB-\xB4\xB6-\xB9\xBB-\xBF\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0378\u0379\u037E\u0380-\u0385\u0387\u038B\u038D\u03A2\u03F6\u0482\u0530\u0557\u0558\u055A-\u055F\u0589-\u0590\u05BE\u05C0\u05C3\u05C6\u05C8-\u05CF\u05EB-\u05EE\u05F3-\u060F\u061B-\u061F\u066A-\u066D\u06D4\u06DD\u06DE\u06E9\u06FD\u06FE\u0700-\u070F\u074B\u074C\u07B2-\u07BF\u07F6-\u07F9\u07FB\u07FC\u07FE\u07FF\u082E-\u083F\u085C-\u085F\u086B-\u089F\u08B5\u08C8-\u08D2\u08E2\u0964\u0965\u0970\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09F2-\u09FB\u09FD\u09FF\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF0-\u0AF8\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B70\u0B72-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BF0-\u0BFF\u0C0D\u0C11\u0C29\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B-\u0C5F\u0C64\u0C65\u0C70-\u0C7F\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0CFF\u0D0D\u0D11\u0D45\u0D49\u0D4F-\u0D53\u0D58-\u0D5E\u0D64\u0D65\u0D70-\u0D79\u0D80\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF4-\u0E00\u0E3B-\u0E3F\u0E4F\u0E5A-\u0E80\u0E83\u0E85\u0E8B\u0EA4\u0EA6\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F01-\u0F17\u0F1A-\u0F1F\u0F2A-\u0F34\u0F36\u0F38\u0F3A-\u0F3D\u0F48\u0F6D-\u0F70\u0F85\u0F98\u0FBD-\u0FC5\u0FC7-\u0FFF\u104A-\u104F\u109E\u109F\u10C6\u10C8-\u10CC\u10CE\u10CF\u10FB\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u1360-\u137F\u1390-\u139F\u13F6\u13F7\u13FE-\u1400\u166D\u166E\u1680\u169B-\u169F\u16EB-\u16ED\u16F9-\u16FF\u170D\u1715-\u171F\u1735-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17D4-\u17D6\u17D8-\u17DB\u17DE\u17DF\u17EA-\u180A\u180E\u180F\u181A-\u181F\u1879-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u1945\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DA-\u19FF\u1A1C-\u1A1F\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1AA6\u1AA8-\u1AAF\u1AC1-\u1AFF\u1B4C-\u1B4F\u1B5A-\u1B6A\u1B74-\u1B7F\u1BF4-\u1BFF\u1C38-\u1C3F\u1C4A-\u1C4C\u1C7E\u1C7F\u1C89-\u1C8F\u1CBB\u1CBC\u1CC0-\u1CCF\u1CD3\u1CFB-\u1CFF\u1DFA\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FBD\u1FBF-\u1FC1\u1FC5\u1FCD-\u1FCF\u1FD4\u1FD5\u1FDC-\u1FDF\u1FED-\u1FF1\u1FF5\u1FFD-\u203E\u2041-\u2053\u2055-\u2070\u2072-\u207E\u2080-\u208F\u209D-\u20CF\u20F1-\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F-\u215F\u2189-\u24B5\u24EA-\u2BFF\u2C2F\u2C5F\u2CE5-\u2CEA\u2CF4-\u2CFF\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D70-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E00-\u2E2E\u2E30-\u3004\u3008-\u3020\u3030\u3036\u3037\u303D-\u3040\u3097\u3098\u309B\u309C\u30A0\u30FB\u3100-\u3104\u3130\u318F-\u319F\u31C0-\u31EF\u3200-\u33FF\u4DC0-\u4DFF\u9FFD-\u9FFF\uA48D-\uA4CF\uA4FE\uA4FF\uA60D-\uA60F\uA62C-\uA63F\uA673\uA67E\uA6F2-\uA716\uA720\uA721\uA789\uA78A\uA7C0\uA7C1\uA7CB-\uA7F4\uA828-\uA82B\uA82D-\uA83F\uA874-\uA87F\uA8C6-\uA8CF\uA8DA-\uA8DF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA954-\uA95F\uA97D-\uA97F\uA9C1-\uA9CE\uA9DA-\uA9DF\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A-\uAA5F\uAA77-\uAA79\uAAC3-\uAADA\uAADE\uAADF\uAAF0\uAAF1\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB5B\uAB6A-\uAB6F\uABEB\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uE000-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB29\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBB2-\uFBD2\uFD3E-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFC-\uFDFF\uFE10-\uFE1F\uFE30-\uFE32\uFE35-\uFE4C\uFE50-\uFE6F\uFE75\uFEFD-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF3E\uFF40\uFF5B-\uFF65\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDD3F\uDD75-\uDDFC\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEE1-\uDEFF\uDF20-\uDF2C\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDF9F\uDFC4-\uDFC7\uDFD0\uDFD6-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDCFF\uDD28-\uDD2F\uDD64-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56-\uDC5F\uDC77-\uDC7F\uDC9F-\uDCDF\uDCF3\uDCF6-\uDCFF\uDD16-\uDD1F\uDD3A-\uDD7F\uDDB8-\uDDBD\uDDC0-\uDDFF\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE36\uDE37\uDE3B-\uDE3E\uDE40-\uDE5F\uDE7D-\uDE7F\uDE9D-\uDEBF\uDEC8\uDEE7-\uDEFF\uDF36-\uDF3F\uDF56-\uDF5F\uDF73-\uDF7F\uDF92-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCFF\uDD28-\uDD2F\uDD3A-\uDE7F\uDEAA\uDEAD-\uDEAF\uDEB2-\uDEFF\uDF1D-\uDF26\uDF28-\uDF2F\uDF51-\uDFAF\uDFC5-\uDFDF\uDFF7-\uDFFF]|\uD804[\uDC47-\uDC65\uDC70-\uDC7E\uDCBB-\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD40-\uDD43\uDD48-\uDD4F\uDD74\uDD75\uDD77-\uDD7F\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDFF\uDE12\uDE38-\uDE3D\uDE3F-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEA9-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC4B-\uDC4F\uDC5A-\uDC5D\uDC62-\uDC7F\uDCC6\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDC1-\uDDD7\uDDDE-\uDDFF\uDE41-\uDE43\uDE45-\uDE4F\uDE5A-\uDE7F\uDEB9-\uDEBF\uDECA-\uDEFF\uDF1B\uDF1C\uDF2C-\uDF2F\uDF3A-\uDFFF]|\uD806[\uDC3B-\uDC9F\uDCEA-\uDCFE\uDD07\uDD08\uDD0A\uDD0B\uDD14\uDD17\uDD36\uDD39\uDD3A\uDD44-\uDD4F\uDD5A-\uDD9F\uDDA8\uDDA9\uDDD8\uDDD9\uDDE2\uDDE5-\uDDFF\uDE3F-\uDE46\uDE48-\uDE4F\uDE9A-\uDE9C\uDE9E-\uDEBF\uDEF9-\uDFFF]|\uD807[\uDC09\uDC37\uDC41-\uDC4F\uDC5A-\uDC71\uDC90\uDC91\uDCA8\uDCB7-\uDCFF\uDD07\uDD0A\uDD37-\uDD39\uDD3B\uDD3E\uDD48-\uDD4F\uDD5A-\uDD5F\uDD66\uDD69\uDD8F\uDD92\uDD99-\uDD9F\uDDAA-\uDEDF\uDEF7-\uDFAF\uDFB1-\uDFFF]|\uD808[\uDF9A-\uDFFF]|\uD809[\uDC6F-\uDC7F\uDD44-\uDFFF]|[\uD80A\uD80B\uD80E-\uD810\uD812-\uD819\uD824-\uD82B\uD82D\uD82E\uD830-\uD833\uD837\uD839\uD83D\uD83F\uD87B-\uD87D\uD87F\uD885-\uDB3F\uDB41-\uDBFF][\uDC00-\uDFFF]|\uD80D[\uDC2F-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDECF\uDEEE\uDEEF\uDEF5-\uDEFF\uDF37-\uDF3F\uDF44-\uDF4F\uDF5A-\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE80-\uDEFF\uDF4B-\uDF4E\uDF88-\uDF8E\uDFA0-\uDFDF\uDFE2\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD821[\uDFF8-\uDFFF]|\uD823[\uDCD6-\uDCFF\uDD09-\uDFFF]|\uD82C[\uDD1F-\uDD4F\uDD53-\uDD63\uDD68-\uDD6F\uDEFC-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A-\uDC9C\uDC9F-\uDFFF]|\uD834[\uDC00-\uDD64\uDD6A-\uDD6C\uDD73-\uDD7A\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDE41\uDE45-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3\uDFCC\uDFCD]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDCFF\uDD2D-\uDD2F\uDD3E\uDD3F\uDD4A-\uDD4D\uDD4F-\uDEBF\uDEFA-\uDFFF]|\uD83A[\uDCC5-\uDCCF\uDCD7-\uDCFF\uDD4C-\uDD4F\uDD5A-\uDFFF]|\uD83B[\uDC00-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDFFF]|\uD83C[\uDC00-\uDD2F\uDD4A-\uDD4F\uDD6A-\uDD6F\uDD8A-\uDFFF]|\uD83E[\uDC00-\uDFEF\uDFFA-\uDFFF]|\uD869[\uDEDE-\uDEFF]|\uD86D[\uDF35-\uDF3F]|\uD86E[\uDC1E\uDC1F]|\uD873[\uDEA2-\uDEAF]|\uD87A[\uDFE1-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD884[\uDF4B-\uDFFF]|\uDB40[\uDC00-\uDCFF\uDDF0-\uDFFF]/g,dz=Object.hasOwnProperty;class hz{constructor(){this.occurrences,this.reset()}slug(t,n){const i=this;let u=mz(t,n===!0);const o=u;for(;dz.call(i.occurrences,u);)i.occurrences[o]++,u=o+"-"+i.occurrences[o];return i.occurrences[u]=0,u}reset(){this.occurrences=Object.create(null)}}function mz(e,t){return typeof e!="string"?"":(t||(e=e.toLowerCase()),e.replace(fz,"").replace(/ /g,"-"))}function nx(e){const t=e.type==="element"?e.tagName.toLowerCase():"",n=t.length===2&&t.charCodeAt(0)===104?t.charCodeAt(1):0;return n>48&&n<55?n-48:void 0}function pz(e){return"children"in e?rx(e):"value"in e?e.value:""}function gz(e){return e.type==="text"?e.value:"children"in e?rx(e):""}function rx(e){let t=-1;const n=[];for(;++t<e.children.length;)n[t]=gz(e.children[t]);return n.join("")}const Ez={},c2=new hz;function Sq(e){const n=(e||Ez).prefix||"";return function(i){c2.reset(),Ds(i,"element",function(u){nx(u)&&!u.properties.id&&(u.properties.id=n+c2.slug(pz(u)))})}}const ix=function(e){if(e==null)return Tz;if(typeof e=="string")return bz(e);if(typeof e=="object")return yz(e);if(typeof e=="function")return Wg(e);throw new Error("Expected function, string, or array as `test`")};function yz(e){const t=[];let n=-1;for(;++n<e.length;)t[n]=ix(e[n]);return Wg(i);function i(...u){let o=-1;for(;++o<t.length;)if(t[o].apply(this,u))return!0;return!1}}function bz(e){return Wg(t);function t(n){return n.tagName===e}}function Wg(e){return t;function t(n,i,u){return!!(Az(n)&&e.call(this,n,typeof i=="number"?i:void 0,u||void 0))}}function Tz(e){return!!(e&&typeof e=="object"&&"type"in e&&e.type==="element"&&"tagName"in e&&typeof e.tagName=="string")}function Az(e){return e!==null&&typeof e=="object"&&"type"in e&&"tagName"in e}const f2={type:"element",tagName:"span",properties:{className:["icon","icon-link"]},children:[]},Sz={};function Dq(e){const t=e||Sz;let n=t.properties;const i=t.headingProperties,u=t.behavior||"prepend",o=t.content,l=t.group,f=ix(t.test);let d;return u==="after"||u==="before"?d=p:u==="wrap"?d=g:(d=h,n||(n={ariaHidden:"true",tabIndex:-1})),function(b){Ds(b,"element",function(T,A,_){if(nx(T)&&T.properties.id&&f(T,A,_))return Object.assign(T.properties,gf(i,T)),d(T,A,_)})};function h(b){const T=d2(o||f2,b);return b.children[u==="prepend"?"unshift":"push"](Cp(b,gf(n,b),T)),[xf]}function p(b,T,A){if(typeof T!="number"||!A)return;const _=d2(o||f2,b),O=Cp(b,gf(n,b),_);let C=u==="before"?[O,b]:[b,O];if(l){const N=ax(l,b);N&&!Array.isArray(N)&&N.type==="element"&&(N.children=C,C=[N])}return A.children.splice(T,1,...C),[xf,T+C.length]}function g(b){let T=b.children,A=[];return typeof o=="function"?(T=[],A=o(b)):o&&(A=Qg(o)),b.children=[Cp(b,gf(n,b),Array.isArray(A)?[...T,...A]:[...T,A])],[xf]}}function Qg(e){return va(e)}function Cp(e,t,n){return{type:"element",tagName:"a",properties:{...t,href:"#"+e.properties.id},children:n}}function d2(e,t){const n=ax(e,t);return Array.isArray(n)?n:[n]}function ax(e,t){return typeof e=="function"?e(t):Qg(e)}function gf(e,t){return typeof e=="function"?e(t):e?Qg(e):{}}const Za=["ariaDescribedBy","ariaLabel","ariaLabelledBy"],h2={ancestors:{tbody:["table"],td:["table"],th:["table"],thead:["table"],tfoot:["table"],tr:["table"]},attributes:{a:[...Za,"dataFootnoteBackref","dataFootnoteRef",["className","data-footnote-backref"],"href"],blockquote:["cite"],code:[["className",/^language-./]],del:["cite"],div:["itemScope","itemType"],dl:[...Za],h2:[["className","sr-only"]],img:[...Za,"longDesc","src"],input:[["disabled",!0],["type","checkbox"]],ins:["cite"],li:[["className","task-list-item"]],ol:[...Za,["className","contains-task-list"]],q:["cite"],section:["dataFootnotes",["className","footnotes"]],source:["srcSet"],summary:[...Za],table:[...Za],ul:[...Za,["className","contains-task-list"]],"*":["abbr","accept","acceptCharset","accessKey","action","align","alt","axis","border","cellPadding","cellSpacing","char","charOff","charSet","checked","clear","colSpan","color","cols","compact","coords","dateTime","dir","encType","frame","hSpace","headers","height","hrefLang","htmlFor","id","isMap","itemProp","label","lang","maxLength","media","method","multiple","name","noHref","noShade","noWrap","open","prompt","readOnly","rev","rowSpan","rows","rules","scope","selected","shape","size","span","start","summary","tabIndex","title","useMap","vAlign","value","width"]},clobber:["ariaDescribedBy","ariaLabelledBy","id","name"],clobberPrefix:"user-content-",protocols:{cite:["http","https"],href:["http","https","irc","ircs","mailto","xmpp"],longDesc:["http","https"],src:["http","https"]},required:{input:{disabled:!0,type:"checkbox"}},strip:["script"],tagNames:["a","b","blockquote","br","code","dd","del","details","div","dl","dt","em","h1","h2","h3","h4","h5","h6","hr","i","img","input","ins","kbd","li","ol","p","picture","pre","q","rp","rt","ruby","s","samp","section","source","span","strike","strong","sub","summary","sup","table","tbody","td","tfoot","th","thead","tr","tt","ul","var"]},ya={}.hasOwnProperty;function Dz(e,t){let n={type:"root",children:[]};const i={schema:t?{...h2,...t}:h2,stack:[]},u=ux(i,e);return u&&(Array.isArray(u)?u.length===1?n=u[0]:n.children=u:n=u),n}function ux(e,t){if(t&&typeof t=="object"){const n=t;switch(typeof n.type=="string"?n.type:""){case"comment":return vz(e,n);case"doctype":return Cz(e,n);case"element":return _z(e,n);case"root":return xz(e,n);case"text":return Rz(e,n)}}}function vz(e,t){if(e.schema.allowComments){const n=typeof t.value=="string"?t.value:"",i=n.indexOf("-->"),o={type:"comment",value:i<0?n:n.slice(0,i)};return zl(o,t),o}}function Cz(e,t){if(e.schema.allowDoctypes){const n={type:"doctype"};return zl(n,t),n}}function _z(e,t){const n=typeof t.tagName=="string"?t.tagName:"";e.stack.push(n);const i=sx(e,t.children),u=wz(e,t.properties);e.stack.pop();let o=!1;if(n&&n!=="*"&&(!e.schema.tagNames||e.schema.tagNames.includes(n))&&(o=!0,e.schema.ancestors&&ya.call(e.schema.ancestors,n))){const f=e.schema.ancestors[n];let d=-1;for(o=!1;++d<f.length;)e.stack.includes(f[d])&&(o=!0)}if(!o)return e.schema.strip&&!e.schema.strip.includes(n)?i:void 0;const l={type:"element",tagName:n,properties:u,children:i};return zl(l,t),l}function xz(e,t){const i={type:"root",children:sx(e,t.children)};return zl(i,t),i}function Rz(e,t){const i={type:"text",value:typeof t.value=="string"?t.value:""};return zl(i,t),i}function sx(e,t){const n=[];if(Array.isArray(t)){const i=t;let u=-1;for(;++u<i.length;){const o=ux(e,i[u]);o&&(Array.isArray(o)?n.push(...o):n.push(o))}}return n}function wz(e,t){const n=e.stack[e.stack.length-1],i=e.schema.attributes,u=e.schema.required,o=i&&ya.call(i,n)?i[n]:void 0,l=i&&ya.call(i,"*")?i["*"]:void 0,f=t&&typeof t=="object"?t:{},d={};let h;for(h in f)if(ya.call(f,h)){const p=f[h];let g=m2(e,p2(o,h),h,p);g==null&&(g=m2(e,p2(l,h),h,p)),g!=null&&(d[h]=g)}if(u&&ya.call(u,n)){const p=u[n];for(h in p)ya.call(p,h)&&!ya.call(d,h)&&(d[h]=p[h])}return d}function m2(e,t,n,i){return t?Array.isArray(i)?Oz(e,t,n,i):ox(e,t,n,i):void 0}function Oz(e,t,n,i){let u=-1;const o=[];for(;++u<i.length;){const l=ox(e,t,n,i[u]);(typeof l=="number"||typeof l=="string")&&o.push(l)}return o}function ox(e,t,n,i){if(!(typeof i!="boolean"&&typeof i!="number"&&typeof i!="string")&&Nz(e,n,i)){if(typeof t=="object"&&t.length>1){let u=!1,o=0;for(;++o<t.length;){const l=t[o];if(l&&typeof l=="object"&&"flags"in l){if(l.test(String(i))){u=!0;break}}else if(l===i){u=!0;break}}if(!u)return}return e.schema.clobber&&e.schema.clobberPrefix&&e.schema.clobber.includes(n)?e.schema.clobberPrefix+i:i}}function Nz(e,t,n){const i=e.schema.protocols&&ya.call(e.schema.protocols,t)?e.schema.protocols[t]:void 0;if(!i||i.length===0)return!0;const u=String(n),o=u.indexOf(":"),l=u.indexOf("?"),f=u.indexOf("#"),d=u.indexOf("/");if(o<0||d>-1&&o>d||l>-1&&o>l||f>-1&&o>f)return!0;let h=-1;for(;++h<i.length;){const p=i[h];if(o===p.length&&u.slice(0,p.length)===p)return!0}return!1}function zl(e,t){const n=mC(t);t.data&&(e.data=va(t.data)),n&&(e.position=n)}function p2(e,t){let n,i=-1;if(e)for(;++i<e.length;){const u=e[i],o=typeof u=="string"?u:u[0];if(o===t)return u;o==="data*"&&(n=u)}if(t.length>4&&t.slice(0,4).toLowerCase()==="data")return n}function vq(e){return function(t){return Dz(t,e)}}/*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE */const{entries:lx,setPrototypeOf:g2,isFrozen:kz,getPrototypeOf:Lz,getOwnPropertyDescriptor:Mz}=Object;let{freeze:jn,seal:zr,create:cx}=Object,{apply:_0,construct:x0}=typeof Reflect<"u"&&Reflect;jn||(jn=function(t){return t});zr||(zr=function(t){return t});_0||(_0=function(t,n,i){return t.apply(n,i)});x0||(x0=function(t,n){return new t(...n)});const Ef=qn(Array.prototype.forEach),Iz=qn(Array.prototype.lastIndexOf),E2=qn(Array.prototype.pop),Yo=qn(Array.prototype.push),Pz=qn(Array.prototype.splice),Of=qn(String.prototype.toLowerCase),_p=qn(String.prototype.toString),y2=qn(String.prototype.match),Go=qn(String.prototype.replace),Fz=qn(String.prototype.indexOf),Bz=qn(String.prototype.trim),Qr=qn(Object.prototype.hasOwnProperty),Hn=qn(RegExp.prototype.test),Xo=Uz(TypeError);function qn(e){return function(t){t instanceof RegExp&&(t.lastIndex=0);for(var n=arguments.length,i=new Array(n>1?n-1:0),u=1;u<n;u++)i[u-1]=arguments[u];return _0(e,t,i)}}function Uz(e){return function(){for(var t=arguments.length,n=new Array(t),i=0;i<t;i++)n[i]=arguments[i];return x0(e,n)}}function ft(e,t){let n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:Of;g2&&g2(e,null);let i=t.length;for(;i--;){let u=t[i];if(typeof u=="string"){const o=n(u);o!==u&&(kz(t)||(t[i]=o),u=o)}e[u]=!0}return e}function Hz(e){for(let t=0;t<e.length;t++)Qr(e,t)||(e[t]=null);return e}function Fi(e){const t=cx(null);for(const[n,i]of lx(e))Qr(e,n)&&(Array.isArray(i)?t[n]=Hz(i):i&&typeof i=="object"&&i.constructor===Object?t[n]=Fi(i):t[n]=i);return t}function Ko(e,t){for(;e!==null;){const i=Mz(e,t);if(i){if(i.get)return qn(i.get);if(typeof i.value=="function")return qn(i.value)}e=Lz(e)}function n(){return null}return n}const b2=jn(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),xp=jn(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),Rp=jn(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),zz=jn(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),wp=jn(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),Vz=jn(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),T2=jn(["#text"]),A2=jn(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),Op=jn(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),S2=jn(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),yf=jn(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),jz=zr(/\{\{[\w\W]*|[\w\W]*\}\}/gm),qz=zr(/<%[\w\W]*|[\w\W]*%>/gm),Yz=zr(/\$\{[\w\W]*/gm),Gz=zr(/^data-[\-\w.\u00B7-\uFFFF]+$/),Xz=zr(/^aria-[\-\w]+$/),fx=zr(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),Kz=zr(/^(?:\w+script|data):/i),Wz=zr(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),dx=zr(/^html$/i),Qz=zr(/^[a-z][.\w]*(-[.\w]+)+$/i);var D2=Object.freeze({__proto__:null,ARIA_ATTR:Xz,ATTR_WHITESPACE:Wz,CUSTOM_ELEMENT:Qz,DATA_ATTR:Gz,DOCTYPE_NAME:dx,ERB_EXPR:qz,IS_ALLOWED_URI:fx,IS_SCRIPT_OR_DATA:Kz,MUSTACHE_EXPR:jz,TMPLIT_EXPR:Yz});const Wo={element:1,text:3,progressingInstruction:7,comment:8,document:9},$z=function(){return typeof window>"u"?null:window},Zz=function(t,n){if(typeof t!="object"||typeof t.createPolicy!="function")return null;let i=null;const u="data-tt-policy-suffix";n&&n.hasAttribute(u)&&(i=n.getAttribute(u));const o="dompurify"+(i?"#"+i:"");try{return t.createPolicy(o,{createHTML(l){return l},createScriptURL(l){return l}})}catch{return console.warn("TrustedTypes policy "+o+" could not be created."),null}},v2=function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}};function hx(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:$z();const t=Se=>hx(Se);if(t.version="3.2.6",t.removed=[],!e||!e.document||e.document.nodeType!==Wo.document||!e.Element)return t.isSupported=!1,t;let{document:n}=e;const i=n,u=i.currentScript,{DocumentFragment:o,HTMLTemplateElement:l,Node:f,Element:d,NodeFilter:h,NamedNodeMap:p=e.NamedNodeMap||e.MozNamedAttrMap,HTMLFormElement:g,DOMParser:b,trustedTypes:T}=e,A=d.prototype,_=Ko(A,"cloneNode"),O=Ko(A,"remove"),C=Ko(A,"nextSibling"),N=Ko(A,"childNodes"),R=Ko(A,"parentNode");if(typeof l=="function"){const Se=n.createElement("template");Se.content&&Se.content.ownerDocument&&(n=Se.content.ownerDocument)}let Y,M="";const{implementation:v,createNodeIterator:J,createDocumentFragment:P,getElementsByTagName:q}=n,{importNode:z}=i;let V=v2();t.isSupported=typeof lx=="function"&&typeof R=="function"&&v&&v.createHTMLDocument!==void 0;const{MUSTACHE_EXPR:F,ERB_EXPR:$,TMPLIT_EXPR:Z,DATA_ATTR:L,ARIA_ATTR:B,IS_SCRIPT_OR_DATA:K,ATTR_WHITESPACE:Q,CUSTOM_ELEMENT:_e}=D2;let{IS_ALLOWED_URI:S}=D2,ne=null;const ge=ft({},[...b2,...xp,...Rp,...wp,...T2]);let w=null;const Te=ft({},[...A2,...Op,...S2,...yf]);let Re=Object.seal(cx(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),xe=null,We=null,Qe=!0,Nt=!0,mt=!1,qt=!0,ln=!1,Ar=!0,tn=!1,ni=!1,ri=!1,Yt=!1,ii=!1,Sr=!1,ai=!0,jr=!1;const ur="user-content-";let Yn=!0,Dr=!1,Gn={},le=null;const Ee=ft({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let Pe=null;const ze=ft({},["audio","video","img","source","image","track"]);let ht=null;const Ft=ft({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Cn="http://www.w3.org/1998/Math/MathML",Wt="http://www.w3.org/2000/svg",Gt="http://www.w3.org/1999/xhtml";let Qt=Gt,Bt=!1,nn=null;const On=ft({},[Cn,Wt,Gt],_p);let qr=ft({},["mi","mo","mn","ms","mtext"]),Ti=ft({},["annotation-xml"]);const Vi=ft({},["title","style","font","a","script"]);let sr=null;const gu=["application/xhtml+xml","text/html"],Ai="text/html";let kt=null,vr=null;const Oa=n.createElement("form"),j=function(G){return G instanceof RegExp||G instanceof Function},te=function(){let G=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(!(vr&&vr===G)){if((!G||typeof G!="object")&&(G={}),G=Fi(G),sr=gu.indexOf(G.PARSER_MEDIA_TYPE)===-1?Ai:G.PARSER_MEDIA_TYPE,kt=sr==="application/xhtml+xml"?_p:Of,ne=Qr(G,"ALLOWED_TAGS")?ft({},G.ALLOWED_TAGS,kt):ge,w=Qr(G,"ALLOWED_ATTR")?ft({},G.ALLOWED_ATTR,kt):Te,nn=Qr(G,"ALLOWED_NAMESPACES")?ft({},G.ALLOWED_NAMESPACES,_p):On,ht=Qr(G,"ADD_URI_SAFE_ATTR")?ft(Fi(Ft),G.ADD_URI_SAFE_ATTR,kt):Ft,Pe=Qr(G,"ADD_DATA_URI_TAGS")?ft(Fi(ze),G.ADD_DATA_URI_TAGS,kt):ze,le=Qr(G,"FORBID_CONTENTS")?ft({},G.FORBID_CONTENTS,kt):Ee,xe=Qr(G,"FORBID_TAGS")?ft({},G.FORBID_TAGS,kt):Fi({}),We=Qr(G,"FORBID_ATTR")?ft({},G.FORBID_ATTR,kt):Fi({}),Gn=Qr(G,"USE_PROFILES")?G.USE_PROFILES:!1,Qe=G.ALLOW_ARIA_ATTR!==!1,Nt=G.ALLOW_DATA_ATTR!==!1,mt=G.ALLOW_UNKNOWN_PROTOCOLS||!1,qt=G.ALLOW_SELF_CLOSE_IN_ATTR!==!1,ln=G.SAFE_FOR_TEMPLATES||!1,Ar=G.SAFE_FOR_XML!==!1,tn=G.WHOLE_DOCUMENT||!1,Yt=G.RETURN_DOM||!1,ii=G.RETURN_DOM_FRAGMENT||!1,Sr=G.RETURN_TRUSTED_TYPE||!1,ri=G.FORCE_BODY||!1,ai=G.SANITIZE_DOM!==!1,jr=G.SANITIZE_NAMED_PROPS||!1,Yn=G.KEEP_CONTENT!==!1,Dr=G.IN_PLACE||!1,S=G.ALLOWED_URI_REGEXP||fx,Qt=G.NAMESPACE||Gt,qr=G.MATHML_TEXT_INTEGRATION_POINTS||qr,Ti=G.HTML_INTEGRATION_POINTS||Ti,Re=G.CUSTOM_ELEMENT_HANDLING||{},G.CUSTOM_ELEMENT_HANDLING&&j(G.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Re.tagNameCheck=G.CUSTOM_ELEMENT_HANDLING.tagNameCheck),G.CUSTOM_ELEMENT_HANDLING&&j(G.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Re.attributeNameCheck=G.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),G.CUSTOM_ELEMENT_HANDLING&&typeof G.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(Re.allowCustomizedBuiltInElements=G.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),ln&&(Nt=!1),ii&&(Yt=!0),Gn&&(ne=ft({},T2),w=[],Gn.html===!0&&(ft(ne,b2),ft(w,A2)),Gn.svg===!0&&(ft(ne,xp),ft(w,Op),ft(w,yf)),Gn.svgFilters===!0&&(ft(ne,Rp),ft(w,Op),ft(w,yf)),Gn.mathMl===!0&&(ft(ne,wp),ft(w,S2),ft(w,yf))),G.ADD_TAGS&&(ne===ge&&(ne=Fi(ne)),ft(ne,G.ADD_TAGS,kt)),G.ADD_ATTR&&(w===Te&&(w=Fi(w)),ft(w,G.ADD_ATTR,kt)),G.ADD_URI_SAFE_ATTR&&ft(ht,G.ADD_URI_SAFE_ATTR,kt),G.FORBID_CONTENTS&&(le===Ee&&(le=Fi(le)),ft(le,G.FORBID_CONTENTS,kt)),Yn&&(ne["#text"]=!0),tn&&ft(ne,["html","head","body"]),ne.table&&(ft(ne,["tbody"]),delete xe.tbody),G.TRUSTED_TYPES_POLICY){if(typeof G.TRUSTED_TYPES_POLICY.createHTML!="function")throw Xo('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof G.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw Xo('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');Y=G.TRUSTED_TYPES_POLICY,M=Y.createHTML("")}else Y===void 0&&(Y=Zz(T,u)),Y!==null&&typeof M=="string"&&(M=Y.createHTML(""));jn&&jn(G),vr=G}},se=ft({},[...xp,...Rp,...zz]),pe=ft({},[...wp,...Vz]),Ce=function(G){let ye=R(G);(!ye||!ye.tagName)&&(ye={namespaceURI:Qt,tagName:"template"});const Oe=Of(G.tagName),rt=Of(ye.tagName);return nn[G.namespaceURI]?G.namespaceURI===Wt?ye.namespaceURI===Gt?Oe==="svg":ye.namespaceURI===Cn?Oe==="svg"&&(rt==="annotation-xml"||qr[rt]):!!se[Oe]:G.namespaceURI===Cn?ye.namespaceURI===Gt?Oe==="math":ye.namespaceURI===Wt?Oe==="math"&&Ti[rt]:!!pe[Oe]:G.namespaceURI===Gt?ye.namespaceURI===Wt&&!Ti[rt]||ye.namespaceURI===Cn&&!qr[rt]?!1:!pe[Oe]&&(Vi[Oe]||!se[Oe]):!!(sr==="application/xhtml+xml"&&nn[G.namespaceURI]):!1},we=function(G){Yo(t.removed,{element:G});try{R(G).removeChild(G)}catch{O(G)}},Fe=function(G,ye){try{Yo(t.removed,{attribute:ye.getAttributeNode(G),from:ye})}catch{Yo(t.removed,{attribute:null,from:ye})}if(ye.removeAttribute(G),G==="is")if(Yt||ii)try{we(ye)}catch{}else try{ye.setAttribute(G,"")}catch{}},Ne=function(G){let ye=null,Oe=null;if(ri)G="<remove></remove>"+G;else{const vt=y2(G,/^[\r\n\t ]+/);Oe=vt&&vt[0]}sr==="application/xhtml+xml"&&Qt===Gt&&(G='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+G+"</body></html>");const rt=Y?Y.createHTML(G):G;if(Qt===Gt)try{ye=new b().parseFromString(rt,sr)}catch{}if(!ye||!ye.documentElement){ye=v.createDocument(Qt,"template",null);try{ye.documentElement.innerHTML=Bt?M:rt}catch{}}const Ut=ye.body||ye.documentElement;return G&&Oe&&Ut.insertBefore(n.createTextNode(Oe),Ut.childNodes[0]||null),Qt===Gt?q.call(ye,tn?"html":"body")[0]:tn?ye.documentElement:Ut},Be=function(G){return J.call(G.ownerDocument||G,G,h.SHOW_ELEMENT|h.SHOW_COMMENT|h.SHOW_TEXT|h.SHOW_PROCESSING_INSTRUCTION|h.SHOW_CDATA_SECTION,null)},ke=function(G){return G instanceof g&&(typeof G.nodeName!="string"||typeof G.textContent!="string"||typeof G.removeChild!="function"||!(G.attributes instanceof p)||typeof G.removeAttribute!="function"||typeof G.setAttribute!="function"||typeof G.namespaceURI!="string"||typeof G.insertBefore!="function"||typeof G.hasChildNodes!="function")},je=function(G){return typeof f=="function"&&G instanceof f};function Ue(Se,G,ye){Ef(Se,Oe=>{Oe.call(t,G,ye,vr)})}const Ge=function(G){let ye=null;if(Ue(V.beforeSanitizeElements,G,null),ke(G))return we(G),!0;const Oe=kt(G.nodeName);if(Ue(V.uponSanitizeElement,G,{tagName:Oe,allowedTags:ne}),Ar&&G.hasChildNodes()&&!je(G.firstElementChild)&&Hn(/<[/\w!]/g,G.innerHTML)&&Hn(/<[/\w!]/g,G.textContent)||G.nodeType===Wo.progressingInstruction||Ar&&G.nodeType===Wo.comment&&Hn(/<[/\w]/g,G.data))return we(G),!0;if(!ne[Oe]||xe[Oe]){if(!xe[Oe]&&Dt(Oe)&&(Re.tagNameCheck instanceof RegExp&&Hn(Re.tagNameCheck,Oe)||Re.tagNameCheck instanceof Function&&Re.tagNameCheck(Oe)))return!1;if(Yn&&!le[Oe]){const rt=R(G)||G.parentNode,Ut=N(G)||G.childNodes;if(Ut&&rt){const vt=Ut.length;for(let cn=vt-1;cn>=0;--cn){const $t=_(Ut[cn],!0);$t.__removalCount=(G.__removalCount||0)+1,rt.insertBefore($t,C(G))}}}return we(G),!0}return G instanceof d&&!Ce(G)||(Oe==="noscript"||Oe==="noembed"||Oe==="noframes")&&Hn(/<\/no(script|embed|frames)/i,G.innerHTML)?(we(G),!0):(ln&&G.nodeType===Wo.text&&(ye=G.textContent,Ef([F,$,Z],rt=>{ye=Go(ye,rt," ")}),G.textContent!==ye&&(Yo(t.removed,{element:G.cloneNode()}),G.textContent=ye)),Ue(V.afterSanitizeElements,G,null),!1)},dt=function(G,ye,Oe){if(ai&&(ye==="id"||ye==="name")&&(Oe in n||Oe in Oa))return!1;if(!(Nt&&!We[ye]&&Hn(L,ye))){if(!(Qe&&Hn(B,ye))){if(!w[ye]||We[ye]){if(!(Dt(G)&&(Re.tagNameCheck instanceof RegExp&&Hn(Re.tagNameCheck,G)||Re.tagNameCheck instanceof Function&&Re.tagNameCheck(G))&&(Re.attributeNameCheck instanceof RegExp&&Hn(Re.attributeNameCheck,ye)||Re.attributeNameCheck instanceof Function&&Re.attributeNameCheck(ye))||ye==="is"&&Re.allowCustomizedBuiltInElements&&(Re.tagNameCheck instanceof RegExp&&Hn(Re.tagNameCheck,Oe)||Re.tagNameCheck instanceof Function&&Re.tagNameCheck(Oe))))return!1}else if(!ht[ye]){if(!Hn(S,Go(Oe,Q,""))){if(!((ye==="src"||ye==="xlink:href"||ye==="href")&&G!=="script"&&Fz(Oe,"data:")===0&&Pe[G])){if(!(mt&&!Hn(K,Go(Oe,Q,"")))){if(Oe)return!1}}}}}}return!0},Dt=function(G){return G!=="annotation-xml"&&y2(G,_e)},Lt=function(G){Ue(V.beforeSanitizeAttributes,G,null);const{attributes:ye}=G;if(!ye||ke(G))return;const Oe={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:w,forceKeepAttr:void 0};let rt=ye.length;for(;rt--;){const Ut=ye[rt],{name:vt,namespaceURI:cn,value:$t}=Ut,Bn=kt(vt),$e=$t;let yt=vt==="value"?$e:Bz($e);if(Oe.attrName=Bn,Oe.attrValue=yt,Oe.keepAttr=!0,Oe.forceKeepAttr=void 0,Ue(V.uponSanitizeAttribute,G,Oe),yt=Oe.attrValue,jr&&(Bn==="id"||Bn==="name")&&(Fe(vt,G),yt=ur+yt),Ar&&Hn(/((--!?|])>)|<\/(style|title)/i,yt)){Fe(vt,G);continue}if(Oe.forceKeepAttr)continue;if(!Oe.keepAttr){Fe(vt,G);continue}if(!qt&&Hn(/\/>/i,yt)){Fe(vt,G);continue}ln&&Ef([F,$,Z],Kn=>{yt=Go(yt,Kn," ")});const Xn=kt(G.nodeName);if(!dt(Xn,Bn,yt)){Fe(vt,G);continue}if(Y&&typeof T=="object"&&typeof T.getAttributeType=="function"&&!cn)switch(T.getAttributeType(Xn,Bn)){case"TrustedHTML":{yt=Y.createHTML(yt);break}case"TrustedScriptURL":{yt=Y.createScriptURL(yt);break}}if(yt!==$e)try{cn?G.setAttributeNS(cn,vt,yt):G.setAttribute(vt,yt),ke(G)?we(G):E2(t.removed)}catch{Fe(vt,G)}}Ue(V.afterSanitizeAttributes,G,null)},pt=function Se(G){let ye=null;const Oe=Be(G);for(Ue(V.beforeSanitizeShadowDOM,G,null);ye=Oe.nextNode();)Ue(V.uponSanitizeShadowNode,ye,null),Ge(ye),Lt(ye),ye.content instanceof o&&Se(ye.content);Ue(V.afterSanitizeShadowDOM,G,null)};return t.sanitize=function(Se){let G=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},ye=null,Oe=null,rt=null,Ut=null;if(Bt=!Se,Bt&&(Se="<!-->"),typeof Se!="string"&&!je(Se))if(typeof Se.toString=="function"){if(Se=Se.toString(),typeof Se!="string")throw Xo("dirty is not a string, aborting")}else throw Xo("toString is not a function");if(!t.isSupported)return Se;if(ni||te(G),t.removed=[],typeof Se=="string"&&(Dr=!1),Dr){if(Se.nodeName){const $t=kt(Se.nodeName);if(!ne[$t]||xe[$t])throw Xo("root node is forbidden and cannot be sanitized in-place")}}else if(Se instanceof f)ye=Ne("<!---->"),Oe=ye.ownerDocument.importNode(Se,!0),Oe.nodeType===Wo.element&&Oe.nodeName==="BODY"||Oe.nodeName==="HTML"?ye=Oe:ye.appendChild(Oe);else{if(!Yt&&!ln&&!tn&&Se.indexOf("<")===-1)return Y&&Sr?Y.createHTML(Se):Se;if(ye=Ne(Se),!ye)return Yt?null:Sr?M:""}ye&&ri&&we(ye.firstChild);const vt=Be(Dr?Se:ye);for(;rt=vt.nextNode();)Ge(rt),Lt(rt),rt.content instanceof o&&pt(rt.content);if(Dr)return Se;if(Yt){if(ii)for(Ut=P.call(ye.ownerDocument);ye.firstChild;)Ut.appendChild(ye.firstChild);else Ut=ye;return(w.shadowroot||w.shadowrootmode)&&(Ut=z.call(i,Ut,!0)),Ut}let cn=tn?ye.outerHTML:ye.innerHTML;return tn&&ne["!doctype"]&&ye.ownerDocument&&ye.ownerDocument.doctype&&ye.ownerDocument.doctype.name&&Hn(dx,ye.ownerDocument.doctype.name)&&(cn="<!DOCTYPE "+ye.ownerDocument.doctype.name+`> +`+cn),ln&&Ef([F,$,Z],$t=>{cn=Go(cn,$t," ")}),Y&&Sr?Y.createHTML(cn):cn},t.setConfig=function(){let Se=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};te(Se),ni=!0},t.clearConfig=function(){vr=null,ni=!1},t.isValidAttribute=function(Se,G,ye){vr||te({});const Oe=kt(Se),rt=kt(G);return dt(Oe,rt,ye)},t.addHook=function(Se,G){typeof G=="function"&&Yo(V[Se],G)},t.removeHook=function(Se,G){if(G!==void 0){const ye=Iz(V[Se],G);return ye===-1?void 0:Pz(V[Se],ye,1)[0]}return E2(V[Se])},t.removeHooks=function(Se){V[Se]=[]},t.removeAllHooks=function(){V=v2()},t}var Cq=hx();function mx(e,t){return function(){return e.apply(t,arguments)}}const{toString:Jz}=Object.prototype,{getPrototypeOf:$g}=Object,{iterator:Ed,toStringTag:px}=Symbol,yd=(e=>t=>{const n=Jz.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),ti=e=>(e=e.toLowerCase(),t=>yd(t)===e),bd=e=>t=>typeof t===e,{isArray:Rs}=Array,xl=bd("undefined");function eV(e){return e!==null&&!xl(e)&&e.constructor!==null&&!xl(e.constructor)&&rr(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const gx=ti("ArrayBuffer");function tV(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&gx(e.buffer),t}const nV=bd("string"),rr=bd("function"),Ex=bd("number"),Td=e=>e!==null&&typeof e=="object",rV=e=>e===!0||e===!1,Nf=e=>{if(yd(e)!=="object")return!1;const t=$g(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(px in e)&&!(Ed in e)},iV=ti("Date"),aV=ti("File"),uV=ti("Blob"),sV=ti("FileList"),oV=e=>Td(e)&&rr(e.pipe),lV=e=>{let t;return e&&(typeof FormData=="function"&&e instanceof FormData||rr(e.append)&&((t=yd(e))==="formdata"||t==="object"&&rr(e.toString)&&e.toString()==="[object FormData]"))},cV=ti("URLSearchParams"),[fV,dV,hV,mV]=["ReadableStream","Request","Response","Headers"].map(ti),pV=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function Vl(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let i,u;if(typeof e!="object"&&(e=[e]),Rs(e))for(i=0,u=e.length;i<u;i++)t.call(null,e[i],i,e);else{const o=n?Object.getOwnPropertyNames(e):Object.keys(e),l=o.length;let f;for(i=0;i<l;i++)f=o[i],t.call(null,e[f],f,e)}}function yx(e,t){t=t.toLowerCase();const n=Object.keys(e);let i=n.length,u;for(;i-- >0;)if(u=n[i],t===u.toLowerCase())return u;return null}const au=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,bx=e=>!xl(e)&&e!==au;function R0(){const{caseless:e}=bx(this)&&this||{},t={},n=(i,u)=>{const o=e&&yx(t,u)||u;Nf(t[o])&&Nf(i)?t[o]=R0(t[o],i):Nf(i)?t[o]=R0({},i):Rs(i)?t[o]=i.slice():t[o]=i};for(let i=0,u=arguments.length;i<u;i++)arguments[i]&&Vl(arguments[i],n);return t}const gV=(e,t,n,{allOwnKeys:i}={})=>(Vl(t,(u,o)=>{n&&rr(u)?e[o]=mx(u,n):e[o]=u},{allOwnKeys:i}),e),EV=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),yV=(e,t,n,i)=>{e.prototype=Object.create(t.prototype,i),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},bV=(e,t,n,i)=>{let u,o,l;const f={};if(t=t||{},e==null)return t;do{for(u=Object.getOwnPropertyNames(e),o=u.length;o-- >0;)l=u[o],(!i||i(l,e,t))&&!f[l]&&(t[l]=e[l],f[l]=!0);e=n!==!1&&$g(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},TV=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const i=e.indexOf(t,n);return i!==-1&&i===n},AV=e=>{if(!e)return null;if(Rs(e))return e;let t=e.length;if(!Ex(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},SV=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&$g(Uint8Array)),DV=(e,t)=>{const i=(e&&e[Ed]).call(e);let u;for(;(u=i.next())&&!u.done;){const o=u.value;t.call(e,o[0],o[1])}},vV=(e,t)=>{let n;const i=[];for(;(n=e.exec(t))!==null;)i.push(n);return i},CV=ti("HTMLFormElement"),_V=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,i,u){return i.toUpperCase()+u}),C2=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),xV=ti("RegExp"),Tx=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),i={};Vl(n,(u,o)=>{let l;(l=t(u,o,e))!==!1&&(i[o]=l||u)}),Object.defineProperties(e,i)},RV=e=>{Tx(e,(t,n)=>{if(rr(e)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const i=e[n];if(rr(i)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},wV=(e,t)=>{const n={},i=u=>{u.forEach(o=>{n[o]=!0})};return Rs(e)?i(e):i(String(e).split(t)),n},OV=()=>{},NV=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function kV(e){return!!(e&&rr(e.append)&&e[px]==="FormData"&&e[Ed])}const LV=e=>{const t=new Array(10),n=(i,u)=>{if(Td(i)){if(t.indexOf(i)>=0)return;if(!("toJSON"in i)){t[u]=i;const o=Rs(i)?[]:{};return Vl(i,(l,f)=>{const d=n(l,u+1);!xl(d)&&(o[f]=d)}),t[u]=void 0,o}}return i};return n(e,0)},MV=ti("AsyncFunction"),IV=e=>e&&(Td(e)||rr(e))&&rr(e.then)&&rr(e.catch),Ax=((e,t)=>e?setImmediate:t?((n,i)=>(au.addEventListener("message",({source:u,data:o})=>{u===au&&o===n&&i.length&&i.shift()()},!1),u=>{i.push(u),au.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",rr(au.postMessage)),PV=typeof queueMicrotask<"u"?queueMicrotask.bind(au):typeof process<"u"&&process.nextTick||Ax,FV=e=>e!=null&&rr(e[Ed]),ce={isArray:Rs,isArrayBuffer:gx,isBuffer:eV,isFormData:lV,isArrayBufferView:tV,isString:nV,isNumber:Ex,isBoolean:rV,isObject:Td,isPlainObject:Nf,isReadableStream:fV,isRequest:dV,isResponse:hV,isHeaders:mV,isUndefined:xl,isDate:iV,isFile:aV,isBlob:uV,isRegExp:xV,isFunction:rr,isStream:oV,isURLSearchParams:cV,isTypedArray:SV,isFileList:sV,forEach:Vl,merge:R0,extend:gV,trim:pV,stripBOM:EV,inherits:yV,toFlatObject:bV,kindOf:yd,kindOfTest:ti,endsWith:TV,toArray:AV,forEachEntry:DV,matchAll:vV,isHTMLForm:CV,hasOwnProperty:C2,hasOwnProp:C2,reduceDescriptors:Tx,freezeMethods:RV,toObjectSet:wV,toCamelCase:_V,noop:OV,toFiniteNumber:NV,findKey:yx,global:au,isContextDefined:bx,isSpecCompliantForm:kV,toJSONObject:LV,isAsyncFn:MV,isThenable:IV,setImmediate:Ax,asap:PV,isIterable:FV};function Je(e,t,n,i,u){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),i&&(this.request=i),u&&(this.response=u,this.status=u.status?u.status:null)}ce.inherits(Je,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:ce.toJSONObject(this.config),code:this.code,status:this.status}}});const Sx=Je.prototype,Dx={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{Dx[e]={value:e}});Object.defineProperties(Je,Dx);Object.defineProperty(Sx,"isAxiosError",{value:!0});Je.from=(e,t,n,i,u,o)=>{const l=Object.create(Sx);return ce.toFlatObject(e,l,function(d){return d!==Error.prototype},f=>f!=="isAxiosError"),Je.call(l,e.message,t,n,i,u),l.cause=e,l.name=e.name,o&&Object.assign(l,o),l};const BV=null;function w0(e){return ce.isPlainObject(e)||ce.isArray(e)}function vx(e){return ce.endsWith(e,"[]")?e.slice(0,-2):e}function _2(e,t,n){return e?e.concat(t).map(function(u,o){return u=vx(u),!n&&o?"["+u+"]":u}).join(n?".":""):t}function UV(e){return ce.isArray(e)&&!e.some(w0)}const HV=ce.toFlatObject(ce,{},null,function(t){return/^is[A-Z]/.test(t)});function Ad(e,t,n){if(!ce.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=ce.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(_,O){return!ce.isUndefined(O[_])});const i=n.metaTokens,u=n.visitor||p,o=n.dots,l=n.indexes,d=(n.Blob||typeof Blob<"u"&&Blob)&&ce.isSpecCompliantForm(t);if(!ce.isFunction(u))throw new TypeError("visitor must be a function");function h(A){if(A===null)return"";if(ce.isDate(A))return A.toISOString();if(ce.isBoolean(A))return A.toString();if(!d&&ce.isBlob(A))throw new Je("Blob is not supported. Use a Buffer instead.");return ce.isArrayBuffer(A)||ce.isTypedArray(A)?d&&typeof Blob=="function"?new Blob([A]):Buffer.from(A):A}function p(A,_,O){let C=A;if(A&&!O&&typeof A=="object"){if(ce.endsWith(_,"{}"))_=i?_:_.slice(0,-2),A=JSON.stringify(A);else if(ce.isArray(A)&&UV(A)||(ce.isFileList(A)||ce.endsWith(_,"[]"))&&(C=ce.toArray(A)))return _=vx(_),C.forEach(function(R,Y){!(ce.isUndefined(R)||R===null)&&t.append(l===!0?_2([_],Y,o):l===null?_:_+"[]",h(R))}),!1}return w0(A)?!0:(t.append(_2(O,_,o),h(A)),!1)}const g=[],b=Object.assign(HV,{defaultVisitor:p,convertValue:h,isVisitable:w0});function T(A,_){if(!ce.isUndefined(A)){if(g.indexOf(A)!==-1)throw Error("Circular reference detected in "+_.join("."));g.push(A),ce.forEach(A,function(C,N){(!(ce.isUndefined(C)||C===null)&&u.call(t,C,ce.isString(N)?N.trim():N,_,b))===!0&&T(C,_?_.concat(N):[N])}),g.pop()}}if(!ce.isObject(e))throw new TypeError("data must be an object");return T(e),t}function x2(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(i){return t[i]})}function Zg(e,t){this._pairs=[],e&&Ad(e,this,t)}const Cx=Zg.prototype;Cx.append=function(t,n){this._pairs.push([t,n])};Cx.toString=function(t){const n=t?function(i){return t.call(this,i,x2)}:x2;return this._pairs.map(function(u){return n(u[0])+"="+n(u[1])},"").join("&")};function zV(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function _x(e,t,n){if(!t)return e;const i=n&&n.encode||zV;ce.isFunction(n)&&(n={serialize:n});const u=n&&n.serialize;let o;if(u?o=u(t,n):o=ce.isURLSearchParams(t)?t.toString():new Zg(t,n).toString(i),o){const l=e.indexOf("#");l!==-1&&(e=e.slice(0,l)),e+=(e.indexOf("?")===-1?"?":"&")+o}return e}class R2{constructor(){this.handlers=[]}use(t,n,i){return this.handlers.push({fulfilled:t,rejected:n,synchronous:i?i.synchronous:!1,runWhen:i?i.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){ce.forEach(this.handlers,function(i){i!==null&&t(i)})}}const xx={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},VV=typeof URLSearchParams<"u"?URLSearchParams:Zg,jV=typeof FormData<"u"?FormData:null,qV=typeof Blob<"u"?Blob:null,YV={isBrowser:!0,classes:{URLSearchParams:VV,FormData:jV,Blob:qV},protocols:["http","https","file","blob","url","data"]},Jg=typeof window<"u"&&typeof document<"u",O0=typeof navigator=="object"&&navigator||void 0,GV=Jg&&(!O0||["ReactNative","NativeScript","NS"].indexOf(O0.product)<0),XV=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",KV=Jg&&window.location.href||"http://localhost",WV=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:Jg,hasStandardBrowserEnv:GV,hasStandardBrowserWebWorkerEnv:XV,navigator:O0,origin:KV},Symbol.toStringTag,{value:"Module"})),Ln={...WV,...YV};function QV(e,t){return Ad(e,new Ln.classes.URLSearchParams,Object.assign({visitor:function(n,i,u,o){return Ln.isNode&&ce.isBuffer(n)?(this.append(i,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)}},t))}function $V(e){return ce.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"":t[1]||t[0])}function ZV(e){const t={},n=Object.keys(e);let i;const u=n.length;let o;for(i=0;i<u;i++)o=n[i],t[o]=e[o];return t}function Rx(e){function t(n,i,u,o){let l=n[o++];if(l==="__proto__")return!0;const f=Number.isFinite(+l),d=o>=n.length;return l=!l&&ce.isArray(u)?u.length:l,d?(ce.hasOwnProp(u,l)?u[l]=[u[l],i]:u[l]=i,!f):((!u[l]||!ce.isObject(u[l]))&&(u[l]=[]),t(n,i,u[l],o)&&ce.isArray(u[l])&&(u[l]=ZV(u[l])),!f)}if(ce.isFormData(e)&&ce.isFunction(e.entries)){const n={};return ce.forEachEntry(e,(i,u)=>{t($V(i),u,n,0)}),n}return null}function JV(e,t,n){if(ce.isString(e))try{return(t||JSON.parse)(e),ce.trim(e)}catch(i){if(i.name!=="SyntaxError")throw i}return(n||JSON.stringify)(e)}const jl={transitional:xx,adapter:["xhr","http","fetch"],transformRequest:[function(t,n){const i=n.getContentType()||"",u=i.indexOf("application/json")>-1,o=ce.isObject(t);if(o&&ce.isHTMLForm(t)&&(t=new FormData(t)),ce.isFormData(t))return u?JSON.stringify(Rx(t)):t;if(ce.isArrayBuffer(t)||ce.isBuffer(t)||ce.isStream(t)||ce.isFile(t)||ce.isBlob(t)||ce.isReadableStream(t))return t;if(ce.isArrayBufferView(t))return t.buffer;if(ce.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let f;if(o){if(i.indexOf("application/x-www-form-urlencoded")>-1)return QV(t,this.formSerializer).toString();if((f=ce.isFileList(t))||i.indexOf("multipart/form-data")>-1){const d=this.env&&this.env.FormData;return Ad(f?{"files[]":t}:t,d&&new d,this.formSerializer)}}return o||u?(n.setContentType("application/json",!1),JV(t)):t}],transformResponse:[function(t){const n=this.transitional||jl.transitional,i=n&&n.forcedJSONParsing,u=this.responseType==="json";if(ce.isResponse(t)||ce.isReadableStream(t))return t;if(t&&ce.isString(t)&&(i&&!this.responseType||u)){const l=!(n&&n.silentJSONParsing)&&u;try{return JSON.parse(t)}catch(f){if(l)throw f.name==="SyntaxError"?Je.from(f,Je.ERR_BAD_RESPONSE,this,null,this.response):f}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:Ln.classes.FormData,Blob:Ln.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};ce.forEach(["delete","get","head","post","put","patch"],e=>{jl.headers[e]={}});const ej=ce.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),tj=e=>{const t={};let n,i,u;return e&&e.split(` +`).forEach(function(l){u=l.indexOf(":"),n=l.substring(0,u).trim().toLowerCase(),i=l.substring(u+1).trim(),!(!n||t[n]&&ej[n])&&(n==="set-cookie"?t[n]?t[n].push(i):t[n]=[i]:t[n]=t[n]?t[n]+", "+i:i)}),t},w2=Symbol("internals");function Qo(e){return e&&String(e).trim().toLowerCase()}function kf(e){return e===!1||e==null?e:ce.isArray(e)?e.map(kf):String(e)}function nj(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let i;for(;i=n.exec(e);)t[i[1]]=i[2];return t}const rj=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function Np(e,t,n,i,u){if(ce.isFunction(i))return i.call(this,t,n);if(u&&(t=n),!!ce.isString(t)){if(ce.isString(i))return t.indexOf(i)!==-1;if(ce.isRegExp(i))return i.test(t)}}function ij(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,i)=>n.toUpperCase()+i)}function aj(e,t){const n=ce.toCamelCase(" "+t);["get","set","has"].forEach(i=>{Object.defineProperty(e,i+n,{value:function(u,o,l){return this[i].call(this,t,u,o,l)},configurable:!0})})}let ir=class{constructor(t){t&&this.set(t)}set(t,n,i){const u=this;function o(f,d,h){const p=Qo(d);if(!p)throw new Error("header name must be a non-empty string");const g=ce.findKey(u,p);(!g||u[g]===void 0||h===!0||h===void 0&&u[g]!==!1)&&(u[g||d]=kf(f))}const l=(f,d)=>ce.forEach(f,(h,p)=>o(h,p,d));if(ce.isPlainObject(t)||t instanceof this.constructor)l(t,n);else if(ce.isString(t)&&(t=t.trim())&&!rj(t))l(tj(t),n);else if(ce.isObject(t)&&ce.isIterable(t)){let f={},d,h;for(const p of t){if(!ce.isArray(p))throw TypeError("Object iterator must return a key-value pair");f[h=p[0]]=(d=f[h])?ce.isArray(d)?[...d,p[1]]:[d,p[1]]:p[1]}l(f,n)}else t!=null&&o(n,t,i);return this}get(t,n){if(t=Qo(t),t){const i=ce.findKey(this,t);if(i){const u=this[i];if(!n)return u;if(n===!0)return nj(u);if(ce.isFunction(n))return n.call(this,u,i);if(ce.isRegExp(n))return n.exec(u);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=Qo(t),t){const i=ce.findKey(this,t);return!!(i&&this[i]!==void 0&&(!n||Np(this,this[i],i,n)))}return!1}delete(t,n){const i=this;let u=!1;function o(l){if(l=Qo(l),l){const f=ce.findKey(i,l);f&&(!n||Np(i,i[f],f,n))&&(delete i[f],u=!0)}}return ce.isArray(t)?t.forEach(o):o(t),u}clear(t){const n=Object.keys(this);let i=n.length,u=!1;for(;i--;){const o=n[i];(!t||Np(this,this[o],o,t,!0))&&(delete this[o],u=!0)}return u}normalize(t){const n=this,i={};return ce.forEach(this,(u,o)=>{const l=ce.findKey(i,o);if(l){n[l]=kf(u),delete n[o];return}const f=t?ij(o):String(o).trim();f!==o&&delete n[o],n[f]=kf(u),i[f]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return ce.forEach(this,(i,u)=>{i!=null&&i!==!1&&(n[u]=t&&ce.isArray(i)?i.join(", "):i)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(` +`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const i=new this(t);return n.forEach(u=>i.set(u)),i}static accessor(t){const i=(this[w2]=this[w2]={accessors:{}}).accessors,u=this.prototype;function o(l){const f=Qo(l);i[f]||(aj(u,l),i[f]=!0)}return ce.isArray(t)?t.forEach(o):o(t),this}};ir.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);ce.reduceDescriptors(ir.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(i){this[n]=i}}});ce.freezeMethods(ir);function kp(e,t){const n=this||jl,i=t||n,u=ir.from(i.headers);let o=i.data;return ce.forEach(e,function(f){o=f.call(n,o,u.normalize(),t?t.status:void 0)}),u.normalize(),o}function wx(e){return!!(e&&e.__CANCEL__)}function ws(e,t,n){Je.call(this,e??"canceled",Je.ERR_CANCELED,t,n),this.name="CanceledError"}ce.inherits(ws,Je,{__CANCEL__:!0});function Ox(e,t,n){const i=n.config.validateStatus;!n.status||!i||i(n.status)?e(n):t(new Je("Request failed with status code "+n.status,[Je.ERR_BAD_REQUEST,Je.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function uj(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function sj(e,t){e=e||10;const n=new Array(e),i=new Array(e);let u=0,o=0,l;return t=t!==void 0?t:1e3,function(d){const h=Date.now(),p=i[o];l||(l=h),n[u]=d,i[u]=h;let g=o,b=0;for(;g!==u;)b+=n[g++],g=g%e;if(u=(u+1)%e,u===o&&(o=(o+1)%e),h-l<t)return;const T=p&&h-p;return T?Math.round(b*1e3/T):void 0}}function oj(e,t){let n=0,i=1e3/t,u,o;const l=(h,p=Date.now())=>{n=p,u=null,o&&(clearTimeout(o),o=null),e.apply(null,h)};return[(...h)=>{const p=Date.now(),g=p-n;g>=i?l(h,p):(u=h,o||(o=setTimeout(()=>{o=null,l(u)},i-g)))},()=>u&&l(u)]}const Wf=(e,t,n=3)=>{let i=0;const u=sj(50,250);return oj(o=>{const l=o.loaded,f=o.lengthComputable?o.total:void 0,d=l-i,h=u(d),p=l<=f;i=l;const g={loaded:l,total:f,progress:f?l/f:void 0,bytes:d,rate:h||void 0,estimated:h&&f&&p?(f-l)/h:void 0,event:o,lengthComputable:f!=null,[t?"download":"upload"]:!0};e(g)},n)},O2=(e,t)=>{const n=e!=null;return[i=>t[0]({lengthComputable:n,total:e,loaded:i}),t[1]]},N2=e=>(...t)=>ce.asap(()=>e(...t)),lj=Ln.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,Ln.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(Ln.origin),Ln.navigator&&/(msie|trident)/i.test(Ln.navigator.userAgent)):()=>!0,cj=Ln.hasStandardBrowserEnv?{write(e,t,n,i,u,o){const l=[e+"="+encodeURIComponent(t)];ce.isNumber(n)&&l.push("expires="+new Date(n).toGMTString()),ce.isString(i)&&l.push("path="+i),ce.isString(u)&&l.push("domain="+u),o===!0&&l.push("secure"),document.cookie=l.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function fj(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function dj(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function Nx(e,t,n){let i=!fj(t);return e&&(i||n==!1)?dj(e,t):t}const k2=e=>e instanceof ir?{...e}:e;function fu(e,t){t=t||{};const n={};function i(h,p,g,b){return ce.isPlainObject(h)&&ce.isPlainObject(p)?ce.merge.call({caseless:b},h,p):ce.isPlainObject(p)?ce.merge({},p):ce.isArray(p)?p.slice():p}function u(h,p,g,b){if(ce.isUndefined(p)){if(!ce.isUndefined(h))return i(void 0,h,g,b)}else return i(h,p,g,b)}function o(h,p){if(!ce.isUndefined(p))return i(void 0,p)}function l(h,p){if(ce.isUndefined(p)){if(!ce.isUndefined(h))return i(void 0,h)}else return i(void 0,p)}function f(h,p,g){if(g in t)return i(h,p);if(g in e)return i(void 0,h)}const d={url:o,method:o,data:o,baseURL:l,transformRequest:l,transformResponse:l,paramsSerializer:l,timeout:l,timeoutMessage:l,withCredentials:l,withXSRFToken:l,adapter:l,responseType:l,xsrfCookieName:l,xsrfHeaderName:l,onUploadProgress:l,onDownloadProgress:l,decompress:l,maxContentLength:l,maxBodyLength:l,beforeRedirect:l,transport:l,httpAgent:l,httpsAgent:l,cancelToken:l,socketPath:l,responseEncoding:l,validateStatus:f,headers:(h,p,g)=>u(k2(h),k2(p),g,!0)};return ce.forEach(Object.keys(Object.assign({},e,t)),function(p){const g=d[p]||u,b=g(e[p],t[p],p);ce.isUndefined(b)&&g!==f||(n[p]=b)}),n}const kx=e=>{const t=fu({},e);let{data:n,withXSRFToken:i,xsrfHeaderName:u,xsrfCookieName:o,headers:l,auth:f}=t;t.headers=l=ir.from(l),t.url=_x(Nx(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),f&&l.set("Authorization","Basic "+btoa((f.username||"")+":"+(f.password?unescape(encodeURIComponent(f.password)):"")));let d;if(ce.isFormData(n)){if(Ln.hasStandardBrowserEnv||Ln.hasStandardBrowserWebWorkerEnv)l.setContentType(void 0);else if((d=l.getContentType())!==!1){const[h,...p]=d?d.split(";").map(g=>g.trim()).filter(Boolean):[];l.setContentType([h||"multipart/form-data",...p].join("; "))}}if(Ln.hasStandardBrowserEnv&&(i&&ce.isFunction(i)&&(i=i(t)),i||i!==!1&&lj(t.url))){const h=u&&o&&cj.read(o);h&&l.set(u,h)}return t},hj=typeof XMLHttpRequest<"u",mj=hj&&function(e){return new Promise(function(n,i){const u=kx(e);let o=u.data;const l=ir.from(u.headers).normalize();let{responseType:f,onUploadProgress:d,onDownloadProgress:h}=u,p,g,b,T,A;function _(){T&&T(),A&&A(),u.cancelToken&&u.cancelToken.unsubscribe(p),u.signal&&u.signal.removeEventListener("abort",p)}let O=new XMLHttpRequest;O.open(u.method.toUpperCase(),u.url,!0),O.timeout=u.timeout;function C(){if(!O)return;const R=ir.from("getAllResponseHeaders"in O&&O.getAllResponseHeaders()),M={data:!f||f==="text"||f==="json"?O.responseText:O.response,status:O.status,statusText:O.statusText,headers:R,config:e,request:O};Ox(function(J){n(J),_()},function(J){i(J),_()},M),O=null}"onloadend"in O?O.onloadend=C:O.onreadystatechange=function(){!O||O.readyState!==4||O.status===0&&!(O.responseURL&&O.responseURL.indexOf("file:")===0)||setTimeout(C)},O.onabort=function(){O&&(i(new Je("Request aborted",Je.ECONNABORTED,e,O)),O=null)},O.onerror=function(){i(new Je("Network Error",Je.ERR_NETWORK,e,O)),O=null},O.ontimeout=function(){let Y=u.timeout?"timeout of "+u.timeout+"ms exceeded":"timeout exceeded";const M=u.transitional||xx;u.timeoutErrorMessage&&(Y=u.timeoutErrorMessage),i(new Je(Y,M.clarifyTimeoutError?Je.ETIMEDOUT:Je.ECONNABORTED,e,O)),O=null},o===void 0&&l.setContentType(null),"setRequestHeader"in O&&ce.forEach(l.toJSON(),function(Y,M){O.setRequestHeader(M,Y)}),ce.isUndefined(u.withCredentials)||(O.withCredentials=!!u.withCredentials),f&&f!=="json"&&(O.responseType=u.responseType),h&&([b,A]=Wf(h,!0),O.addEventListener("progress",b)),d&&O.upload&&([g,T]=Wf(d),O.upload.addEventListener("progress",g),O.upload.addEventListener("loadend",T)),(u.cancelToken||u.signal)&&(p=R=>{O&&(i(!R||R.type?new ws(null,e,O):R),O.abort(),O=null)},u.cancelToken&&u.cancelToken.subscribe(p),u.signal&&(u.signal.aborted?p():u.signal.addEventListener("abort",p)));const N=uj(u.url);if(N&&Ln.protocols.indexOf(N)===-1){i(new Je("Unsupported protocol "+N+":",Je.ERR_BAD_REQUEST,e));return}O.send(o||null)})},pj=(e,t)=>{const{length:n}=e=e?e.filter(Boolean):[];if(t||n){let i=new AbortController,u;const o=function(h){if(!u){u=!0,f();const p=h instanceof Error?h:this.reason;i.abort(p instanceof Je?p:new ws(p instanceof Error?p.message:p))}};let l=t&&setTimeout(()=>{l=null,o(new Je(`timeout ${t} of ms exceeded`,Je.ETIMEDOUT))},t);const f=()=>{e&&(l&&clearTimeout(l),l=null,e.forEach(h=>{h.unsubscribe?h.unsubscribe(o):h.removeEventListener("abort",o)}),e=null)};e.forEach(h=>h.addEventListener("abort",o));const{signal:d}=i;return d.unsubscribe=()=>ce.asap(f),d}},gj=function*(e,t){let n=e.byteLength;if(n<t){yield e;return}let i=0,u;for(;i<n;)u=i+t,yield e.slice(i,u),i=u},Ej=async function*(e,t){for await(const n of yj(e))yield*gj(n,t)},yj=async function*(e){if(e[Symbol.asyncIterator]){yield*e;return}const t=e.getReader();try{for(;;){const{done:n,value:i}=await t.read();if(n)break;yield i}}finally{await t.cancel()}},L2=(e,t,n,i)=>{const u=Ej(e,t);let o=0,l,f=d=>{l||(l=!0,i&&i(d))};return new ReadableStream({async pull(d){try{const{done:h,value:p}=await u.next();if(h){f(),d.close();return}let g=p.byteLength;if(n){let b=o+=g;n(b)}d.enqueue(new Uint8Array(p))}catch(h){throw f(h),h}},cancel(d){return f(d),u.return()}},{highWaterMark:2})},Sd=typeof fetch=="function"&&typeof Request=="function"&&typeof Response=="function",Lx=Sd&&typeof ReadableStream=="function",bj=Sd&&(typeof TextEncoder=="function"?(e=>t=>e.encode(t))(new TextEncoder):async e=>new Uint8Array(await new Response(e).arrayBuffer())),Mx=(e,...t)=>{try{return!!e(...t)}catch{return!1}},Tj=Lx&&Mx(()=>{let e=!1;const t=new Request(Ln.origin,{body:new ReadableStream,method:"POST",get duplex(){return e=!0,"half"}}).headers.has("Content-Type");return e&&!t}),M2=64*1024,N0=Lx&&Mx(()=>ce.isReadableStream(new Response("").body)),Qf={stream:N0&&(e=>e.body)};Sd&&(e=>{["text","arrayBuffer","blob","formData","stream"].forEach(t=>{!Qf[t]&&(Qf[t]=ce.isFunction(e[t])?n=>n[t]():(n,i)=>{throw new Je(`Response type '${t}' is not supported`,Je.ERR_NOT_SUPPORT,i)})})})(new Response);const Aj=async e=>{if(e==null)return 0;if(ce.isBlob(e))return e.size;if(ce.isSpecCompliantForm(e))return(await new Request(Ln.origin,{method:"POST",body:e}).arrayBuffer()).byteLength;if(ce.isArrayBufferView(e)||ce.isArrayBuffer(e))return e.byteLength;if(ce.isURLSearchParams(e)&&(e=e+""),ce.isString(e))return(await bj(e)).byteLength},Sj=async(e,t)=>{const n=ce.toFiniteNumber(e.getContentLength());return n??Aj(t)},Dj=Sd&&(async e=>{let{url:t,method:n,data:i,signal:u,cancelToken:o,timeout:l,onDownloadProgress:f,onUploadProgress:d,responseType:h,headers:p,withCredentials:g="same-origin",fetchOptions:b}=kx(e);h=h?(h+"").toLowerCase():"text";let T=pj([u,o&&o.toAbortSignal()],l),A;const _=T&&T.unsubscribe&&(()=>{T.unsubscribe()});let O;try{if(d&&Tj&&n!=="get"&&n!=="head"&&(O=await Sj(p,i))!==0){let M=new Request(t,{method:"POST",body:i,duplex:"half"}),v;if(ce.isFormData(i)&&(v=M.headers.get("content-type"))&&p.setContentType(v),M.body){const[J,P]=O2(O,Wf(N2(d)));i=L2(M.body,M2,J,P)}}ce.isString(g)||(g=g?"include":"omit");const C="credentials"in Request.prototype;A=new Request(t,{...b,signal:T,method:n.toUpperCase(),headers:p.normalize().toJSON(),body:i,duplex:"half",credentials:C?g:void 0});let N=await fetch(A,b);const R=N0&&(h==="stream"||h==="response");if(N0&&(f||R&&_)){const M={};["status","statusText","headers"].forEach(q=>{M[q]=N[q]});const v=ce.toFiniteNumber(N.headers.get("content-length")),[J,P]=f&&O2(v,Wf(N2(f),!0))||[];N=new Response(L2(N.body,M2,J,()=>{P&&P(),_&&_()}),M)}h=h||"text";let Y=await Qf[ce.findKey(Qf,h)||"text"](N,e);return!R&&_&&_(),await new Promise((M,v)=>{Ox(M,v,{data:Y,headers:ir.from(N.headers),status:N.status,statusText:N.statusText,config:e,request:A})})}catch(C){throw _&&_(),C&&C.name==="TypeError"&&/Load failed|fetch/i.test(C.message)?Object.assign(new Je("Network Error",Je.ERR_NETWORK,e,A),{cause:C.cause||C}):Je.from(C,C&&C.code,e,A)}}),k0={http:BV,xhr:mj,fetch:Dj};ce.forEach(k0,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch{}Object.defineProperty(e,"adapterName",{value:t})}});const I2=e=>`- ${e}`,vj=e=>ce.isFunction(e)||e===null||e===!1,Ix={getAdapter:e=>{e=ce.isArray(e)?e:[e];const{length:t}=e;let n,i;const u={};for(let o=0;o<t;o++){n=e[o];let l;if(i=n,!vj(n)&&(i=k0[(l=String(n)).toLowerCase()],i===void 0))throw new Je(`Unknown adapter '${l}'`);if(i)break;u[l||"#"+o]=i}if(!i){const o=Object.entries(u).map(([f,d])=>`adapter ${f} `+(d===!1?"is not supported by the environment":"is not available in the build"));let l=t?o.length>1?`since : +`+o.map(I2).join(` +`):" "+I2(o[0]):"as no adapter specified";throw new Je("There is no suitable adapter to dispatch the request "+l,"ERR_NOT_SUPPORT")}return i},adapters:k0};function Lp(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new ws(null,e)}function P2(e){return Lp(e),e.headers=ir.from(e.headers),e.data=kp.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),Ix.getAdapter(e.adapter||jl.adapter)(e).then(function(i){return Lp(e),i.data=kp.call(e,e.transformResponse,i),i.headers=ir.from(i.headers),i},function(i){return wx(i)||(Lp(e),i&&i.response&&(i.response.data=kp.call(e,e.transformResponse,i.response),i.response.headers=ir.from(i.response.headers))),Promise.reject(i)})}const Px="1.10.0",Dd={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{Dd[e]=function(i){return typeof i===e||"a"+(t<1?"n ":" ")+e}});const F2={};Dd.transitional=function(t,n,i){function u(o,l){return"[Axios v"+Px+"] Transitional option '"+o+"'"+l+(i?". "+i:"")}return(o,l,f)=>{if(t===!1)throw new Je(u(l," has been removed"+(n?" in "+n:"")),Je.ERR_DEPRECATED);return n&&!F2[l]&&(F2[l]=!0,console.warn(u(l," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,l,f):!0}};Dd.spelling=function(t){return(n,i)=>(console.warn(`${i} is likely a misspelling of ${t}`),!0)};function Cj(e,t,n){if(typeof e!="object")throw new Je("options must be an object",Je.ERR_BAD_OPTION_VALUE);const i=Object.keys(e);let u=i.length;for(;u-- >0;){const o=i[u],l=t[o];if(l){const f=e[o],d=f===void 0||l(f,o,e);if(d!==!0)throw new Je("option "+o+" must be "+d,Je.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new Je("Unknown option "+o,Je.ERR_BAD_OPTION)}}const Lf={assertOptions:Cj,validators:Dd},fi=Lf.validators;let lu=class{constructor(t){this.defaults=t||{},this.interceptors={request:new R2,response:new R2}}async request(t,n){try{return await this._request(t,n)}catch(i){if(i instanceof Error){let u={};Error.captureStackTrace?Error.captureStackTrace(u):u=new Error;const o=u.stack?u.stack.replace(/^.+\n/,""):"";try{i.stack?o&&!String(i.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(i.stack+=` +`+o):i.stack=o}catch{}}throw i}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=fu(this.defaults,n);const{transitional:i,paramsSerializer:u,headers:o}=n;i!==void 0&&Lf.assertOptions(i,{silentJSONParsing:fi.transitional(fi.boolean),forcedJSONParsing:fi.transitional(fi.boolean),clarifyTimeoutError:fi.transitional(fi.boolean)},!1),u!=null&&(ce.isFunction(u)?n.paramsSerializer={serialize:u}:Lf.assertOptions(u,{encode:fi.function,serialize:fi.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Lf.assertOptions(n,{baseUrl:fi.spelling("baseURL"),withXsrfToken:fi.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let l=o&&ce.merge(o.common,o[n.method]);o&&ce.forEach(["delete","get","head","post","put","patch","common"],A=>{delete o[A]}),n.headers=ir.concat(l,o);const f=[];let d=!0;this.interceptors.request.forEach(function(_){typeof _.runWhen=="function"&&_.runWhen(n)===!1||(d=d&&_.synchronous,f.unshift(_.fulfilled,_.rejected))});const h=[];this.interceptors.response.forEach(function(_){h.push(_.fulfilled,_.rejected)});let p,g=0,b;if(!d){const A=[P2.bind(this),void 0];for(A.unshift.apply(A,f),A.push.apply(A,h),b=A.length,p=Promise.resolve(n);g<b;)p=p.then(A[g++],A[g++]);return p}b=f.length;let T=n;for(g=0;g<b;){const A=f[g++],_=f[g++];try{T=A(T)}catch(O){_.call(this,O);break}}try{p=P2.call(this,T)}catch(A){return Promise.reject(A)}for(g=0,b=h.length;g<b;)p=p.then(h[g++],h[g++]);return p}getUri(t){t=fu(this.defaults,t);const n=Nx(t.baseURL,t.url,t.allowAbsoluteUrls);return _x(n,t.params,t.paramsSerializer)}};ce.forEach(["delete","get","head","options"],function(t){lu.prototype[t]=function(n,i){return this.request(fu(i||{},{method:t,url:n,data:(i||{}).data}))}});ce.forEach(["post","put","patch"],function(t){function n(i){return function(o,l,f){return this.request(fu(f||{},{method:t,headers:i?{"Content-Type":"multipart/form-data"}:{},url:o,data:l}))}}lu.prototype[t]=n(),lu.prototype[t+"Form"]=n(!0)});let _j=class Fx{constructor(t){if(typeof t!="function")throw new TypeError("executor must be a function.");let n;this.promise=new Promise(function(o){n=o});const i=this;this.promise.then(u=>{if(!i._listeners)return;let o=i._listeners.length;for(;o-- >0;)i._listeners[o](u);i._listeners=null}),this.promise.then=u=>{let o;const l=new Promise(f=>{i.subscribe(f),o=f}).then(u);return l.cancel=function(){i.unsubscribe(o)},l},t(function(o,l,f){i.reason||(i.reason=new ws(o,l,f),n(i.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const t=new AbortController,n=i=>{t.abort(i)};return this.subscribe(n),t.signal.unsubscribe=()=>this.unsubscribe(n),t.signal}static source(){let t;return{token:new Fx(function(u){t=u}),cancel:t}}};function xj(e){return function(n){return e.apply(null,n)}}function Rj(e){return ce.isObject(e)&&e.isAxiosError===!0}const L0={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(L0).forEach(([e,t])=>{L0[t]=e});function Bx(e){const t=new lu(e),n=mx(lu.prototype.request,t);return ce.extend(n,lu.prototype,t,{allOwnKeys:!0}),ce.extend(n,t,null,{allOwnKeys:!0}),n.create=function(u){return Bx(fu(e,u))},n}const gn=Bx(jl);gn.Axios=lu;gn.CanceledError=ws;gn.CancelToken=_j;gn.isCancel=wx;gn.VERSION=Px;gn.toFormData=Ad;gn.AxiosError=Je;gn.Cancel=gn.CanceledError;gn.all=function(t){return Promise.all(t)};gn.spread=xj;gn.isAxiosError=Rj;gn.mergeConfig=fu;gn.AxiosHeaders=ir;gn.formToJSON=e=>Rx(ce.isHTMLForm(e)?new FormData(e):e);gn.getAdapter=Ix.getAdapter;gn.HttpStatusCode=L0;gn.default=gn;const{Axios:Rq,AxiosError:wq,CanceledError:Oq,isCancel:Nq,CancelToken:kq,VERSION:Lq,all:Mq,Cancel:Iq,isAxiosError:Pq,spread:Fq,toFormData:Bq,AxiosHeaders:Uq,HttpStatusCode:Hq,formToJSON:zq,getAdapter:Vq,mergeConfig:jq}=gn;export{Oj as $,Ij as A,qj as B,Yj as C,Xj as D,Cq as E,Zj as F,eq as G,$j as H,nq as I,iq as J,cq as K,lD as L,Eq as M,kj as N,Qj as O,Kj as P,Wj as Q,tq as R,sq as S,fq as T,dq as U,gn as V,oq as W,Jj as X,hq as Y,Lj as Z,Mj as _,Bj as a,wj as a0,rD as b,Uj as c,Nj as d,aq as e,rq as f,lq as g,uq as h,Vj as i,Br as j,h2 as k,Aq as l,Fj as m,vq as n,Sq as o,Dq as p,Q9 as q,W as r,Tq as s,Hj as t,xa as u,yq as v,bq as w,zj as x,jj as y,Gj as z}; diff --git a/assets/vendor-h0EPuWW_.css b/assets/vendor-h0EPuWW_.css new file mode 100644 index 00000000..57162b08 --- /dev/null +++ b/assets/vendor-h0EPuWW_.css @@ -0,0 +1 @@ +.carousel .control-arrow,.carousel.carousel-slider .control-arrow{-webkit-transition:all .25s ease-in;-moz-transition:all .25s ease-in;-ms-transition:all .25s ease-in;-o-transition:all .25s ease-in;transition:all .25s ease-in;opacity:.4;filter:alpha(opacity=40);position:absolute;z-index:2;top:20px;background:none;border:0;font-size:32px;cursor:pointer}.carousel .control-arrow:focus,.carousel .control-arrow:hover{opacity:1;filter:alpha(opacity=100)}.carousel .control-arrow:before,.carousel.carousel-slider .control-arrow:before{margin:0 5px;display:inline-block;border-top:8px solid transparent;border-bottom:8px solid transparent;content:""}.carousel .control-disabled.control-arrow{opacity:0;filter:alpha(opacity=0);cursor:inherit;display:none}.carousel .control-prev.control-arrow{left:0}.carousel .control-prev.control-arrow:before{border-right:8px solid #fff}.carousel .control-next.control-arrow{right:0}.carousel .control-next.control-arrow:before{border-left:8px solid #fff}.carousel-root{outline:none}.carousel{position:relative;width:100%}.carousel *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.carousel img{width:100%;display:inline-block;pointer-events:none}.carousel .carousel{position:relative}.carousel .control-arrow{outline:0;border:0;background:none;top:50%;margin-top:-13px;font-size:18px}.carousel .thumbs-wrapper{margin:20px;overflow:hidden}.carousel .thumbs{-webkit-transition:all .15s ease-in;-moz-transition:all .15s ease-in;-ms-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translateZ(0);position:relative;list-style:none;white-space:nowrap}.carousel .thumb{-webkit-transition:border .15s ease-in;-moz-transition:border .15s ease-in;-ms-transition:border .15s ease-in;-o-transition:border .15s ease-in;transition:border .15s ease-in;display:inline-block;margin-right:6px;white-space:nowrap;overflow:hidden;border:3px solid #fff;padding:2px}.carousel .thumb:focus{border:3px solid #ccc;outline:none}.carousel .thumb.selected,.carousel .thumb:hover{border:3px solid #333}.carousel .thumb img{vertical-align:top}.carousel.carousel-slider{position:relative;margin:0;overflow:hidden}.carousel.carousel-slider .control-arrow{top:0;color:#fff;font-size:26px;bottom:0;margin-top:0;padding:5px}.carousel.carousel-slider .control-arrow:hover{background:#0003}.carousel .slider-wrapper{overflow:hidden;margin:auto;width:100%;-webkit-transition:height .15s ease-in;-moz-transition:height .15s ease-in;-ms-transition:height .15s ease-in;-o-transition:height .15s ease-in;transition:height .15s ease-in}.carousel .slider-wrapper.axis-horizontal .slider{-ms-box-orient:horizontal;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-moz-flex;display:-webkit-flex;display:flex}.carousel .slider-wrapper.axis-horizontal .slider .slide{flex-direction:column;flex-flow:column}.carousel .slider-wrapper.axis-vertical{-ms-box-orient:horizontal;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-moz-flex;display:-webkit-flex;display:flex}.carousel .slider-wrapper.axis-vertical .slider{-webkit-flex-direction:column;flex-direction:column}.carousel .slider{margin:0;padding:0;position:relative;list-style:none;width:100%}.carousel .slider.animated{-webkit-transition:all .35s ease-in-out;-moz-transition:all .35s ease-in-out;-ms-transition:all .35s ease-in-out;-o-transition:all .35s ease-in-out;transition:all .35s ease-in-out}.carousel .slide{min-width:100%;margin:0;position:relative;text-align:center}.carousel .slide img{width:100%;vertical-align:top;border:0}.carousel .slide iframe{display:inline-block;width:calc(100% - 80px);margin:0 40px 40px;border:0}.carousel .slide .legend{-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out;position:absolute;bottom:40px;left:50%;margin-left:-45%;width:90%;border-radius:10px;background:#000;color:#fff;padding:10px;font-size:12px;text-align:center;opacity:.25;-webkit-transition:opacity .35s ease-in-out;-moz-transition:opacity .35s ease-in-out;-ms-transition:opacity .35s ease-in-out;-o-transition:opacity .35s ease-in-out;transition:opacity .35s ease-in-out}.carousel .control-dots{position:absolute;bottom:0;margin:10px 0;padding:0;text-align:center;width:100%;z-index:1}@media (min-width: 960px){.carousel .control-dots{bottom:0}}.carousel .control-dots .dot{-webkit-transition:opacity .25s ease-in;-moz-transition:opacity .25s ease-in;-ms-transition:opacity .25s ease-in;-o-transition:opacity .25s ease-in;transition:opacity .25s ease-in;opacity:.3;filter:alpha(opacity=30);box-shadow:1px 1px 2px #000000e6;background:#fff;border-radius:50%;width:8px;height:8px;cursor:pointer;display:inline-block;margin:0 8px}.carousel .control-dots .dot.selected,.carousel .control-dots .dot:hover{opacity:1;filter:alpha(opacity=100)}.carousel .carousel-status{position:absolute;top:0;right:0;padding:5px;font-size:10px;text-shadow:1px 1px 1px rgba(0,0,0,.9);color:#fff}.carousel:hover .slide .legend{opacity:1} diff --git a/components.json b/components.json deleted file mode 100644 index 3cc2342f..00000000 --- a/components.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema.json", - "style": "new-york", - "rsc": false, - "tsx": true, - "tailwind": { - "config": "", - "css": "src/styles/globals.css", - "baseColor": "zinc", - "cssVariables": true, - "prefix": "" - }, - "aliases": { - "components": "@/components", - "utils": "@/lib/utils", - "ui": "@/components/ui", - "lib": "@/lib", - "hooks": "@/hooks" - }, - "iconLibrary": "lucide" -} diff --git a/docs/Adding_favicon.md b/docs/Adding_favicon.md deleted file mode 100644 index 3e132e8d..00000000 --- a/docs/Adding_favicon.md +++ /dev/null @@ -1,24 +0,0 @@ -# Adding a Favicon - -## Steps to Add a New Favicon - -1. **Prepare the Favicon File:** - - Create an SVG (preferred) or PNG file for the favicon. - - Ensure the favicon design aligns with the existing ones. - -2. **Place the Favicon in the Correct Directory:** - - Move the favicon file to the `public/favicons/` folder. - -3. **Update the Favicon List:** - - Open the `public/Randomfavicon.js` file. - - Locate the `const favicons` array. - - Add the filename to the array, e.g., `'filename.svg'`. - -## Modifying the Colors of Existing Favicons - -If you need to update the colors of an existing favicon, edit the SVG file and update the hex codes in the following places: - -- `fill="#033CD2"` -- `stroke="#FF7800"` - -Ensure that the new colors remain consistent with the current favicon theme. diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md deleted file mode 100644 index 0b49c9c0..00000000 --- a/docs/CONTRIBUTING.md +++ /dev/null @@ -1,92 +0,0 @@ -# Contributing Guide - -## New Contributors - -Use the [discussions](https://github.com/sugarlabs/www-v2/discussions/) tab at the top of -the repository to: - -- Ask questions you're wondering about. -- Share ideas. -- Engage with other community members. - -Feel free. But, please don't spam :p. - -## Keep in Mind - -1. Your contributions need not necessarily have to address any discovered issue. If you encounter any, - feel free to add a fix through a PR, or create a new issue ticket. - -2. Use [labels](https://github.com/sugarlabs/www-v2/labels) on your issues and PRs. - -3. Do not spam with lots of PRs with little changes. - -4. If you are addressing a bulk change, divide your commits across multiple PRs, and send them one at - a time. The fewer the number of files addressed per PR, the better. - -5. Communicate effectively. Go straight to the point. Don't write unnecessary comments; don't be - over-apologetic. Every single contribution is welcome, as long as it doesn't spam or distract the flow. - -6. Write useful, brief commit messages. Add commit descriptions if necessary. PR name should speak - about what it is addressing and not the issue. In case a PR fixes an issue, use `fixes #ticketno` or - `closes #ticketno` in the PR's comment. Briefly explain what your PR is doing. - -7. Always test your changes extensively before creating a PR. There's no sense in merging broken code. - If a PR is a _work in progress (WIP)_, convert it to draft. It'll let the maintainers know it isn't - ready for merging. - -8. Read and revise the concepts about programming constructs you're dealing with. You must be clear - about the behavior of the language or compiler/transpiler. See - [JavaScript docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript) and [TypeScript docs](https://www.typescriptlang.org/docs/). - -9. If you have a question, do a _web search_ first. If you don't find any satisfactory answer, then - ask it in a comment. If it is a general question, please use the new - [discussions](https://github.com/sugarlabs/www-v2/discussions) tab on top the the repository, or - the _Sugar-dev Devel <[sugar-devel@lists.sugarlabs.org](mailto:sugar-devel@lists.sugarlabs.org)>_ mailing - list. Don't ask silly questions (unless you don't know it is silly ;p) before searching it on the web. - -## Code Quality Notes - -1. Sticking to _TypeScript_ conventions, use _camelCase_ for filenames (_PascalCase_ for _class_ files), - _CAPITALCASE_ for constants, _camelCase_ for identifiers, and _PascalCase_ for _classes_. Linting has - been strictly configured. A `super-linter` is configured to lint check the files on a pull request. - In fact, the _TypeScript_ watcher or build will throw errors/warnings if there are linting problems. - This has been done to maintain code quality. - -2. If a PR is addressing an issue, prefix the branch name with the issue number. For example, say a - PR is addressing issue `100`, a branch name could be `100-patch-foobar`. - -3. Meaningfully separate code across commits. Don't create arbitrary commits. In case it gets dirty, - please do an _interactive rebase_ with _squash_ and _reword_ to improve. - -4. Follow [conventional commit messages specification](https://www.conventionalcommits.org/en/v1.0.0-beta.2/) - to help issue tracking. More often than not, take time to add meaningful commit descriptions. However, - add specificity by mentioning the component; prefer `feat(mycomponent): [UI] add button` over - `feat: add button`, `fix(mycomponent): use try-catch` over `fix: use try-catch`, etc. - -5. At any point, when new components are created or existing components are modified, unit tests (passing) - reflecting the changes need to be part of the PR before being reviewed. - -6. Two workflows -- a _Continuous Integration_ (_CI_) and a _Linter_ (_Super Linter_), have been configured. - Each PR must pass the checks before being reviewed. - -7. For any new functions/methods or classes, add extensive [TSDoc](https://tsdoc.org/) documentation. - -8. Each PR needs to have supporting unit tests covering all (or as much practical) use cases to qualify - for review. In case testing is done via some non-standard method, adequate description of the method/s - need/s to be specified in the PR body. - -## Checklist before Commits - -- Make sure there are no _TypeScript_ warnings/errors. Run `npm run lint:ts` to verify. - -- Make sure there are no linting errors in the Markdown. Run `npm run lint:md` to verify. - -- Format code you've modified. Run `npm run format`. - -**Note for Windows users:** To format a specific file, run `npm run format:file <file-path>`. - -- Make sure the application builds successfully. Run `npm run build` to verify. - -- Add meaningful documentation to every new function/method/class/type added. - -- One commit must address only one concept. Do not add multiple unrelated changes in one commit. diff --git a/docs/GSoC-Blogpost-Guidelines.md b/docs/GSoC-Blogpost-Guidelines.md deleted file mode 100644 index fb27ac25..00000000 --- a/docs/GSoC-Blogpost-Guidelines.md +++ /dev/null @@ -1,166 +0,0 @@ -# GSoC '25 Blogpost Guidelines - -This document explains how to write and format your weekly GSoC '25 updates for the Sugar Labs website. Follow these instructions to ensure consistency and clarity across all posts. - -<!-- markdownlint-disable --> - -## Step 1: Create Your Author Profile (One-time setup) - -Before writing your first blog post, you need to create an author profile that will be linked to all your posts. - -1. **Create a new file** in `constants/MarkdownFiles/authors/` named `your-username.md` -2. **Use this template** and replace the placeholder information: - -```markdown ---- -name: "Your Full Name" -slug: "your-username" -title: "GSoC'25 Contributor" -organization: "SugarLabs" -description: "GSoC'25 Contributor at SugarLabs" -avatar: "https://avatars.githubusercontent.com/u/YOUR_GITHUB_ID?s=400" ---- - -<!--markdownlint-disable--> - -# About [Your Name] - -Write something about yourself - -## Experience - -Write some experience or other categories that you want to add - -## Current Projects - -Your Projects or other sections - -## Connect with Me - -- **GitHub**: [@your-username](https://github.com/your-username) -- **Email**: [your.email@example.com](mailto:your.email@example.com) -- **LinkedIn**: [Your Name](https://linkedin.com/in/your-profile) -- **Twitter**: [@your_handle](https://twitter.com/your_handle) -- **Website**: [yourwebsite.com](https://yourwebsite.com) *(optional)* -- **Discord**: [your#1234](https://discord.com/users/your#1234) *(optional)* -``` - -## Step 2: Official GSoC Blog Post Template - -Use the exact template below for every GSoC '25 week update. You can also find this under `constants/MarkdownFiles/posts/YYYY-MM-DD-GSoC_DMP_SSoC_Template.md`. Copy it into `constants/MarkdownFiles/posts/YYYY-MM-DD-gsoc-25-username-weekXX.md`, then fill in your details. - -```markdown ---- -title: "GSoC '25 Week XX Update by [Your Name]" -excerpt: "Brief description of this week's progress" -category: "DEVELOPER NEWS" -date: "2025-06-14" -slug: ""YYYY-MM-DD-gsoc-25-username-weekXX"" -author: "@/constants/MarkdownFiles/authors/your-username.md" -tags: "gsoc25,sugarlabs,weekXX,username" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week XX Progress Report by Safwan Sayeed - -**Project:** [Project Name](https://github.com/sugarlabs/project_repo) -**Mentors:** [Mentor1](https://github.com/Username), [Mentor2](https://github.com/Username) -**Assisting Mentors:** [Mentor3](https://github.com/Username), [Mentor4](https://github.com/Username) -**Reporting Period:** yyyy-mm-dd - yyyy-mm-dd - ---- - -## Goals for This Week - -- **Goal 1:** Describe the first planned deliverable. -- **Goal 2:** Describe the second planned deliverable. -- **Goal 3:** Describe an additional target. - ---- - -## This Week's Achievements - -1. **[Task or Feature]** - - What you did and why it matters. - - Links (if any): PR [#123](https://github.com/owner/repo/pull/123), Issue [#456](https://github.com/owner/repo/issues/456). - -2. **[Task or Feature]** - - Brief summary or a video. - [youtube: MM-H69cHYMk] - -3. **[Task or Feature]** - - Add screenshots or diagrams here if useful: -  - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Describe a blocker or difficulty. - **Solution:** Outline your approach or resources used. - -- **Challenge:** Another issue faced. - **Solution:** Steps taken to resolve or next action plan. - ---- - -## Key Learnings - -- Gained familiarity with **XYZ library or tool**. -- Deepened understanding of **SOLID principles**, **architecture modeling**, **DFDs**, etc. -- Improved skills in **testing**, **documentation**, and **collaboration workflows**. - ---- - -## Next Week's Roadmap - -- Implement **Feature XYZ** and write corresponding tests. -- Refine **technical design** based on mentor feedback. -- Prepare a mini-demo for the community check-in. - ---- - -## Resources & References - -- **PRD:** [Link to Product Requirements Document]({{prd_link}}) -- **Tech Spec & Diagrams:** [Architecture & Specs]({{tech_spec_link}}) -- **Repository:** [github.com/owner/repo](https://github.com/owner/repo) -- Any additional links, diagrams, or attachments. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- -``` - -## Updating Your Post - -1. Change the frontmatter `category` from `"TEMPLATE"` to `"DEVELOPER NEWS"`. -2. Replace placeholder text: - - **Week XX**, dates, PR/issue numbers, links, screenshot URLs. - - Your project name, mentor usernames, reporting period. -3. Update `title`, `excerpt`, `date`, `slug`, `author`, `tags`, `image`. -4. The `author` field should point to your author file: `"@/constants/MarkdownFiles/authors/your-username.md"` -5. Please keep (`<!-- markdownlint-disable -->`) to disable any markdown linting. -6. Change the contents of the file accordingly. -7. **Remove the "Connect with Me" section** from your blog post - this information is now in your author profile. - -## File & PR Workflow - -- Branch off `main` with `gsoc-weekXX-username`. -- Add your file under `constants/MarkdownFiles/posts/`. -- Commit and open a PR titled: - ``` - GSoC '25 Week XX Update by Name - ``` -- In PR description, link any issue tracking the weekly report and ping your mentors. -- After review, squash-and-merge. - ---- - -By strictly following this template and these steps, we ensure every GSoC '25 post is uniform and high quality. Happy writing! \ No newline at end of file diff --git a/docs/SECURITY.md b/docs/SECURITY.md deleted file mode 100644 index 835b5b93..00000000 --- a/docs/SECURITY.md +++ /dev/null @@ -1,46 +0,0 @@ -# Security Policy - -## Reporting a Vulnerability - -If you discover a security vulnerability within this project, please follow the steps below to responsibly disclose it: - -1. **Do not open an issue or pull request directly on GitHub**. This avoids making the vulnerability public and potentially exploitable by malicious actors. -2. **Send an email to our security team** at [security@sugarlabs.org](mailto:security@sugarlabs.org) with the following details: - - A description of the vulnerability and its impact. - - Detailed steps to reproduce the vulnerability, including any relevant code snippets, configuration details, or screenshots. - - Any potential mitigations or fixes you have identified. - -Our security team will acknowledge receipt of your report within 48 hours and will work with you to understand and address the issue. We aim to resolve critical vulnerabilities as quickly as possible and will provide updates on the status of the fix. - -## Supported Versions - -We only support the latest version of the project for security updates. Please ensure you are using the most recent release to benefit from the latest security enhancements. - -| Version | Supported | -| ------- | ------------------ | -| Latest | :white_check_mark: | - -## Security Best Practices - -To help ensure the security of your contributions and the overall project, please follow these best practices: - -1. **Stay Informed**: Keep up-to-date with the latest security advisories and updates related to the technologies used in this project, such as TypeScript, React, Node.js, and npm. -2. **Use Strong Authentication**: Enable two-factor authentication (2FA) on your GitHub account to protect your contributions and maintain the integrity of the project. -3. **Review Dependencies**: Regularly review and update project dependencies to ensure they are free from known vulnerabilities. Use tools like `npm audit` to identify and address security issues in dependencies. -4. **Follow Secure Coding Guidelines**: Adhere to secure coding practices, such as validating input, sanitizing output, and avoiding the use of unsafe functions. Refer to resources like the [OWASP Top Ten](https://owasp.org/www-project-top-ten/) for guidance. -5. **Report Suspicious Activity**: If you notice any suspicious activity or potential security issues within the project or its dependencies, report it immediately to the security team. - -## Handling Sensitive Information - -Avoid including sensitive information, such as passwords, API keys, or personal data, in your code contributions or public discussions. If sensitive information is accidentally exposed, notify the security team immediately to mitigate any potential impact. - -## Code Quality and Security - -To maintain a high level of security and code quality, please adhere to the following guidelines when contributing to the project: - -1. **Conduct Code Reviews**: All pull requests must be reviewed by at least one other contributor before being merged. Reviewers should pay close attention to potential security issues and ensure that the code follows best practices. -2. **Write Unit Tests**: Include unit tests for any new functionality or changes to existing code to ensure that the code behaves as expected and does not introduce security vulnerabilities. -3. **Use Linting Tools**: Run linting tools, such as ESLint, to identify and address potential security issues and code quality problems. -4. **Continuous Integration**: Ensure that all tests pass and that the code meets the project's quality standards before merging pull requests. Use continuous integration tools, such as GitHub Actions, to automate these checks. - -Thank you for helping us maintain the security and integrity of our project! diff --git a/docs/dev_guide.md b/docs/dev_guide.md deleted file mode 100644 index 95f53c64..00000000 --- a/docs/dev_guide.md +++ /dev/null @@ -1,117 +0,0 @@ -# Developer's Guide - -## Getting the code - -1. Fork this repository, - -2. Clone your forked copy of the project; - - ```bash - git clone https://github.com/<your_user_name>/www-v2.git - ``` - -3. Change to the project directory; - - ```bash - cd www-v2 - ``` - -## Setup Development Environment - -This is a _**TypeScript**_ project that uses _**React**_. You'll just need _[**Node.js**](https://nodejs.org/en) and _**npm**_ installed on your development machine. -Although, this is sufficient to run, build, and test the project as a whole, you might need some -extra tools for other development tasks. - -You'll need _**tsc**_ (_TypeScript Compiler_) to manually compile `.ts` files. You'll need -_**ts-node**_ (_Node.js executable for TypeScript_) to manually execute `.ts` scripts directly. Finally, - -Once _**npm**_ is installed, to install the above, run - -```bash -npm i -g typescript -npm i -g ts-node -``` - -_**Note:**_ Users on _Linux_ and _MacOS_ are required to add a `sudo` before these commands. - -Check installation using - -```bash -node -v && npm -v && tsc -v && ts-node -v -``` - -Output should look like - -```bash -v23.7.0 -11.1.0 -Version 5.7.3 -v10.9.2 -``` - -## Commands - -After you are set-up, the steps you take depend on what you want to do: - -- **Run a development server** - - 1. To install all the dependencies (in `package.json`), run - - ```bash - npm install - ``` - - 2. Run _React scripts_. - - - For unoptimized development serving, run - - ```bash - npm run dev - ``` - - Visit `localhost:5173` in a browser to view the web page served. - - - For generating a generic production build, run - - ```bash - npm run build - ``` - - - For generating a production build under the subdirectory `/www-v2`, run - - ```bash - npm run build - ``` - - - For serving the last production build (`dist` folder), run - - ```bash - npm run preview - ``` - - Visit `localhost:4173` in a browser to view the web page served. - -## Editor - -_All code is just plain text, so it doesn't really matter what you use to edit them._ However, -using modern, feature-rich IDEs/text-editors like: -[_**Atom**_](https://github.blog/2022-06-08-sunsetting-atom/), -[_**Brackets**_](https://brackets.io), -[_**WebStorm**_](https://www.jetbrains.com/webstorm/), -[_**Sublime Text**_](https://www.sublimetext.com/), -[_**Visual Studio Code**_](https://code.visualstudio.com/), etc. makes life way easier. These come -with a directory-tree explorer, and an integrated terminal, at the very least, while having support -for plugins/extensions to expand their functionality. - -Some (non-exhaustive) benefits of using these are _syntax highlighting_, -_warning/error annotations_, _formatting_, _auto-refactoring_, tons of customizable -_keyboard shortcuts_, etc. - -_**Visual Studio Code**_ (_**VSCode**_) is currently the most-popular code editor for reasons like -being _lightweight_, _cleaner_, large marketplace of _extensions_, integrated _source control_ -features, _debugger_, _remote explorer_ support, _regular expression_ based find/replace, etc. - -Recommended extensions for this project are `Babel JavaScript`, `ESLint`, `Git Graph`,`GitLens`, `markdownlint`, `Prettier`, `Tailwind CSS IntelliSense`, and `SVG`. - -All that, however, shouldn't necessarily stop you from using _**Emacs**_, _**Nano**_, or _**Vim**_, -if that's your poison :D. Happy coding! diff --git a/eslint.config.js b/eslint.config.js deleted file mode 100644 index 092408a9..00000000 --- a/eslint.config.js +++ /dev/null @@ -1,28 +0,0 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import tseslint from 'typescript-eslint' - -export default tseslint.config( - { ignores: ['dist'] }, - { - extends: [js.configs.recommended, ...tseslint.configs.recommended], - files: ['**/*.{ts,tsx}'], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - }, - plugins: { - 'react-hooks': reactHooks, - 'react-refresh': reactRefresh, - }, - rules: { - ...reactHooks.configs.recommended.rules, - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], - }, - }, -) diff --git a/public/favicons/favicon1.svg b/favicons/favicon1.svg similarity index 100% rename from public/favicons/favicon1.svg rename to favicons/favicon1.svg diff --git a/public/favicons/favicon10.svg b/favicons/favicon10.svg similarity index 100% rename from public/favicons/favicon10.svg rename to favicons/favicon10.svg diff --git a/public/favicons/favicon11.svg b/favicons/favicon11.svg similarity index 100% rename from public/favicons/favicon11.svg rename to favicons/favicon11.svg diff --git a/public/favicons/favicon12.svg b/favicons/favicon12.svg similarity index 100% rename from public/favicons/favicon12.svg rename to favicons/favicon12.svg diff --git a/public/favicons/favicon2.svg b/favicons/favicon2.svg similarity index 100% rename from public/favicons/favicon2.svg rename to favicons/favicon2.svg diff --git a/public/favicons/favicon3.svg b/favicons/favicon3.svg similarity index 100% rename from public/favicons/favicon3.svg rename to favicons/favicon3.svg diff --git a/public/favicons/favicon4.svg b/favicons/favicon4.svg similarity index 100% rename from public/favicons/favicon4.svg rename to favicons/favicon4.svg diff --git a/public/favicons/favicon5.svg b/favicons/favicon5.svg similarity index 100% rename from public/favicons/favicon5.svg rename to favicons/favicon5.svg diff --git a/public/favicons/favicon6.svg b/favicons/favicon6.svg similarity index 100% rename from public/favicons/favicon6.svg rename to favicons/favicon6.svg diff --git a/public/favicons/favicon7.svg b/favicons/favicon7.svg similarity index 100% rename from public/favicons/favicon7.svg rename to favicons/favicon7.svg diff --git a/public/favicons/favicon8.svg b/favicons/favicon8.svg similarity index 100% rename from public/favicons/favicon8.svg rename to favicons/favicon8.svg diff --git a/public/favicons/favicon9.svg b/favicons/favicon9.svg similarity index 100% rename from public/favicons/favicon9.svg rename to favicons/favicon9.svg diff --git a/public/fonts/AnonymousPro-Regular.ttf b/fonts/AnonymousPro-Regular.ttf similarity index 100% rename from public/fonts/AnonymousPro-Regular.ttf rename to fonts/AnonymousPro-Regular.ttf diff --git a/public/fonts/Caveat-Regular.ttf b/fonts/Caveat-Regular.ttf similarity index 100% rename from public/fonts/Caveat-Regular.ttf rename to fonts/Caveat-Regular.ttf diff --git a/public/fonts/Inter_28pt-Regular.ttf b/fonts/Inter_28pt-Regular.ttf similarity index 100% rename from public/fonts/Inter_28pt-Regular.ttf rename to fonts/Inter_28pt-Regular.ttf diff --git a/public/fonts/Oswald-Regular.ttf b/fonts/Oswald-Regular.ttf similarity index 100% rename from public/fonts/Oswald-Regular.ttf rename to fonts/Oswald-Regular.ttf diff --git a/public/fonts/Pacifico-Regular.ttf b/fonts/Pacifico-Regular.ttf similarity index 100% rename from public/fonts/Pacifico-Regular.ttf rename to fonts/Pacifico-Regular.ttf diff --git a/public/fonts/Roboto-Regular.ttf b/fonts/Roboto-Regular.ttf similarity index 100% rename from public/fonts/Roboto-Regular.ttf rename to fonts/Roboto-Regular.ttf diff --git a/public/funding.json b/funding.json similarity index 100% rename from public/funding.json rename to funding.json diff --git a/index.html b/index.html index 6d2862a7..9642248b 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,6 @@ <head> <meta charset="UTF-8" /> <link id="dynamic" rel="icon" type="image/svg+xml" href="favicons/favicon1.svg" /> - <link href="./src/styles/globals.css" rel="stylesheet"> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <base href="/" /> <title>SugarLabs</title> @@ -16,10 +15,13 @@ } })(); </script> + <script type="module" crossorigin src="./assets/index-M22Aoh9H.js"></script> + <link rel="modulepreload" crossorigin href="./assets/vendor-19NJoZqN.js"> + <link rel="stylesheet" crossorigin href="./assets/vendor-h0EPuWW_.css"> + <link rel="stylesheet" crossorigin href="./assets/index-vc2PfLu3.css"> </head> <body> <div id="root"></div> - <script type="module" src="/src/main.tsx"></script> - <script type="module" src="/Randomfavicon.js" crossorigin="anonymous"></script> + <script type="module" src="./Randomfavicon.js" crossorigin="anonymous"></script> </body> </html> diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index e95633a0..00000000 --- a/package-lock.json +++ /dev/null @@ -1,9219 +0,0 @@ -{ - "name": "www-v2", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "www-v2", - "version": "0.0.0", - "dependencies": { - "@tailwindcss/vite": "^4.1.11", - "axios": "^1.10.0", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "dompurify": "^3.2.6", - "framer-motion": "^12.23.3", - "hastscript": "^9.0.1", - "lucide-react": "^0.525.0", - "react": "^19.1.0", - "react-dom": "^19.1.0", - "react-markdown": "^10.1.0", - "react-responsive-carousel": "^3.2.23", - "react-router-dom": "^7.6.3", - "rehype-autolink-headings": "^7.1.0", - "rehype-raw": "^7.0.0", - "rehype-sanitize": "^6.0.0", - "rehype-slug": "^6.0.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.1", - "remark-supersub": "^1.0.0", - "tailwind-merge": "^3.3.1", - "tailwindcss": "^4.1.11", - "tailwindcss-animate": "^1.0.7", - "unist-util-visit": "^5.0.0" - }, - "devDependencies": { - "@eslint/js": "^9.30.1", - "@types/node": "^24.0.13", - "@types/react": "^19.1.8", - "@types/react-dom": "^19.1.6", - "@vitejs/plugin-react": "^4.6.0", - "eslint": "^9.31.0", - "eslint-config-prettier": "^10.1.5", - "eslint-plugin-prettier": "^5.5.1", - "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.4.20", - "gh-pages": "^6.3.0", - "globals": "^16.3.0", - "markdownlint": "^0.38.0", - "markdownlint-cli": "^0.45.0", - "prettier": "^3.6.2", - "typescript": "~5.8.3", - "typescript-eslint": "^8.36.0", - "vite": "^7.0.4" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", - "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.6", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.0", - "@babel/types": "^7.28.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", - "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/types": "^7.28.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", - "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", - "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.0", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.1.tgz", - "integrity": "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.6.tgz", - "integrity": "sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.6.tgz", - "integrity": "sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.6.tgz", - "integrity": "sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.6.tgz", - "integrity": "sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.6.tgz", - "integrity": "sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.6.tgz", - "integrity": "sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.6.tgz", - "integrity": "sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.6.tgz", - "integrity": "sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.6.tgz", - "integrity": "sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.6.tgz", - "integrity": "sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.6.tgz", - "integrity": "sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.6.tgz", - "integrity": "sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.6.tgz", - "integrity": "sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.6.tgz", - "integrity": "sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.6.tgz", - "integrity": "sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.6.tgz", - "integrity": "sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.6.tgz", - "integrity": "sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.6.tgz", - "integrity": "sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.6.tgz", - "integrity": "sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.6.tgz", - "integrity": "sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.6.tgz", - "integrity": "sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.6.tgz", - "integrity": "sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.6.tgz", - "integrity": "sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.6.tgz", - "integrity": "sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.6.tgz", - "integrity": "sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.6.tgz", - "integrity": "sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", - "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", - "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", - "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/js": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz", - "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.3.tgz", - "integrity": "sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.15.1", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgr/core": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.7.tgz", - "integrity": "sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.19", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz", - "integrity": "sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.0.tgz", - "integrity": "sha512-2o/FgACbji4tW1dzXOqAV15Eu7DdgbKsF2QKcxfG4xbh5iwU7yr5RRP5/U+0asQliSYv5M4o7BevlGIoSL0LXg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.0.tgz", - "integrity": "sha512-PSZ0SvMOjEAxwZeTx32eI/j5xSYtDCRxGu5k9zvzoY77xUNssZM+WV6HYBLROpY5CkXsbQjvz40fBb7WPwDqtQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.0.tgz", - "integrity": "sha512-BA4yPIPssPB2aRAWzmqzQ3y2/KotkLyZukVB7j3psK/U3nVJdceo6qr9pLM2xN6iRP/wKfxEbOb1yrlZH6sYZg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.0.tgz", - "integrity": "sha512-Pr2o0lvTwsiG4HCr43Zy9xXrHspyMvsvEw4FwKYqhli4FuLE5FjcZzuQ4cfPe0iUFCvSQG6lACI0xj74FDZKRA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.0.tgz", - "integrity": "sha512-lYE8LkE5h4a/+6VnnLiL14zWMPnx6wNbDG23GcYFpRW1V9hYWHAw9lBZ6ZUIrOaoK7NliF1sdwYGiVmziUF4vA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.0.tgz", - "integrity": "sha512-PVQWZK9sbzpvqC9Q0GlehNNSVHR+4m7+wET+7FgSnKG3ci5nAMgGmr9mGBXzAuE5SvguCKJ6mHL6vq1JaJ/gvw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.0.tgz", - "integrity": "sha512-hLrmRl53prCcD+YXTfNvXd776HTxNh8wPAMllusQ+amcQmtgo3V5i/nkhPN6FakW+QVLoUUr2AsbtIRPFU3xIA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.0.tgz", - "integrity": "sha512-XBKGSYcrkdiRRjl+8XvrUR3AosXU0NvF7VuqMsm7s5nRy+nt58ZMB19Jdp1RdqewLcaYnpk8zeVs/4MlLZEJxw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.0.tgz", - "integrity": "sha512-fRvZZPUiBz7NztBE/2QnCS5AtqLVhXmUOPj9IHlfGEXkapgImf4W9+FSkL8cWqoAjozyUzqFmSc4zh2ooaeF6g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.0.tgz", - "integrity": "sha512-Btv2WRZOcUGi8XU80XwIvzTg4U6+l6D0V6sZTrZx214nrwxw5nAi8hysaXj/mctyClWgesyuxbeLylCBNauimg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.0.tgz", - "integrity": "sha512-Li0emNnwtUZdLwHjQPBxn4VWztcrw/h7mgLyHiEI5Z0MhpeFGlzaiBHpSNVOMB/xucjXTTcO+dhv469Djr16KA==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.0.tgz", - "integrity": "sha512-sB8+pfkYx2kvpDCfd63d5ScYT0Fz1LO6jIb2zLZvmK9ob2D8DeVqrmBDE0iDK8KlBVmsTNzrjr3G1xV4eUZhSw==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.0.tgz", - "integrity": "sha512-5GQ6PFhh7E6jQm70p1aW05G2cap5zMOvO0se5JMecHeAdj5ZhWEHbJ4hiKpfi1nnnEdTauDXxPgXae/mqjow9w==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.0.tgz", - "integrity": "sha512-N/euLsBd1rekWcuduakTo/dJw6U6sBP3eUq+RXM9RNfPuWTvG2w/WObDkIvJ2KChy6oxZmOSC08Ak2OJA0UiAA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.0.tgz", - "integrity": "sha512-2l9sA7d7QdikL0xQwNMO3xURBUNEWyHVHfAsHsUdq+E/pgLTUcCE+gih5PCdmyHmfTDeXUWVhqL0WZzg0nua3g==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.0.tgz", - "integrity": "sha512-XZdD3fEEQcwG2KrJDdEQu7NrHonPxxaV0/w2HpvINBdcqebz1aL+0vM2WFJq4DeiAVT6F5SUQas65HY5JDqoPw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.0.tgz", - "integrity": "sha512-7ayfgvtmmWgKWBkCGg5+xTQ0r5V1owVm67zTrsEY1008L5ro7mCyGYORomARt/OquB9KY7LpxVBZes+oSniAAQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.0.tgz", - "integrity": "sha512-B+IJgcBnE2bm93jEW5kHisqvPITs4ddLOROAcOc/diBgrEiQJJ6Qcjby75rFSmH5eMGrqJryUgJDhrfj942apQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.0.tgz", - "integrity": "sha512-+CXwwG66g0/FpWOnP/v1HnrGVSOygK/osUbu3wPRy8ECXjoYKjRAyfxYpDQOfghC5qPJYLPH0oN4MCOjwgdMug==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.0.tgz", - "integrity": "sha512-SRf1cytG7wqcHVLrBc9VtPK4pU5wxiB/lNIkNmW2ApKXIg+RpqwHfsaEK+e7eH4A1BpI6BX/aBWXxZCIrJg3uA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@tailwindcss/node": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", - "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "enhanced-resolve": "^5.18.1", - "jiti": "^2.4.2", - "lightningcss": "1.30.1", - "magic-string": "^0.30.17", - "source-map-js": "^1.2.1", - "tailwindcss": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz", - "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.4", - "tar": "^7.4.3" - }, - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-x64": "4.1.11", - "@tailwindcss/oxide-freebsd-x64": "4.1.11", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-x64-musl": "4.1.11", - "@tailwindcss/oxide-wasm32-wasi": "4.1.11", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz", - "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz", - "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz", - "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz", - "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz", - "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz", - "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz", - "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz", - "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz", - "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz", - "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@emnapi/wasi-threads": "^1.0.2", - "@napi-rs/wasm-runtime": "^0.2.11", - "@tybys/wasm-util": "^0.9.0", - "tslib": "^2.8.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz", - "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz", - "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/vite": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.11.tgz", - "integrity": "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw==", - "license": "MIT", - "dependencies": { - "@tailwindcss/node": "4.1.11", - "@tailwindcss/oxide": "4.1.11", - "tailwindcss": "4.1.11" - }, - "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", - "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", - "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/katex": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", - "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "24.0.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.13.tgz", - "integrity": "sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.8.0" - } - }, - "node_modules/@types/react": { - "version": "19.1.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", - "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", - "license": "MIT", - "dependencies": { - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz", - "integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.0.0" - } - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "license": "MIT", - "optional": true - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.36.0.tgz", - "integrity": "sha512-lZNihHUVB6ZZiPBNgOQGSxUASI7UJWhT8nHyUGCnaQ28XFCw98IfrMCG3rUl1uwUWoAvodJQby2KTs79UTcrAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.36.0", - "@typescript-eslint/type-utils": "8.36.0", - "@typescript-eslint/utils": "8.36.0", - "@typescript-eslint/visitor-keys": "8.36.0", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.36.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.36.0.tgz", - "integrity": "sha512-FuYgkHwZLuPbZjQHzJXrtXreJdFMKl16BFYyRrLxDhWr6Qr7Kbcu2s1Yhu8tsiMXw1S0W1pjfFfYEt+R604s+Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.36.0", - "@typescript-eslint/types": "8.36.0", - "@typescript-eslint/typescript-estree": "8.36.0", - "@typescript-eslint/visitor-keys": "8.36.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.36.0.tgz", - "integrity": "sha512-JAhQFIABkWccQYeLMrHadu/fhpzmSQ1F1KXkpzqiVxA/iYI6UnRt2trqXHt1sYEcw1mxLnB9rKMsOxXPxowN/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.36.0", - "@typescript-eslint/types": "^8.36.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.36.0.tgz", - "integrity": "sha512-wCnapIKnDkN62fYtTGv2+RY8FlnBYA3tNm0fm91kc2BjPhV2vIjwwozJ7LToaLAyb1ca8BxrS7vT+Pvvf7RvqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.36.0", - "@typescript-eslint/visitor-keys": "8.36.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.36.0.tgz", - "integrity": "sha512-Nhh3TIEgN18mNbdXpd5Q8mSCBnrZQeY9V7Ca3dqYvNDStNIGRmJA6dmrIPMJ0kow3C7gcQbpsG2rPzy1Ks/AnA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.36.0.tgz", - "integrity": "sha512-5aaGYG8cVDd6cxfk/ynpYzxBRZJk7w/ymto6uiyUFtdCozQIsQWh7M28/6r57Fwkbweng8qAzoMCPwSJfWlmsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "8.36.0", - "@typescript-eslint/utils": "8.36.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.36.0.tgz", - "integrity": "sha512-xGms6l5cTJKQPZOKM75Dl9yBfNdGeLRsIyufewnxT4vZTrjC0ImQT4fj8QmtJK84F58uSh5HVBSANwcfiXxABQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.36.0.tgz", - "integrity": "sha512-JaS8bDVrfVJX4av0jLpe4ye0BpAaUW7+tnS4Y4ETa3q7NoZgzYbN9zDQTJ8kPb5fQ4n0hliAt9tA4Pfs2zA2Hg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.36.0", - "@typescript-eslint/tsconfig-utils": "8.36.0", - "@typescript-eslint/types": "8.36.0", - "@typescript-eslint/visitor-keys": "8.36.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.36.0.tgz", - "integrity": "sha512-VOqmHu42aEMT+P2qYjylw6zP/3E/HvptRwdn/PZxyV27KhZg2IOszXod4NcXisWzPAGSS4trE/g4moNj6XmH2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.36.0", - "@typescript-eslint/types": "8.36.0", - "@typescript-eslint/typescript-estree": "8.36.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.36.0.tgz", - "integrity": "sha512-vZrhV2lRPWDuGoxcmrzRZyxAggPL+qp3WzUrlZD+slFueDiYHxeBa34dUXPuC0RmGKzl4lS5kFJYvKCq9cnNDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.36.0", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "license": "ISC" - }, - "node_modules/@vitejs/plugin-react": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.6.0.tgz", - "integrity": "sha512-5Kgff+m8e2PB+9j51eGHEpn5kUzRKH2Ry0qGoe8ItJg7pqnkPrYPkDQZGgGmTa0EGarHrkjLvOdU3b1fzI8otQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.19", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.17.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" - } - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", - "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.24.0", - "es-object-atoms": "^1.1.1", - "get-intrinsic": "^1.3.0", - "is-string": "^1.1.1", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", - "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", - "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, - "node_modules/async-function": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axios": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", - "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.25.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", - "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001726", - "electron-to-chromium": "^1.5.173", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/class-variance-authority": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", - "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", - "license": "Apache-2.0", - "dependencies": { - "clsx": "^2.1.1" - }, - "funding": { - "url": "https://polar.sh/cva" - } - }, - "node_modules/classnames": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", - "license": "MIT" - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/data-view-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/inspect-js" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", - "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/dompurify": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", - "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", - "license": "(MPL-2.0 OR Apache-2.0)", - "optionalDependencies": { - "@types/trusted-types": "^2.0.7" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.182", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.182.tgz", - "integrity": "sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==", - "dev": true, - "license": "ISC" - }, - "node_modules/email-addresses": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", - "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", - "dev": true, - "license": "MIT" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/enhanced-resolve": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", - "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/es-abstract": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.2", - "arraybuffer.prototype.slice": "^1.0.4", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "data-view-buffer": "^1.0.2", - "data-view-byte-length": "^1.0.2", - "data-view-byte-offset": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-set-tostringtag": "^2.1.0", - "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.3.0", - "get-proto": "^1.0.1", - "get-symbol-description": "^1.1.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.5", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.2", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.2.1", - "is-set": "^2.0.3", - "is-shared-array-buffer": "^1.0.4", - "is-string": "^1.1.1", - "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.1", - "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.4", - "object-keys": "^1.1.1", - "object.assign": "^4.1.7", - "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.4", - "safe-array-concat": "^1.1.3", - "safe-push-apply": "^1.0.0", - "safe-regex-test": "^1.1.0", - "set-proto": "^1.0.0", - "stop-iteration-iterator": "^1.1.0", - "string.prototype.trim": "^1.2.10", - "string.prototype.trimend": "^1.0.9", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.3", - "typed-array-byte-length": "^1.0.3", - "typed-array-byte-offset": "^1.0.4", - "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.19" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-iterator-helpers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", - "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.6", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "iterator.prototype": "^1.1.4", - "safe-array-concat": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", - "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/esbuild": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz", - "integrity": "sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.6", - "@esbuild/android-arm": "0.25.6", - "@esbuild/android-arm64": "0.25.6", - "@esbuild/android-x64": "0.25.6", - "@esbuild/darwin-arm64": "0.25.6", - "@esbuild/darwin-x64": "0.25.6", - "@esbuild/freebsd-arm64": "0.25.6", - "@esbuild/freebsd-x64": "0.25.6", - "@esbuild/linux-arm": "0.25.6", - "@esbuild/linux-arm64": "0.25.6", - "@esbuild/linux-ia32": "0.25.6", - "@esbuild/linux-loong64": "0.25.6", - "@esbuild/linux-mips64el": "0.25.6", - "@esbuild/linux-ppc64": "0.25.6", - "@esbuild/linux-riscv64": "0.25.6", - "@esbuild/linux-s390x": "0.25.6", - "@esbuild/linux-x64": "0.25.6", - "@esbuild/netbsd-arm64": "0.25.6", - "@esbuild/netbsd-x64": "0.25.6", - "@esbuild/openbsd-arm64": "0.25.6", - "@esbuild/openbsd-x64": "0.25.6", - "@esbuild/openharmony-arm64": "0.25.6", - "@esbuild/sunos-x64": "0.25.6", - "@esbuild/win32-arm64": "0.25.6", - "@esbuild/win32-ia32": "0.25.6", - "@esbuild/win32-x64": "0.25.6" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.31.0.tgz", - "integrity": "sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.0", - "@eslint/core": "^0.15.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.31.0", - "@eslint/plugin-kit": "^0.3.1", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-config-prettier": { - "version": "10.1.5", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.5.tgz", - "integrity": "sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "funding": { - "url": "https://opencollective.com/eslint-config-prettier" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.1.tgz", - "integrity": "sha512-dobTkHT6XaEVOo8IO90Q4DOSxnm3Y151QxPJlM/vKC0bVy+d6cVWQZLlFiuZPP0wS6vZwSKeJgKkcS+KfMBlRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.11.7" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.37.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", - "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.8", - "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.3", - "array.prototype.tosorted": "^1.1.4", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.2.1", - "estraverse": "^5.3.0", - "hasown": "^2.0.2", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.9", - "object.fromentries": "^2.0.8", - "object.values": "^1.2.1", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.12", - "string.prototype.repeat": "^1.0.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", - "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.20", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz", - "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "eslint": ">=8.40" - } - }, - "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "license": "MIT", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "license": "MIT", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/framer-motion": { - "version": "12.23.3", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.3.tgz", - "integrity": "sha512-llmLkf44zuIZOPSrE4bl4J0UTg6bav+rlKEfMRKgvDMXqBrUtMg6cspoQeRVK3nqRLxTmAJhfGXk39UDdZD7Kw==", - "license": "MIT", - "dependencies": { - "motion-dom": "^12.23.2", - "motion-utils": "^12.23.2", - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gh-pages": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.3.0.tgz", - "integrity": "sha512-Ot5lU6jK0Eb+sszG8pciXdjMXdBJ5wODvgjR+imihTqsUWF2K6dJ9HST55lgqcs8wWcw6o6wAsUzfcYRhJPXbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "async": "^3.2.4", - "commander": "^13.0.0", - "email-addresses": "^5.0.0", - "filenamify": "^4.3.0", - "find-cache-dir": "^3.3.1", - "fs-extra": "^11.1.1", - "globby": "^11.1.0" - }, - "bin": { - "gh-pages": "bin/gh-pages.js", - "gh-pages-clean": "bin/gh-pages-clean.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", - "license": "ISC" - }, - "node_modules/glob": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.3.1", - "jackspeak": "^4.1.1", - "minimatch": "^10.0.3", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/globals": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz", - "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/has-bigints": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", - "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^9.0.0", - "property-information": "^7.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-heading-rank": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", - "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", - "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-sanitize": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz", - "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "unist-util-position": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", - "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-js": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5/node_modules/property-information": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", - "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast-util-to-string": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", - "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", - "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/html-url-attributes": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", - "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/ini": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", - "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/inline-style-parser": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", - "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", - "license": "MIT" - }, - "node_modules/internal-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "license": "MIT", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-async-function": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", - "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "async-function": "^1.0.0", - "call-bound": "^1.0.3", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", - "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-finalizationregistry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-symbols": "^1.1.0", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", - "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/iterator.prototype": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", - "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "get-proto": "^1.0.0", - "has-symbols": "^1.1.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/jackspeak": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/katex": { - "version": "0.16.22", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz", - "integrity": "sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==", - "dev": true, - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], - "license": "MIT", - "dependencies": { - "commander": "^8.3.0" - }, - "bin": { - "katex": "cli.js" - } - }, - "node_modules/katex/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lightningcss": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", - "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.30.1", - "lightningcss-darwin-x64": "1.30.1", - "lightningcss-freebsd-x64": "1.30.1", - "lightningcss-linux-arm-gnueabihf": "1.30.1", - "lightningcss-linux-arm64-gnu": "1.30.1", - "lightningcss-linux-arm64-musl": "1.30.1", - "lightningcss-linux-x64-gnu": "1.30.1", - "lightningcss-linux-x64-musl": "1.30.1", - "lightningcss-win32-arm64-msvc": "1.30.1", - "lightningcss-win32-x64-msvc": "1.30.1" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", - "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", - "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", - "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", - "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", - "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", - "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", - "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", - "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", - "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", - "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "uc.micro": "^2.0.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/lucide-react": { - "version": "0.525.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.525.0.tgz", - "integrity": "sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ==", - "license": "ISC", - "peerDependencies": { - "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.0", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.1.0" - }, - "bin": { - "markdown-it": "bin/markdown-it.mjs" - } - }, - "node_modules/markdown-table": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", - "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/markdownlint": { - "version": "0.38.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.38.0.tgz", - "integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark": "4.0.2", - "micromark-core-commonmark": "2.0.3", - "micromark-extension-directive": "4.0.0", - "micromark-extension-gfm-autolink-literal": "2.1.0", - "micromark-extension-gfm-footnote": "2.1.0", - "micromark-extension-gfm-table": "2.1.1", - "micromark-extension-math": "3.1.0", - "micromark-util-types": "2.0.2" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/DavidAnson" - } - }, - "node_modules/markdownlint-cli": { - "version": "0.45.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.45.0.tgz", - "integrity": "sha512-GiWr7GfJLVfcopL3t3pLumXCYs8sgWppjIA1F/Cc3zIMgD3tmkpyZ1xkm1Tej8mw53B93JsDjgA3KOftuYcfOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "~13.1.0", - "glob": "~11.0.2", - "ignore": "~7.0.4", - "js-yaml": "~4.1.0", - "jsonc-parser": "~3.3.1", - "jsonpointer": "~5.0.1", - "markdown-it": "~14.1.0", - "markdownlint": "~0.38.0", - "minimatch": "~10.0.1", - "run-con": "~1.3.2", - "smol-toml": "~1.3.4" - }, - "bin": { - "markdownlint": "markdownlint.js" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/markdownlint-cli/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/markdownlint-cli/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-frontmatter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "escape-string-regexp": "^5.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", - "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", - "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", - "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz", - "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-frontmatter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", - "license": "MIT", - "dependencies": { - "fault": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-math": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", - "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/katex": "^0.16.0", - "devlop": "^1.0.0", - "katex": "^0.16.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", - "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/motion-dom": { - "version": "12.23.2", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.2.tgz", - "integrity": "sha512-73j6xDHX/NvVh5L5oS1ouAVnshsvmApOq4F3VZo5MkYSD/YVsVLal4Qp9wvVgJM9uU2bLZyc0Sn8B9c/MMKk4g==", - "license": "MIT", - "dependencies": { - "motion-utils": "^12.23.2" - } - }, - "node_modules/motion-utils": { - "version": "12.23.2", - "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.2.tgz", - "integrity": "sha512-cIEXlBlXAOUyiAtR0S+QPQUM9L3Diz23Bo+zM420NvSd/oPQJwg6U+rT+WRTpp0rizMsBGQOsAwhWIfglUcZfA==", - "license": "MIT" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true, - "license": "MIT" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", - "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", - "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/own-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.6", - "object-keys": "^1.1.1", - "safe-push-apply": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-entities": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", - "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", - "license": "MIT" - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", - "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", - "dev": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", - "license": "MIT", - "dependencies": { - "scheduler": "^0.26.0" - }, - "peerDependencies": { - "react": "^19.1.0" - } - }, - "node_modules/react-easy-swipe": { - "version": "0.0.21", - "resolved": "https://registry.npmjs.org/react-easy-swipe/-/react-easy-swipe-0.0.21.tgz", - "integrity": "sha512-OeR2jAxdoqUMHIn/nS9fgreI5hSpgGoL5ezdal4+oO7YSSgJR8ga+PkYGJrSrJ9MKlPcQjMQXnketrD7WNmNsg==", - "license": "MIT", - "dependencies": { - "prop-types": "^15.5.8" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, - "node_modules/react-markdown": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", - "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "html-url-attributes": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "unified": "^11.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=18", - "react": ">=18" - } - }, - "node_modules/react-refresh": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", - "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-responsive-carousel": { - "version": "3.2.23", - "resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.23.tgz", - "integrity": "sha512-pqJLsBaKHWJhw/ItODgbVoziR2z4lpcJg+YwmRlSk4rKH32VE633mAtZZ9kDXjy4wFO+pgUZmDKPsPe1fPmHCg==", - "license": "MIT", - "dependencies": { - "classnames": "^2.2.5", - "prop-types": "^15.5.8", - "react-easy-swipe": "^0.0.21" - } - }, - "node_modules/react-router": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.3.tgz", - "integrity": "sha512-zf45LZp5skDC6I3jDLXQUu0u26jtuP4lEGbc7BbdyxenBN1vJSTA18czM2D+h5qyMBuMrD+9uB+mU37HIoKGRA==", - "license": "MIT", - "dependencies": { - "cookie": "^1.0.1", - "set-cookie-parser": "^2.6.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - } - } - }, - "node_modules/react-router-dom": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.3.tgz", - "integrity": "sha512-DiWJm9qdUAmiJrVWaeJdu4TKu13+iB/8IEi0EW/XgaHCjW/vWGrwzup0GVvaMteuZjKnh5bEvJP/K0MDnzawHw==", - "license": "MIT", - "dependencies": { - "react-router": "7.6.3" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.1", - "which-builtin-type": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/rehype-autolink-headings": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/rehype-autolink-headings/-/rehype-autolink-headings-7.1.0.tgz", - "integrity": "sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-heading-rank": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "unified": "^11.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-sanitize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rehype-sanitize/-/rehype-sanitize-6.0.0.tgz", - "integrity": "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-sanitize": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-slug": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", - "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "github-slugger": "^2.0.0", - "hast-util-heading-rank": "^3.0.0", - "hast-util-to-string": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-frontmatter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-frontmatter": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", - "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", - "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-supersub": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/remark-supersub/-/remark-supersub-1.0.0.tgz", - "integrity": "sha512-3SYsphMqpAWbr8AZozdcypozinl/lly3e7BEwPG3YT5J9uZQaDcELBF6/sr/OZoAlFxy2nhNFWSrZBu/ZPRT3Q==", - "license": "MIT", - "dependencies": { - "unist-util-visit": "^4.0.0" - } - }, - "node_modules/remark-supersub/node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", - "license": "MIT" - }, - "node_modules/remark-supersub/node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-supersub/node_modules/unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-supersub/node_modules/unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rollup": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.0.tgz", - "integrity": "sha512-WLjEcJRIo7i3WDDgOIJqVI2d+lAC3EwvOGy+Xfq6hs+GQuAA4Di/H72xmXkOhrIWFg2PFYSKZYfH0f4vfKXN4A==", - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.45.0", - "@rollup/rollup-android-arm64": "4.45.0", - "@rollup/rollup-darwin-arm64": "4.45.0", - "@rollup/rollup-darwin-x64": "4.45.0", - "@rollup/rollup-freebsd-arm64": "4.45.0", - "@rollup/rollup-freebsd-x64": "4.45.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.45.0", - "@rollup/rollup-linux-arm-musleabihf": "4.45.0", - "@rollup/rollup-linux-arm64-gnu": "4.45.0", - "@rollup/rollup-linux-arm64-musl": "4.45.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.45.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.45.0", - "@rollup/rollup-linux-riscv64-gnu": "4.45.0", - "@rollup/rollup-linux-riscv64-musl": "4.45.0", - "@rollup/rollup-linux-s390x-gnu": "4.45.0", - "@rollup/rollup-linux-x64-gnu": "4.45.0", - "@rollup/rollup-linux-x64-musl": "4.45.0", - "@rollup/rollup-win32-arm64-msvc": "4.45.0", - "@rollup/rollup-win32-ia32-msvc": "4.45.0", - "@rollup/rollup-win32-x64-msvc": "4.45.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/run-con": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", - "integrity": "sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==", - "dev": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~4.1.0", - "minimist": "^1.2.8", - "strip-json-comments": "~3.1.1" - }, - "bin": { - "run-con": "cli.js" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "has-symbols": "^1.1.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-push-apply": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", - "license": "MIT" - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", - "license": "MIT" - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-proto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/smol-toml": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.4.tgz", - "integrity": "sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 18" - }, - "funding": { - "url": "https://github.com/sponsors/cyyynthia" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/stop-iteration-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", - "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "internal-slot": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", - "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "regexp.prototype.flags": "^1.5.3", - "set-function-name": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.repeat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", - "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-data-property": "^1.1.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-outer/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/style-to-js": { - "version": "1.1.17", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz", - "integrity": "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==", - "license": "MIT", - "dependencies": { - "style-to-object": "1.0.9" - } - }, - "node_modules/style-to-object": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz", - "integrity": "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==", - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.2.4" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/synckit": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.8.tgz", - "integrity": "sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.2.4" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" - } - }, - "node_modules/tailwind-merge": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz", - "integrity": "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/dcastil" - } - }, - "node_modules/tailwindcss": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", - "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", - "license": "MIT" - }, - "node_modules/tailwindcss-animate": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", - "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", - "license": "MIT", - "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders" - } - }, - "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", - "license": "ISC", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", - "license": "MIT", - "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/trim-repeated/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.15", - "reflect.getprototypeof": "^1.0.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0", - "reflect.getprototypeof": "^1.0.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.36.0.tgz", - "integrity": "sha512-fTCqxthY+h9QbEgSIBfL9iV6CvKDFuoxg6bHPNpJ9HIUzS+jy2lCEyCmGyZRWEBSaykqcDPf1SJ+BfCI8DRopA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.36.0", - "@typescript-eslint/parser": "8.36.0", - "@typescript-eslint/utils": "8.36.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/uc.micro": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true, - "license": "MIT" - }, - "node_modules/unbox-primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-bigints": "^1.0.2", - "has-symbols": "^1.1.0", - "which-boxed-primitive": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", - "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vite": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.4.tgz", - "integrity": "sha512-SkaSguuS7nnmV7mfJ8l81JGBFV7Gvzp8IzgE8A8t23+AxuNX61Q5H1Tpz5efduSN7NHC8nQXD3sKQKZAu5mNEA==", - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.6", - "picomatch": "^4.0.2", - "postcss": "^8.5.6", - "rollup": "^4.40.0", - "tinyglobby": "^0.2.14" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-bigint": "^1.1.0", - "is-boolean-object": "^1.2.1", - "is-number-object": "^1.1.1", - "is-string": "^1.1.1", - "is-symbol": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.1.0", - "is-finalizationregistry": "^1.1.0", - "is-generator-function": "^1.0.10", - "is-regex": "^1.2.1", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.1.0", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 210d1fb8..00000000 --- a/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "www-v2", - "private": true, - "version": "0.0.0", - "type": "module", - "homepage": "https://www.sugarlabs.org/", - "scripts": { - "dev": "vite --host", - "build": "tsc -b && vite build", - "lint": "eslint .", - "preview": "vite preview --host", - "predeploy": "npm run build", - "deploy": "gh-pages -d dist", - "lint:ts": "eslint 'src/**/*.{ts,tsx}'", - "lint:md": "markdownlint '**/*.md' --ignore-path .prettierignore", - "format": "prettier --write 'src/**/*.{js,jsx,ts,tsx,json,css,md}'", - "format:file": "prettier --write", - "format:check": "prettier --check 'src/**/*.{js,jsx,ts,tsx,json,css,md}'" - }, - "dependencies": { - "@tailwindcss/vite": "^4.1.11", - "axios": "^1.10.0", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "dompurify": "^3.2.6", - "framer-motion": "^12.23.3", - "hastscript": "^9.0.1", - "lucide-react": "^0.525.0", - "react": "^19.1.0", - "react-dom": "^19.1.0", - "react-markdown": "^10.1.0", - "react-responsive-carousel": "^3.2.23", - "react-router-dom": "^7.6.3", - "rehype-autolink-headings": "^7.1.0", - "rehype-raw": "^7.0.0", - "rehype-sanitize": "^6.0.0", - "rehype-slug": "^6.0.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.1", - "remark-supersub": "^1.0.0", - "tailwind-merge": "^3.3.1", - "tailwindcss": "^4.1.11", - "tailwindcss-animate": "^1.0.7", - "unist-util-visit": "^5.0.0" - }, - "devDependencies": { - "@eslint/js": "^9.30.1", - "@types/node": "^24.0.13", - "@types/react": "^19.1.8", - "@types/react-dom": "^19.1.6", - "@vitejs/plugin-react": "^4.6.0", - "eslint": "^9.31.0", - "eslint-config-prettier": "^10.1.5", - "eslint-plugin-prettier": "^5.5.1", - "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.4.20", - "gh-pages": "^6.3.0", - "globals": "^16.3.0", - "markdownlint": "^0.38.0", - "markdownlint-cli": "^0.45.0", - "prettier": "^3.6.2", - "typescript": "~5.8.3", - "typescript-eslint": "^8.36.0", - "vite": "^7.0.4" - } -} diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index 6f1559fe..00000000 --- a/src/App.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { useEffect } from 'react'; -import { RouterProvider } from 'react-router-dom'; -import router from '@/routes'; - -const App = () => { - useEffect(() => { - const unsubscribe = router.subscribe(() => { - window.scrollTo(0, 0); - }); - const handleRedirect = () => { - const redirectPath = sessionStorage.getItem('gh_redirect'); - if (redirectPath) { - console.log('Restoring route:', redirectPath); - sessionStorage.removeItem('gh_redirect'); - setTimeout(() => { - router.navigate(redirectPath); - }, 10); - } - }; - handleRedirect(); - - return () => unsubscribe(); - }, []); - - return ( - <div className="min-h-screen flex flex-col"> - <RouterProvider router={router} /> - </div> - ); -}; - -export default App; diff --git a/src/components/AboutUs/GoalsSection.tsx b/src/components/AboutUs/GoalsSection.tsx deleted file mode 100644 index 046948cf..00000000 --- a/src/components/AboutUs/GoalsSection.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { motion } from 'framer-motion'; -import { goals, sectionContent, animations } from '@/constants/aboutUs/goals'; -import { FC } from 'react'; - -const GoalsSection: FC = () => { - return ( - <section id="goals" className="w-full py-24 bg-white"> - <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> - {/* Section header */} - <div className="text-center mb-16"> - <motion.h2 - className="text-3xl font-semibold text-slate-800 sm:text-4xl mb-4 tracking-tight" - initial={animations.flowContainer.initial} - whileInView={animations.flowContainer.whileInView} - viewport={{ once: true }} - transition={{ duration: 0.6 }} - > - <span className="text-blue-900 font-medium"> - {sectionContent.title.main} - </span>{' '} - <span className="text-red-600 font-medium"> - {sectionContent.title.highlight} - </span> - </motion.h2> - - <motion.div - className="h-0.5 w-24 bg-gradient-to-r from-blue-600 to-rose-400 mx-auto mb-8" - initial={{ width: 0 }} - whileInView={{ width: 96 }} - viewport={{ once: true }} - transition={{ duration: 0.8, delay: 0.2 }} - /> - - <motion.p - className="text-base sm:text-lg text-slate-600 max-w-3xl mx-auto" - initial={animations.flowContainer.initial} - whileInView={animations.flowContainer.whileInView} - viewport={{ once: true }} - transition={{ duration: 0.6, delay: 0.3 }} - > - {sectionContent.introduction} - </motion.p> - </div> - - {/* Modular Goals Grid */} - <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> - {goals.map((goal, i) => ( - <motion.div - key={i} - className="bg-white rounded-lg shadow-sm p-6 border border-slate-100 transition-all duration-300 - hover:shadow-md group relative overflow-hidden" - initial={animations.goalItem.initial} - whileInView={{ opacity: 1, x: 0 }} - whileHover={{ y: -5 }} - viewport={{ once: true }} - transition={{ duration: 0.5, delay: 0.1 * (i % 6) }} - > - {/* Decorative element - colored top border */} - <div - className={`absolute top-0 left-0 right-0 h-1 - ${i % 3 === 0 ? 'bg-blue-500' : i % 3 === 1 ? 'bg-rose-400' : 'bg-gradient-to-r from-blue-600 to-rose-400'}`} - /> - - {/* Goal number indicator */} - <div className="flex items-center mb-4"> - <div className="w-8 h-8 rounded-full bg-gradient-to-br from-blue-500 to-rose-400 flex items-center justify-center text-white font-semibold text-sm"> - {i + 1} - </div> - <div className="h-px flex-grow bg-slate-100 ml-3"></div> - </div> - - {/* Goal content */} - <h4 className="font-semibold text-slate-800 text-lg mb-3"> - {goal.title} - </h4> - <p className="text-slate-600 leading-relaxed"> - {goal.description} - </p> - - {/* Category tag */} - {goal.category && ( - <div className="mt-4 inline-block px-3 py-1 bg-slate-50 text-xs font-medium text-slate-600 rounded-full"> - {goal.category} - </div> - )} - - {/* Hover indicator */} - <div className="absolute bottom-0 left-0 right-0 h-0.5 bg-gradient-to-r from-blue-500 to-rose-400 transform scale-x-0 group-hover:scale-x-100 transition-transform duration-300 origin-left"></div> - </motion.div> - ))} - </div> - - {/* Call to action */} - <motion.div - className="mt-16 text-center" - initial={animations.flowContainer.initial} - whileInView={animations.flowContainer.whileInView} - viewport={{ once: true }} - transition={{ duration: 0.6, delay: 0.5 }} - ></motion.div> - </div> - </section> - ); -}; - -export default GoalsSection; diff --git a/src/components/AboutUs/HeroSection.tsx b/src/components/AboutUs/HeroSection.tsx deleted file mode 100644 index d27aa642..00000000 --- a/src/components/AboutUs/HeroSection.tsx +++ /dev/null @@ -1,155 +0,0 @@ -import { motion } from 'framer-motion'; -import { heroAnimations } from '@/styles/Animations'; -import { - fadeIn, - slideInLeft, - slideInBottom, - bounce, - staggerContainer, - subtleRise, - dividerVariants, -} from '@/styles/Animations'; - -const HeroSection = () => { - const title = 'ABOUT US'.split(''); - - return ( - <motion.div - className="relative min-h-[50vh] flex flex-col items-center justify-center text-center px-4 py-16 sm:py-20 overflow-hidden" - variants={staggerContainer} - initial="hidden" - animate="visible" - > - {/* Enhanced background elements with gradient overlays - repositioned for mobile */} - <motion.div - className="absolute top-5 left-5 sm:top-10 sm:left-10 w-24 h-24 sm:w-32 sm:h-32 rounded-full bg-gradient-to-br from-indigo-400 to-blue-500 blur-xl sm:blur-2xl opacity-60 dark:opacity-40" - variants={fadeIn} - custom={0.2} - initial="hidden" - animate="visible" - /> - <motion.div - className="absolute bottom-5 right-5 sm:bottom-10 sm:right-10 w-32 h-32 sm:w-48 sm:h-48 rounded-full bg-gradient-to-tr from-emerald-300 to-teal-400 blur-xl sm:blur-2xl opacity-50 dark:opacity-30" - variants={fadeIn} - custom={0.4} - initial="hidden" - animate="visible" - /> - <motion.div - className="absolute top-1/2 left-1/4 w-16 h-16 sm:w-24 sm:h-24 rounded-full bg-gradient-to-r from-amber-300 to-yellow-400 blur-xl sm:blur-2xl opacity-40 dark:opacity-20" - variants={fadeIn} - custom={0.6} - initial="hidden" - animate="visible" - /> - - {/* Main content container with subtle rise effect */} - <motion.div - className="relative z-10 max-w-full" - variants={subtleRise} - initial="hidden" - animate="visible" - > - {/* Main title with animated letters - improved sizing for mobile */} - <motion.h1 className="text-4xl sm:text-6xl md:text-8xl font-bold mb-6 sm:mb-9 tracking-tight relative inline-block font-Caveat"> - <div className="flex justify-center items-center relative"> - {title.map((letter, index) => ( - <motion.span - key={index} - variants={heroAnimations.letterAnimation} - initial="hidden" - animate="visible" - transition={{ - delay: index * 0.1, - duration: 0.6, - ease: [0.22, 1, 0.36, 1], - }} - className={ - index >= title.length - 2 - ? 'text-blue-800 dark:text-blue-600' - : 'text-slate-800 dark:text-slate-200' - } - whileHover={{ - scale: 1.2, - rotate: Math.random() * 10 - 5, - transition: { duration: 0.2 }, - }} - > - {letter === ' ' ? '\u00A0' : letter} - </motion.span> - ))} - - {/* Enhanced animated underline with gradient - adjusted for mobile */} - <motion.div - className="absolute -z-10 h-3 sm:h-6 bottom-1 sm:bottom-2 left-0 transform -skew-x-6 bg-gradient-to-r from-emerald-300 via-teal-400 to-cyan-300 opacity-70 dark:opacity-80" - variants={slideInLeft} - initial="hidden" - animate="visible" - transition={{ delay: 0.8, duration: 0.6 }} - /> - </div> - </motion.h1> - - {/* Decorative divider - adjusted for consistent spacing */} - <motion.div - className="w-16 sm:w-24 h-1 sm:h-1.5 mx-auto mb-6 sm:mb-8 rounded-full bg-gradient-to-r from-blue-500 to-slate-500" - variants={dividerVariants} - initial="hidden" - animate="visible" - /> - - {/* Enhanced subtitle with improved animation and mobile sizing */} - <motion.h2 - className="text-xl sm:text-3xl md:text-4xl mb-8 sm:mb-12 max-w-xs sm:max-w-lg md:max-w-3xl mx-auto leading-relaxed font-Caveat relative text-slate-700 dark:text-slate-200" - variants={slideInBottom} - initial="hidden" - animate="visible" - transition={{ delay: 0.5, duration: 0.8 }} - > - <motion.span - className="relative inline-block" - variants={heroAnimations.hoverText} - whileHover="hover" - > - A - <span className="text-rose-500 dark:text-rose-400 font-semibold"> - {' '} - Community - </span> - </motion.span>{' '} - of{' '} - <motion.span - className="relative inline-block" - variants={heroAnimations.hoverText} - whileHover="hover" - > - <span className="text-emerald-500 dark:text-emerald-400 font-semibold"> - Open Source - </span> - </motion.span>{' '} - <motion.span - variants={bounce} - animate="visible" - className="inline-block" - > - Enthusiasts - </motion.span> - </motion.h2> - </motion.div> - - {/* Enhanced interactive mouse-follow effect - adjusted size for mobile */} - <motion.div - className="absolute w-64 h-64 sm:w-96 sm:h-96 bg-gradient-to-br from-indigo-100 via-purple-100 to-pink-100 dark:from-indigo-900/20 dark:via-purple-900/20 dark:to-pink-900/20 rounded-full blur-2xl sm:blur-3xl opacity-30 dark:opacity-20" - variants={heroAnimations.mouseFollow} - initial="hidden" - animate="visible" - whileHover="hover" - style={{ - mixBlendMode: 'multiply', - }} - /> - </motion.div> - ); -}; - -export default HeroSection; diff --git a/src/components/AboutUs/MissionSection.tsx b/src/components/AboutUs/MissionSection.tsx deleted file mode 100644 index e316f89a..00000000 --- a/src/components/AboutUs/MissionSection.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { motion } from 'framer-motion'; -import { content } from '@/constants/aboutUs/mission'; - -const MissionSection = () => { - return ( - <section id={content.sectionId} className="w-full py-24 bg-white"> - <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> - {/* Section header */} - <div className="text-center mb-16"> - <motion.h2 - className="text-3xl font-semibold text-slate-800 sm:text-4xl mb-4 tracking-tight" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.6 }} - > - <span className="text-blue-900 font-medium"> - {content.title.prefix} - </span>{' '} - <span className="text-red-600 font-medium"> - {content.title.highlighted} - </span> - </motion.h2> - - <motion.div - className="h-0.5 w-24 bg-gradient-to-r from-blue-600 to-red-600 mx-auto mb-8" - initial={{ width: 0 }} - whileInView={{ width: 96 }} - viewport={{ once: true }} - transition={{ duration: 0.8, delay: 0.2 }} - /> - </div> - - <div className="flex flex-col lg:flex-row justify-between items-center gap-16"> - {/* Main image */} - <motion.div - className="w-full lg:w-1/2 order-2 lg:order-1" - initial={{ opacity: 0, x: -20 }} - whileInView={{ opacity: 1, x: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.8 }} - > - <div className="relative"> - <div className="absolute inset-0 bg-gradient-to-r from-blue-600/5 to-red-600/5 rounded-lg -m-2 -z-10"></div> - <div className="overflow-hidden rounded-lg shadow-xl"> - <img - src={content.images.main.src} - alt={content.images.main.alt} - className="w-full h-full object-cover transition-transform duration-700 hover:scale-105" - /> - </div> - </div> - </motion.div> - - {/* Text content */} - <motion.div - className="w-full lg:w-1/2 order-1 lg:order-2 text-slate-700" - initial={{ opacity: 0, x: 20 }} - whileInView={{ opacity: 1, x: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.8 }} - > - <div className="space-y-6"> - {content.paragraphs.map((paragraph, index) => ( - <motion.p - key={index} - className="text-base sm:text-lg leading-relaxed" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.5, delay: 0.1 * index }} - > - {paragraph} - </motion.p> - ))} - </div> - - <motion.div - className="grid grid-cols-2 md:grid-cols-3 gap-4 mt-10" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.6, delay: 0.3 }} - > - {content.images.gallery.map((img, index) => ( - <motion.div - key={index} - className="aspect-video overflow-hidden rounded-md shadow-md" - whileHover={{ scale: 1.03 }} - transition={{ duration: 0.3 }} - > - <img - src={img.src} - alt={img.alt} - className="w-full h-full object-cover" - /> - </motion.div> - ))} - </motion.div> - </motion.div> - </div> - </div> - </section> - ); -}; - -export default MissionSection; diff --git a/src/components/AboutUs/PrinciplesSection.tsx b/src/components/AboutUs/PrinciplesSection.tsx deleted file mode 100644 index 5cac651f..00000000 --- a/src/components/AboutUs/PrinciplesSection.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { motion } from 'framer-motion'; -import { principles, principlesContent } from '@/constants/aboutUs/principles'; - -const PrinciplesSection = () => { - return ( - <section id={principlesContent.sectionId} className="w-full py-24 bg-white"> - <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> - {/* Section header */} - <div className="text-center mb-16"> - <motion.h2 - className="text-3xl font-semibold text-slate-800 sm:text-4xl mb-4 tracking-tight" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.6 }} - > - <span className="text-blue-900 font-medium"> - {principlesContent.title.prefix} - </span>{' '} - <span className="text-red-600 font-medium"> - {principlesContent.title.highlight} - </span> - </motion.h2> - - <motion.div - className="h-0.5 w-24 bg-gradient-to-r from-indigo-700 to-rose-700 mx-auto mb-8" - initial={{ width: 0 }} - whileInView={{ width: 96 }} - viewport={{ once: true }} - transition={{ duration: 0.8, delay: 0.2 }} - /> - </div> - - <div className="flex flex-col lg:flex-row justify-between items-center gap-16 mb-20"> - <motion.div - className="w-full lg:w-1/2" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.8 }} - > - <div className="bg-slate-50 p-8 rounded-lg shadow-md border-l-2 border-indigo-700"> - <p className="text-base sm:text-lg text-slate-700 leading-relaxed"> - {principlesContent.description} - </p> - </div> - </motion.div> - - <motion.div - className="w-full lg:w-1/2" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.8, delay: 0.2 }} - > - <div className="rounded-lg overflow-hidden shadow-lg relative"> - <img - src={principlesContent.featuredImage} - alt="Our Principles" - className="w-full h-[350px] object-cover" - /> - <div className="absolute inset-0 bg-gradient-to-t from-slate-900/80 via-transparent to-transparent opacity-80"></div> - <div className="absolute bottom-0 left-0 right-0 p-6 text-white"> - <h3 className="text-xl font-semibold"> - Our Guiding Principles - </h3> - <div className="w-20 h-0.5 bg-rose-600 mt-2 mb-3"></div> - <p className="text-sm text-slate-100"> - Values that drive our organization forward - </p> - </div> - </div> - </motion.div> - </div> - - {/* Principles grid */} - <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> - {principles.map((principle, index) => ( - <motion.div - key={principle.id} - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.6, delay: 0.1 * index }} - > - <div className="bg-white rounded-lg shadow-md overflow-hidden h-full flex flex-col border border-slate-200 transition-all duration-300 hover:shadow-lg hover:translate-y-[-4px]"> - <div className="h-48 overflow-hidden relative"> - <img - src={principle.image} - alt={principle.title} - className="w-full h-full object-cover" - /> - </div> - - <div className="p-6 flex flex-col flex-grow bg-gradient-to-b from-white to-slate-50"> - <h3 className="text-lg font-semibold text-slate-800 mb-3 pb-2 border-b border-slate-200"> - {principle.title} - </h3> - <p className="text-slate-700 text-base"> - {principle.description} - </p> - </div> - </div> - </motion.div> - ))} - </div> - </div> - </section> - ); -}; - -export default PrinciplesSection; diff --git a/src/components/AboutUs/ProjectSection.tsx b/src/components/AboutUs/ProjectSection.tsx deleted file mode 100644 index a5d3409e..00000000 --- a/src/components/AboutUs/ProjectSection.tsx +++ /dev/null @@ -1,234 +0,0 @@ -import { useState } from 'react'; -import { motion } from 'framer-motion'; -import { projects, projectsContent } from '@/constants/aboutUs/projects'; - -const ProjectsSection = () => { - const [showAllProjects, setShowAllProjects] = useState(false); - - const initialProjectCount = 3; - const displayProjects = showAllProjects - ? projects - : projects.slice(0, initialProjectCount); - - return ( - <section id={projectsContent.sectionId} className="w-full py-24"> - <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> - {/* Section header */} - <div className="text-center mb-16"> - <motion.h2 - className="text-3xl font-semibold text-slate-800 sm:text-4xl mb-4 tracking-tight" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.6 }} - > - <span className="text-blue-900 font-medium"> - {projectsContent.title.prefix} - </span>{' '} - <span className="text-red-600 font-medium"> - {projectsContent.title.highlight} - </span> - </motion.h2> - - <motion.div - className="h-0.5 w-24 bg-gradient-to-r from-blue-600 to-red-600 mx-auto mb-8" - initial={{ width: 0 }} - whileInView={{ width: 96 }} - viewport={{ once: true }} - transition={{ duration: 0.8, delay: 0.2 }} - /> - - {projectsContent.description && ( - <motion.p - className="text-base sm:text-lg text-slate-600 max-w-3xl mx-auto" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.6, delay: 0.3 }} - > - {projectsContent.description} - </motion.p> - )} - </div> - - {/* Projects grid */} - <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> - {displayProjects.map((project, i) => ( - <motion.div - key={i} - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.6, delay: 0.1 * i }} - className="h-full" - > - <div className="bg-white rounded-lg shadow-md overflow-hidden h-full flex flex-col border border-slate-100 transition-all duration-300 hover:shadow-lg hover:translate-y-[-4px]"> - <div className="relative"> - <div className="absolute top-0 right-0 z-10"> - <div className="bg-blue-600 text-white text-xs py-1 px-3 font-medium"> - Project {i + 1} - </div> - </div> - <div className="w-full h-48 bg-slate-50 flex items-center justify-center p-6"> - <img - src={project.imageUrl} - alt={project.title} - className="w-full h-full object-contain" - /> - </div> - </div> - - <div className="p-6 flex flex-col flex-grow"> - <h3 className="text-lg font-semibold text-slate-800 mb-3 pb-2 border-b border-slate-100"> - {project.title} - </h3> - - <p className="text-slate-600 mb-6 flex-grow text-base"> - {project.description} - </p> - - {project.tags && project.tags.length > 0 && ( - <div className="flex flex-wrap gap-2 mb-4"> - {project.tags.map((tag, tagIndex) => ( - <span - key={tagIndex} - className="px-2 py-1 bg-slate-100 text-slate-700 rounded-full text-xs font-medium" - > - {tag} - </span> - ))} - </div> - )} - - {/* Link handling */} - {project.link && ( - <a - href={project.link} - className="text-blue-600 hover:text-red-600 font-medium text-sm flex items-center gap-1 mt-auto transition-colors duration-300 group" - > - {projectsContent.ctaText || 'Learn More'} - <svg - className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-1" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth="2" - d="M9 5l7 7-7 7" - ></path> - </svg> - </a> - )} - - {project.exlink && ( - <a - href={project.exlink} - target="_blank" - rel="noopener noreferrer" - className="text-blue-600 hover:text-red-600 font-medium text-sm flex items-center gap-1 mt-auto transition-colors duration-300 group" - > - {projectsContent.ctaText || 'Visit Website'} - <svg - className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-1" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth="2" - d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" - ></path> - </svg> - </a> - )} - - {!project.link && !project.exlink && ( - <button - className="text-blue-600 hover:text-red-600 font-medium text-sm flex items-center gap-1 mt-auto transition-colors duration-300 group" - onClick={() => (window.location.href = '#projects')} - > - {projectsContent.ctaText || 'Learn More'} - <svg - className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-1" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth="2" - d="M9 5l7 7-7 7" - ></path> - </svg> - </button> - )} - </div> - </div> - </motion.div> - ))} - </div> - - {/* Show more button*/} - {projects.length > initialProjectCount && ( - <motion.div - className="flex justify-center mt-14" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.5, delay: 0.4 }} - > - {!showAllProjects ? ( - <button - onClick={() => setShowAllProjects(true)} - className="px-8 py-3 bg-blue-600 hover:bg-red-600 cursor-pointer text-white rounded-lg shadow-sm font-medium transition-all duration-300 inline-flex items-center gap-2" - > - Show more - <svg - className="w-4 h-4" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth="2" - d="M19 9l-7 7-7-7" - ></path> - </svg> - </button> - ) : ( - <button - onClick={() => setShowAllProjects(false)} - className="px-8 py-3 bg-blue-600 hover:bg-red-600 text-white rounded-lg shadow-sm font-medium transition-all duration-300 inline-flex items-center gap-2" - > - Show less - <svg - className="w-4 h-4" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth="2" - d="M5 15l7-7 7 7" - ></path> - </svg> - </button> - )} - </motion.div> - )} - </div> - </section> - ); -}; - -export default ProjectsSection; diff --git a/src/components/AboutUs/RoadmapSection.tsx b/src/components/AboutUs/RoadmapSection.tsx deleted file mode 100644 index 9f6fb58e..00000000 --- a/src/components/AboutUs/RoadmapSection.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import React from 'react'; -import { motion } from 'framer-motion'; -import { roadmapItems, roadmapContent } from '@/constants/aboutUs/roadmap'; - -const RoadmapSection: React.FC = () => { - return ( - <section id={roadmapContent.sectionId} className="w-full py-24 bg-white"> - <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> - {/* Section header */} - <div className="text-center mb-16"> - <motion.h2 - className="text-3xl font-semibold text-slate-800 sm:text-4xl mb-4 tracking-tight" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.6 }} - > - <span className="text-blue-900 font-medium"> - {roadmapContent.title.prefix} - </span>{' '} - <span className="text-red-600 font-medium"> - {roadmapContent.title.highlight} - </span> - </motion.h2> - - <motion.div - className="h-0.5 w-24 bg-gradient-to-r from-blue-600 to-red-600 mx-auto mb-8" - initial={{ width: 0 }} - whileInView={{ width: 96 }} - viewport={{ once: true }} - transition={{ duration: 0.8, delay: 0.2 }} - /> - - <motion.p - className="text-base sm:text-lg text-slate-600 max-w-3xl mx-auto" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.6, delay: 0.3 }} - > - {roadmapContent.description} - </motion.p> - </div> - - <div className="hidden md:block relative w-full mt-20"> - <motion.div - className="absolute top-0 bottom-0 left-1/2 w-0.5 bg-slate-200 transform -translate-x-1/2" - initial={{ scaleY: 0, transformOrigin: 'top' }} - whileInView={{ scaleY: 1 }} - viewport={{ once: true }} - transition={{ duration: 1.2 }} - /> - - {/* Roadmap items */} - <div className="relative"> - {roadmapItems.map((item, index) => ( - <motion.div - key={index} - className={`flex mb-10 ${ - index % 2 === 0 ? 'justify-start' : 'justify-end' - } relative`} - initial={{ opacity: 0, x: index % 2 === 0 ? -30 : 30 }} - whileInView={{ opacity: 1, x: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.6, delay: 0.2 * index }} - > - {/* Content */} - <div className={`w-3/7 ${index % 2 === 0 ? 'pr-1' : 'pl-1'}`}> - <div - className={`p-5 bg-white rounded-lg shadow-md border-t-2 ${ - item.borderColor || 'border-blue-600' - } transition-all duration-300 hover:shadow-lg`} - > - <h3 className="text-base font-semibold text-slate-800 mb-2 pb-2 border-b border-slate-100"> - {item.title} - </h3> - <p className="text-slate-600 text-sm"> - {item.description || 'Milestone in our journey'} - </p> - </div> - </div> - - {/* Center node */} - <div className="absolute top-5 left-1/2 transform -translate-x-1/2"> - <motion.div - className={`w-10 h-10 rounded-full flex items-center justify-center text-white font-semibold shadow-sm z-10 - ${item.stepColor || 'bg-blue-600'}`} - initial={{ scale: 0 }} - whileInView={{ scale: 1 }} - viewport={{ once: true }} - transition={{ duration: 0.5, delay: 0.3 + 0.1 * index }} - > - {index + 1} - </motion.div> - </div> - </motion.div> - ))} - </div> - </div> - - {/* Mobile Timeline - Single Column */} - <div className="md:hidden relative w-full mt-16"> - <div className="flex flex-col items-start space-y-12"> - {/* Vertical connecting line */} - <motion.div - className="absolute top-0 bottom-0 left-5 w-0.5 bg-slate-200 h-full" - style={{ zIndex: 1 }} - initial={{ scaleY: 0, transformOrigin: 'top' }} - whileInView={{ scaleY: 1 }} - viewport={{ once: true }} - transition={{ duration: 1.2 }} - /> - - {roadmapItems.map((item, index) => ( - <motion.div - key={index} - className="relative w-full flex items-start space-x-4 pl-4 pr-2" - style={{ zIndex: 2 }} - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.5, delay: 0.1 * index }} - > - {/* Step number */} - <motion.div - className={`w-10 h-10 flex-shrink-0 rounded-full flex items-center justify-center text-white font-semibold shadow-sm - ${item.stepColor || 'bg-blue-600'}`} - initial={{ scale: 0 }} - whileInView={{ scale: 1 }} - viewport={{ once: true }} - transition={{ duration: 0.4, delay: 0.2 }} - > - {index + 1} - </motion.div> - - {/* Card */} - <div - className={`flex-grow p-5 bg-white rounded-lg shadow-md border-l-2 ${ - item.borderColor || 'border-blue-600' - }`} - > - <h3 className="text-base font-semibold text-slate-800 mb-2 pb-2 border-b border-slate-100"> - {item.title} - </h3> - <p className="text-slate-600 text-sm"> - {item.description || 'Milestone in our journey'} - </p> - </div> - </motion.div> - ))} - </div> - </div> - </div> - </section> - ); -}; - -export default RoadmapSection; diff --git a/src/components/AboutUs/TextMaskSection.tsx b/src/components/AboutUs/TextMaskSection.tsx deleted file mode 100644 index e9b29176..00000000 --- a/src/components/AboutUs/TextMaskSection.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import { motion } from 'framer-motion'; -import { useState, useEffect } from 'react'; - -const TextMaskSection = () => { - const [fontSize, setFontSize] = useState('120'); - - useEffect(() => { - const handleResize = () => { - const width = window.innerWidth; - if (width < 640) { - setFontSize('50'); - } else if (width < 768) { - setFontSize('70'); - } else if (width < 1024) { - setFontSize('90'); - } else { - setFontSize('120'); - } - }; - - handleResize(); - window.addEventListener('resize', handleResize); - return () => window.removeEventListener('resize', handleResize); - }, []); - - return ( - <div className="py-16"> - <motion.div - className="relative rounded-lg shadow-md overflow-hidden" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ duration: 0.6 }} - > - <div className="relative"> - <div className="relative h-[280px] md:h-[400px] overflow-hidden"> - <div - className="absolute inset-0 w-full h-full" - style={{ - backgroundImage: "url('assets/Images/teach.jpg')", - backgroundSize: 'cover', - backgroundPosition: 'center', - }} - /> - - <div className="relative h-full flex items-center justify-center"> - <svg - className="w-full h-full absolute inset-0" - viewBox="0 0 1200 400" - preserveAspectRatio="xMidYMid slice" - > - <defs> - <mask id="textMask"> - <rect width="100%" height="100%" fill="white" /> - - <text - x="50%" - y="50%" - textAnchor="middle" - dominantBaseline="middle" - fill="black" - fontSize={fontSize} - fontWeight="bold" - fontFamily="Arial, sans-serif" - letterSpacing="0.05em" - className="select-none" - > - SUGAR LABS - </text> - - <line - x1="30%" - y1="65%" - x2="70%" - y2="65%" - stroke="black" - strokeWidth="4" - /> - <line - x1="35%" - y1="70%" - x2="65%" - y2="70%" - stroke="black" - strokeWidth="3" - /> - </mask> - </defs> - - <rect - width="100%" - height="100%" - fill="rgba(255, 255, 255, 0.92)" - mask="url(#textMask)" - /> - </svg> - - {/* Overlay gradient */} - <div className="absolute inset-0 bg-gradient-to-t from-slate-900/30 via-transparent to-transparent mix-blend-overlay"></div> - </div> - - {/* Corner elements */} - <div className="absolute top-6 left-6 w-16 h-16 border-t-2 border-l-2 border-white/60"></div> - <div className="absolute bottom-6 right-6 w-16 h-16 border-b-2 border-r-2 border-white/60"></div> - </div> - - <div className="py-8 px-6 md:px-12 bg-white text-center"> - <motion.h3 - className="text-lg md:text-xl font-medium text-blue-600 mb-3" - initial={{ opacity: 0, y: 10 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ delay: 0.3 }} - > - Innovate. Educate. Transform. - </motion.h3> - - <motion.p - className="text-base md:text-lg text-slate-700 max-w-2xl mx-auto leading-relaxed" - initial={{ opacity: 0, y: 10 }} - whileInView={{ opacity: 1, y: 0 }} - viewport={{ once: true }} - transition={{ delay: 0.5 }} - > - Sugar Labs creates innovative educational tools that transform how - children learn and explore technology. Our community-driven - approach empowers young minds to become creators, not just - consumers. - </motion.p> - </div> - </div> - </motion.div> - </div> - ); -}; - -export default TextMaskSection; diff --git a/src/components/Banner/Icon.tsx b/src/components/Banner/Icon.tsx deleted file mode 100644 index f7c24abf..00000000 --- a/src/components/Banner/Icon.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { IconProps } from '@/constants/Banner'; -import React from 'react'; - -export const PromoIcon: React.FC<IconProps> = ({ theme }) => { - switch (theme) { - case 'primary': - return ( - <svg - xmlns="http://www.w3.org/2000/svg" - className="h-5 w-5" - viewBox="0 0 24 24" - fill="none" - stroke="currentColor" - strokeWidth="1.5" - strokeLinecap="round" - strokeLinejoin="round" - > - {/* Currency note design */} - <rect x="2" y="6" width="20" height="12" rx="2" /> - <circle cx="12" cy="12" r="3.5" /> - <line x1="2" y1="10" x2="22" y2="10" /> - <line x1="2" y1="14" x2="22" y2="14" /> - <path d="M12 8.5v7" /> - <path d="M10.5 10.5c.83-.35 2.17-.35 3 0" /> - <path d="M10.5 13.5c.83.35 2.17.35 3 0" /> - </svg> - ); - case 'success': - return ( - <svg - xmlns="http://www.w3.org/2000/svg" - className="h-5 w-5" - viewBox="0 0 24 24" - fill="none" - stroke="currentColor" - strokeWidth="1.5" - strokeLinecap="round" - strokeLinejoin="round" - > - {/* Check mark in circle */} - <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" /> - <polyline points="22 4 12 14.01 9 11.01" /> - </svg> - ); - case 'warning': - return ( - <svg - xmlns="http://www.w3.org/2000/svg" - className="h-5 w-5" - viewBox="0 0 24 24" - fill="none" - stroke="currentColor" - strokeWidth="1.5" - strokeLinecap="round" - strokeLinejoin="round" - > - {/* Warning triangle */} - <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" /> - <line x1="12" y1="9" x2="12" y2="13" /> - <line x1="12" y1="17" x2="12.01" y2="17" /> - </svg> - ); - case 'sale': - return ( - <svg - xmlns="http://www.w3.org/2000/svg" - className="h-5 w-5" - viewBox="0 0 24 24" - fill="none" - stroke="currentColor" - strokeWidth="1.5" - strokeLinecap="round" - strokeLinejoin="round" - > - {/* Shopping bag */} - <path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z" /> - <line x1="3" y1="6" x2="21" y2="6" /> - <path d="M16 10a4 4 0 0 1-8 0" /> - <line x1="9" y1="15" x2="15" y2="15" /> - </svg> - ); - case 'info': - default: - return ( - <svg - xmlns="http://www.w3.org/2000/svg" - className="h-5 w-5" - viewBox="0 0 24 24" - fill="none" - stroke="currentColor" - strokeWidth="1.5" - strokeLinecap="round" - strokeLinejoin="round" - > - {/* Info icon */} - <circle cx="12" cy="12" r="10" /> - <path d="M12 16v-4" /> - <path d="M12 8h.01" /> - </svg> - ); - } -}; diff --git a/src/components/Banner/Theme.ts b/src/components/Banner/Theme.ts deleted file mode 100644 index e8dc72b2..00000000 --- a/src/components/Banner/Theme.ts +++ /dev/null @@ -1,46 +0,0 @@ -export const themeConfig = { - primary: { - background: 'from-blue-100 to-indigo-200', - border: 'border-blue-300', - icon: 'text-blue-700', - button: - 'from-blue-700 to-indigo-800 hover:from-blue-800 hover:to-indigo-900', - progress: 'from-blue-600 to-indigo-700', - text: 'text-blue-950', - }, - success: { - background: 'from-green-100 to-emerald-200', - border: 'border-green-300', - icon: 'text-emerald-700', - button: - 'from-green-700 to-emerald-800 hover:from-green-800 hover:to-emerald-900', - progress: 'from-green-600 to-emerald-700', - text: 'text-green-950', - }, - warning: { - background: 'from-amber-100 to-orange-200', - border: 'border-amber-300', - icon: 'text-amber-700', - button: - 'from-amber-600 to-orange-700 hover:from-amber-700 hover:to-orange-800', - progress: 'from-amber-600 to-orange-700', - text: 'text-amber-950', - }, - sale: { - background: 'from-purple-100 to-fuchsia-200', - border: 'border-purple-300', - icon: 'text-purple-700', - button: - 'from-purple-700 to-fuchsia-800 hover:from-purple-800 hover:to-fuchsia-900', - progress: 'from-purple-600 to-fuchsia-700', - text: 'text-purple-950', - }, - info: { - background: 'from-cyan-100 to-sky-200', - border: 'border-cyan-300', - icon: 'text-cyan-700', - button: 'from-cyan-700 to-sky-800 hover:from-cyan-800 hover:to-sky-900', - progress: 'from-cyan-600 to-sky-700', - text: 'text-cyan-950', - }, -}; diff --git a/src/components/DeveloperLinks.tsx b/src/components/DeveloperLinks.tsx deleted file mode 100644 index a195d0d7..00000000 --- a/src/components/DeveloperLinks.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { developerLinks } from '@/constants/VolunteerAndDev/Links'; -import { motion } from 'framer-motion'; - -const DeveloperLinks = () => { - const container = { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { - staggerChildren: 0.15, - delayChildren: 0.1, - }, - }, - }; - - const item = { - hidden: { y: 20, opacity: 0 }, - visible: { - y: 0, - opacity: 1, - transition: { type: 'spring' as const, stiffness: 300, damping: 24 }, - }, - }; - - return ( - <section className="container mx-auto px-6 py-10"> - <motion.div - className="grid grid-cols-1 md:grid-cols-2 gap-5 w-full max-w-6xl mx-auto" - variants={container} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - > - {developerLinks.map((link, index) => ( - <motion.a - key={index} - href={link.url} - target="_blank" - rel="noopener noreferrer" - className="relative flex items-center justify-between px-6 py-5 rounded-xl - border-2 border-gray-200 bg-white shadow-sm hover:shadow-lg - overflow-hidden transition-all duration-300 group h-full" - variants={item} - whileHover={{ - scale: 1.02, - borderColor: '#D32F2F', - backgroundColor: 'rgba(240, 249, 255, 0.7)', - }} - whileTap={{ scale: 0.98 }} - > - {/* Gradient Hover Effect */} - <span className="absolute inset-0 bg-gradient-to-r from-red-50 to-red-100 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></span> - - {/* Link Content */} - <div className="relative flex items-center gap-4 z-10 flex-1"> - <div className="flex-shrink-0 w-10 h-10 rounded-full bg-red-100 flex items-center justify-center group-hover:bg-red-200 transition-colors"> - <img - src={link.icon} - alt={link.name} - className="w-5 h-5 group-hover:scale-110 transition-transform" - /> - </div> - <span className="text-base md:text-lg font-medium text-gray-800 group-hover:text-red-700 transition-colors"> - {link.name} - </span> - </div> - - {/* Arrow with enhanced animation */} - <div className="relative z-10 flex items-center justify-center w-8 h-8 rounded-full bg-red-100 group-hover:bg-red-200 transition-colors ml-4 flex-shrink-0"> - <span className="text-gray-600 group-hover:text-red-700 transform group-hover:translate-x-1 transition-all"> - → - </span> - </div> - </motion.a> - ))} - </motion.div> - </section> - ); -}; - -export default DeveloperLinks; diff --git a/src/components/DeveloperTestimonials.tsx b/src/components/DeveloperTestimonials.tsx deleted file mode 100644 index fb8b16b4..00000000 --- a/src/components/DeveloperTestimonials.tsx +++ /dev/null @@ -1,160 +0,0 @@ -import { motion } from 'framer-motion'; -import { Marquee } from '@/components/magicui/Marquee'; -import { developertestimonials } from '@/constants/VolunteerAndDev/DeveloperTestimonials'; -import { stats } from '@/constants/Stats'; -import { - testimonialCard, - testimonialHeading, - decorativeElement, - testimonialText, - avatarReveal, - marqueeContainer, -} from '@/styles/Animations'; - -const ReviewCard = ({ - img, - name, - username, - body, - delay = 0, -}: { - img: string; - name: string; - username: string; - body: string; - delay?: number; -}) => { - return ( - <motion.div - className="bg-white dark:bg-gray-900 rounded-xl p-6 flex flex-col items-center text-center min-h-[250px] h-auto w-[350px] shadow-lg border border-gray-200 dark:border-gray-700 mx-2 justify-between" - variants={testimonialCard} - initial="hidden" - whileInView="visible" - whileHover="hover" - viewport={{ once: true, amount: 0.1 }} - transition={{ delay }} - > - {/* Quote Icon */} - <motion.img - src={stats.apostrophie} - alt="double-quotes" - className="w-10 h-10 self-start opacity-70" - variants={decorativeElement} - /> - - {/* Feedback Text */} - <motion.p - className="text-gray-700 dark:text-gray-300 mt-2" - variants={testimonialText} - > - {body} - </motion.p> - - {/* User Info */} - <div className="flex items-center mt-4 space-x-3 text-left"> - <motion.img - src={img} - alt={name} - className="w-12 h-12 rounded-full border border-gray-300" - variants={avatarReveal} - /> - <motion.div variants={testimonialText}> - <h3 className="text-lg font-semibold text-gray-900 dark:text-white"> - {name} - </h3> - <p className="text-sm text-gray-500 dark:text-gray-400"> - @{username} - </p> - </motion.div> - </div> - </motion.div> - ); -}; - -export function DeveloperTestimonials() { - return ( - <div className="w-full p-6"> - {/* Heading Section with Hearts */} - <motion.div - className="flex items-center justify-center gap-4 md:gap-6 mb-12" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.6 }} - variants={marqueeContainer} - > - {/* Left Heart */} - <motion.img - src={stats.leftHeart} - alt="Heart Left" - className="w-8 md:w-12 lg:w-16 fill-current text-red-500 border-none shadow-none" - variants={decorativeElement} - animate="float" - custom={1} - /> - - <div className="relative flex items-center justify-center gap-4 md:gap-6 lg:gap-8"> - {/* Left Apostrophe (Hidden Below 400px) */} - <motion.img - src={stats.apostrophie} - alt="Apostrophe Left" - className="w-8 md:w-12 lg:w-16 -translate-y-2 block max-[400px]:hidden" - variants={decorativeElement} - custom={2} - /> - - <motion.h2 - className="font-bold tracking-wider font-Caveat text-3xl md:text-5xl lg:text-6xl text-gray-800 text-center" - variants={testimonialHeading} - > - <span className="text-5xl font-bold font-[Caveat]"> - What do developers say - <br /> - about their journey? - </span> - </motion.h2> - - {/* Right Apostrophe (Flipped, Hidden Below 400px) */} - <motion.img - src={stats.apostrophie} - alt="Apostrophe Right" - className="w-8 md:w-12 lg:w-16 -translate-y-2 scale-x-[-1] block max-[400px]:hidden" - variants={decorativeElement} - custom={3} - /> - </div> - - {/* Right Heart */} - <motion.img - src={stats.rightHeart} - alt="Heart Right" - className="w-8 md:w-12 lg:w-16 fill-current text-red-500 border-none shadow-none" - variants={decorativeElement} - animate="float" - custom={4} - /> - </motion.div> - - {/* Testimonials Section */} - <motion.div - className="relative flex flex-col items-center justify-center w-full overflow-hidden mt-6" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.1 }} - variants={marqueeContainer} - > - <Marquee pauseOnHover className="w-full flex"> - {developertestimonials.map((review, index) => ( - <ReviewCard - key={review.username} - {...review} - delay={index * 0.05} - /> - ))} - </Marquee> - - <div className="pointer-events-none absolute inset-y-0 left-0 w-1/4 bg-gradient-to-r from-background"></div> - <div className="pointer-events-none absolute inset-y-0 right-0 w-1/4 bg-gradient-to-l from-background"></div> - </motion.div> - </div> - ); -} diff --git a/src/components/DirectorCard.tsx b/src/components/DirectorCard.tsx deleted file mode 100644 index 3ca5ad0e..00000000 --- a/src/components/DirectorCard.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import React, { useState } from 'react'; -import { DirectorCardProps, SocialLinkProps } from '@/constants/Leadership'; - -const DirectorCard: React.FC<DirectorCardProps> = ({ director }) => { - const [imageError, setImageError] = useState(false); - const showPlaceholder = imageError || !director.imageUrl; - - return ( - <div className="flex flex-col h-full bg-white rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300"> - <div className="flex justify-center pt-8 pb-4 relative"> - <div className="absolute top-0 left-0 w-1 h-full bg-red-500"></div> - <div className="w-32 h-32 rounded-full overflow-hidden border-4 border-white shadow-md"> - {showPlaceholder ? ( - <div className="flex items-center justify-center w-full h-full bg-gray-100 text-gray-700 text-2xl font-bold"> - {director.name - .split(' ') - .map((n) => n[0]) - .join('')} - </div> - ) : ( - <img - src={director.imageUrl} - alt={`${director.name}`} - className="w-full h-full object-cover" - onError={() => setImageError(true)} - /> - )} - </div> - </div> - - <div className="flex flex-col flex-grow p-5 gap-3"> - <div className="text-center"> - <h3 className="text-xl font-bold text-gray-900">{director.name}</h3> - {director.position && ( - <p className="text-sm font-medium text-red-500 mt-1"> - {director.position} - </p> - )} - </div> - - <div className="w-16 h-0.5 bg-gray-200 mx-auto"></div> - <div className="flex-grow"> - <div className="text-gray-600 text-sm leading-relaxed max-h-28 overflow-y-auto pr-1 custom-scrollbar"> - {director.bio || 'No biography available.'} - </div> - </div> - - <div className="pt-3 mt-auto border-t border-gray-100"> - <div className="flex items-center justify-center gap-4"> - {director.socialLinks?.linkedin && ( - <SocialLink - href={director.socialLinks.linkedin} - aria="LinkedIn" - icon={<LinkedInIcon />} - /> - )} - {director.socialLinks?.github && ( - <SocialLink - href={director.socialLinks.github} - aria="GitHub" - icon={<GitHubIcon />} - /> - )} - {director.socialLinks?.wiki && ( - <SocialLink - href={director.socialLinks.wiki} - aria="Wiki" - icon={<WikiIcon />} - /> - )} - {!director.socialLinks?.linkedin && - !director.socialLinks?.github && - !director.socialLinks?.wiki && ( - <span className="text-xs text-gray-400"> - No social links available - </span> - )} - </div> - </div> - </div> - </div> - ); -}; - -const SocialLink: React.FC<SocialLinkProps> = ({ href, aria, icon }) => ( - <a - href={href} - target="_blank" - rel="noopener noreferrer" - className="text-gray-500 hover:text-red-500 transition-colors" - aria-label={aria} - > - {icon} - </a> -); - -const LinkedInIcon = () => ( - <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> - <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452z" /> - </svg> -); - -const GitHubIcon = () => ( - <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> - <path - fillRule="evenodd" - d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" - clipRule="evenodd" - /> - </svg> -); -const WikiIcon = () => ( - <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> - <path d="M4 5h2l2.5 9L12 5h2l3.5 9L20 5h2l-4 14h-2l-4-10-4 10H6L2 5z" /> - </svg> -); - -export default DirectorCard; diff --git a/src/components/Donation.tsx b/src/components/Donation.tsx deleted file mode 100644 index 2a97ea84..00000000 --- a/src/components/Donation.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import React, { useState } from 'react'; -import { Link } from 'react-router-dom'; -import { motion } from 'framer-motion'; -import { donationData } from '@/constants/Donation'; -import { volunteerImages } from '@/constants/Volunteer'; -import { - fadeIn, - slideInLeft, - slideInRight, - slideInBottom, - bounce, - staggerContainer, - buttonAnimation, -} from '@/styles/Animations'; - -const Donation: React.FC = () => { - const [email, setEmail] = useState(''); - - const handleDonateClick = () => { - window.open(donationData.url, '_blank'); - }; - - return ( - <section className="relative overflow-hidden bg-white text-black py-16 px-4"> - <div className="max-w-[90%] mx-auto flex flex-col lg:flex-row items-center justify-center lg:gap-12"> - {/* Left Side - Text Content */} - <motion.div - className="lg:w-1/2 text-center lg:text-left" - variants={slideInLeft} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <p className="italic text-gray-600 text-lg md:text-xl"> - Donate to Sugar Labs to make a{' '} - <span className="font-bold">Positive</span> Impact - </p> - <h1 className="text-4xl md:text-5xl font-bold mt-2 leading-tight"> - <span className="text-red-500">Support</span> and Empower <br />{' '} - Learners Everywhere - </h1> - <p className="text-gray-600 text-lg mt-4"> - Support Sugar Labs and make a difference in children's education. - Sugar Labs has brought educational software and authentic problem - solving to millions in the US and across the globe. - </p> - - {/* Donate Now Button */} - <motion.button - onClick={handleDonateClick} - className="mt-6 px-6 py-3 bg-[#fbd04d] text-black text-2xl font-bold rounded-full shadow-md hover:bg-yellow-500 cursor-pointer transition duration-300 uppercase" - variants={bounce} - whileHover="hover" - whileTap="tap" - > - Donate Now - </motion.button> - </motion.div> - - {/* Right Side - Image */} - <motion.img - src="assets/Images/DonateToSugarLabs.png" - alt="Children with laptops and Donate to Sugarlabs" - className="w-[400px] lg:w-[500px] transition-none hover:transform-none object-contain" - variants={slideInRight} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - whileHover={{ scale: 1.01 }} - /> - </div> - - {/* Newsletter and Volunteer Section*/} - <div className="relative z-10 w-full mt-12 text-center"> - <motion.div - className="flex justify-center items-center" - variants={slideInBottom} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.6 }} - > - <div className="relative"> - <motion.div - className="absolute -top-8 -right-8" - animate={{ - x: [0, 10, 0], - transition: { repeat: Infinity, duration: 1.5 }, - }} - > - <i className="fas fa-arrow-right text-2xl" /> - </motion.div> - <Link to="/volunteer"> - <motion.div - className="bg-white border border-gray-300 rounded-full px-4 py-2 flex items-center shadow-lg" - whileHover={{ scale: 1.05 }} - transition={{ type: 'spring', stiffness: 400, damping: 10 }} - > - {volunteerImages.map((volunteer, index) => ( - <motion.img - key={volunteer.id} - alt={volunteer.alt} - className="w-8 h-8 rounded-full border-2 border-white -ml-2" - src={volunteer.src} - initial={{ opacity: 0, x: -20 }} - animate={{ opacity: 1, x: 0 }} - transition={{ delay: 0.05 * index }} - /> - ))} - <span className="ml-4 text-sm">Join the volunteer</span> - <motion.span - className="ml-2 bg-blue-500 text-white text-xs rounded-full px-2 py-1" - initial={{ scale: 0 }} - animate={{ - scale: 1, - transition: { - type: 'spring', - stiffness: 400, - damping: 10, - delay: 0.3, - }, - }} - > - +1000 - </motion.span> - </motion.div> - </Link> - </div> - </motion.div> - - {/* Newsletter Subscription Section */} - <motion.div - className="mt-16" - variants={staggerContainer} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - > - <motion.p className="text-lg" variants={fadeIn}> - Join us to empower young learners across the globe. The simplest way - to get involved is to join our newsletter. - </motion.p> - - <motion.div - className="mt-4 flex justify-center items-center" - variants={slideInRight} - > - <motion.form - action="https://buttondown.com/api/emails/embed-subscribe/sugarlabs" - method="post" - onSubmit={() => setTimeout(() => setEmail(''), 500)} - className="flex" - > - <input - className="px-4 py-2 border border-gray-300 rounded-l-full focus:outline-none" - placeholder="Enter your email" - type="email" - name="email" - value={email} - onChange={(e) => setEmail(e.target.value)} - required - /> - <input value="1" type="hidden" name="embed" /> - <motion.button - className="px-6 py-2 bg-red-500 text-white font-bold rounded-r-full shadow-lg hover:bg-red-600 cursor-pointer transition duration-300" - variants={buttonAnimation} - whileHover="whileHover" - whileTap="whileTap" - type="submit" - > - SUBSCRIBE - </motion.button> - </motion.form> - </motion.div> - </motion.div> - </div> - </section> - ); -}; - -export default Donation; diff --git a/src/components/FAQItem.tsx b/src/components/FAQItem.tsx deleted file mode 100644 index 8dc5bc0e..00000000 --- a/src/components/FAQItem.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { useState } from 'react'; -import { motion } from 'framer-motion'; - -type FAQItemProps = { - index: number; - question: string; - answer: string; -}; - -const faqItemVariants = { - initial: { opacity: 0, y: 10 }, - animate: { opacity: 1, y: 0, transition: { duration: 0.3 } }, -}; - -const faqQuestionButtonVariants = { - hover: { scale: 1.02 }, -}; - -const faqToggleIconVariants = (isOpen: boolean) => ({ - initial: { rotate: 0 }, - animate: { rotate: isOpen ? 180 : 0, transition: { duration: 0.2 } }, -}); - -const faqAnswerVariants = (isOpen: boolean) => ({ - initial: { height: 0, opacity: 0 }, - animate: { - height: isOpen ? 'auto' : 0, - opacity: isOpen ? 1 : 0, - transition: { duration: 0.3 }, - }, -}); - -const FAQItem = ({ index, question, answer }: FAQItemProps) => { - const [isOpen, setIsOpen] = useState(false); - - const toggleFAQ = () => setIsOpen((prev) => !prev); - - return ( - <motion.div - key={index} - className="border-b last:border-b-0" - variants={faqItemVariants} - initial="initial" - animate="animate" - > - <motion.button - className="w-full text-left py-4 text-lg font-medium flex justify-between items-center hover:cursor-pointer" - onClick={toggleFAQ} - whileHover="hover" - variants={faqQuestionButtonVariants} - > - {question} - <motion.span - variants={faqToggleIconVariants(isOpen)} - initial="initial" - animate="animate" - > - {isOpen ? '-' : '+'} - </motion.span> - </motion.button> - <motion.div - variants={faqAnswerVariants(isOpen)} - initial="initial" - animate="animate" - style={{ overflow: 'hidden' }} - > - <p className="p-4 text-gray-700">{answer}</p> - </motion.div> - </motion.div> - ); -}; - -export default FAQItem; diff --git a/src/components/Info.tsx b/src/components/Info.tsx deleted file mode 100644 index f92664ae..00000000 --- a/src/components/Info.tsx +++ /dev/null @@ -1,293 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { Carousel } from 'react-responsive-carousel'; -import 'react-responsive-carousel/lib/styles/carousel.min.css'; -import { motion } from 'framer-motion'; -import { heroContent, images, ImageConfig, mission } from '@/constants/Info.ts'; -import { - fadeIn, - simpleFadeIn, - subtleRise, - simpleGridContainer, -} from '@/styles/Animations'; - -const Info: React.FC = () => { - const [windowWidth, setWindowWidth] = useState(0); - - useEffect(() => { - const handleResize = () => { - setWindowWidth(window.innerWidth); - }; - // Set initial width - handleResize(); - // Add event listener - window.addEventListener('resize', handleResize); - // Cleanup event listener - return () => window.removeEventListener('resize', handleResize); - }, []); - - const renderCarouselItem = (key: string, image: ImageConfig) => ( - <div key={key} className="relative"> - <img - src={image.src} - alt={image.alt} - className="w-full h-48 sm:h-64 object-cover" - loading="lazy" - /> - {image.caption && ( - <div - className="absolute bottom-0 inset-x-0 bg-gradient-to-t from-black/90 - to-transparent p-3 sm:p-4" - > - <p className="text-white font-normal text-sm sm:text-base"> - {image.caption} - </p> - </div> - )} - </div> - ); - - return ( - <> - <div className="min-h-screen bg-gradient-to-b from-slate-50 to-white font-Inter"> - <main className="max-w-7xl mx-auto px-3 sm:px-4 md:px-6 py-8 sm:py-10 md:py-12 space-y-12 sm:space-y-16 md:space-y-20"> - {/* Hero Section */} - <section className="container mx-auto px-2 sm:px-4 py-6 sm:py-8 max-w-7xl"> - <motion.div - className="relative mb-6 sm:mb-8 rounded-2xl sm:rounded-3xl overflow-hidden shadow-xl sm:shadow-2xl - transform hover:scale-[1.01] transition-all duration-500 - ease-out bg-white" - initial="hidden" - whileInView="visible" - viewport={{ once: true }} - variants={simpleFadeIn} - > - <img - src={images.main.src} - alt={images.main.alt} - className="w-full h-[350px] sm:h-[400px] md:h-[500px] lg:h-[600px] xl:h-[700px] object-cover" - /> - <div - className="absolute inset-0 bg-gradient-to-r from-black/70 - via-black/50 to-transparent" - /> - <motion.div - className="absolute top-1/2 left-2 sm:left-6 md:left-12 transform -translate-y-1/2 - text-white max-w-xs sm:max-w-sm md:max-w-lg lg:max-w-2xl p-2 sm:p-0" - initial="hidden" - whileInView="visible" - viewport={{ once: true }} - variants={subtleRise} - > - <h1 - className="text-3xl sm:text-4xl md:text-5xl lg:text-6xl xl:text-7xl font-black mb-3 sm:mb-4 md:mb-6 lg:mb-8 - leading-tight tracking-tight animate-fade-in font-display" - > - {heroContent.title} - </h1> - <p - className="text-base sm:text-lg md:text-xl lg:text-2xl leading-relaxed opacity-90 - animate-fade-in-delayed font-light" - > - {heroContent.description} - </p> - </motion.div> - </motion.div> - - {/* Desktop Image Grid */} - <motion.div - className="hidden md:grid grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4" - variants={simpleGridContainer} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.1 }} - > - {Object.entries(images) - .filter(([key]) => key.startsWith('bottom')) - .map(([key, image]) => ( - <motion.div - key={key} - className="group relative rounded-3xl overflow-hidden shadow-lg hover:shadow-2xl - transition-all duration-500 bg-white" - variants={subtleRise} - whileHover="hover" - > - <img - src={image.src} - alt={image.alt || key} - className="w-full h-auto object-cover transform group-hover:scale-105 - transition-all duration-700 ease-out" - loading="lazy" - /> - {image.caption && ( - <div - className="absolute bottom-0 inset-x-0 bg-gradient-to-t from-black/90 - to-transparent p-3 sm:p-4 md:p-6 lg:p-8" - > - <p className="text-white font-medium text-sm sm:text-base md:text-lg lg:text-xl"> - {image.caption} - </p> - </div> - )} - </motion.div> - ))} - </motion.div> - - {/* Mobile Carousel */} - <motion.div - className="md:hidden" - variants={fadeIn} - initial="hidden" - whileInView="visible" - viewport={{ once: true }} - > - <Carousel - showThumbs={false} - showStatus={false} - infiniteLoop - autoPlay - interval={5000} - transitionTime={500} - className="rounded-xl sm:rounded-2xl overflow-hidden" - stopOnHover - swipeable - emulateTouch - > - {Object.entries(images) - .filter(([key]) => key.startsWith('bottom')) - .map(([key, image]) => renderCarouselItem(key, image))} - </Carousel> - </motion.div> - </section> - - {/* Mission Section */} - <motion.section - className="grid sm:grid-cols-1 md:grid-cols-2 gap-8 sm:gap-10 md:gap-16 lg:gap-20 items-center px-2 sm:px-4" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - variants={simpleFadeIn} - > - <div className="space-y-6 sm:space-y-8 md:space-y-10"> - <div - className="inline-block px-3 sm:px-4 md:px-6 py-1.5 sm:py-2 md:py-3 bg-gradient-to-r - from-red-500/10 to-orange-500/10 rounded-full" - > - <span - className="text-xs sm:text-sm font-bold text-red-600 tracking-wider - uppercase" - > - Empowering Young Learners - </span> - </div> - <motion.h2 - className="text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-black space-y-1 sm:space-y-2 - font-display tracking-tight" - variants={subtleRise} - > - <span className="font-bold tracking-wider font-Caveat text-5xl sm:text-6xl md:text-7xl lg:text-8xl"> - Our Mission? - </span> - <div> - <div - className="text-transparent bg-clip-text bg-gradient-to-r - from-red-500 to-orange-500 font-Caveat text-5xl sm:text-6xl md:text-7xl lg:text-8xl" - > - Authentic - </div> - <span className="font-semibold">Problem</span> - <br /> - <span className="font-semibold">Solving</span> - </div> - </motion.h2> - - <motion.h4 - className="text-base sm:text-lg md:text-xl font-bold text-gray-800" - variants={subtleRise} - > - Igniting Curiosity through Project Based Learning - </motion.h4> - - <p className="text-gray-600 text-sm sm:text-base md:text-lg font-Roboto"> - Empowering Young Minds with Hands-on Learning, Transforming - Curiosity into Discovery and Innovation. - </p> - </div> - - <motion.div className="relative" variants={subtleRise}> - <div className="bg-auto rounded-xl sm:rounded-2xl overflow-hidden shadow-lg sm:shadow-xl"> - {/* Background Image */} - <motion.img - src={mission.learnImage} - alt="Students learning" - className="w-full rounded-xl sm:rounded-2xl transform hover:scale-105 - transition-all duration-500 ease-out" - loading="lazy" - whileHover={{ scale: 1.05 }} - /> - - {/* Card on Top Left */} - {windowWidth >= 270 && ( - <motion.div - className="absolute top-2 left-2 bg-black/60 - backdrop-blur-sm rounded-lg sm:rounded-xl p-2.5 sm:p-4 md:p-6 shadow-lg - max-w-[180px] sm:max-w-[220px] md:max-w-xs transform hover:scale-105 - transition-all duration-300 ease-out z-10 border border-white/50" - whileHover={{ scale: 1.05 }} - > - {windowWidth >= 355 && ( - <> - <h3 className="text-base sm:text-lg md:text-xl font-bold mb-1 md:mb-2 text-gray-100 font-AnonymousPro"> - Project Based Learning - </h3> - <p className="text-white text-xs sm:text-sm leading-tight sm:leading-snug"> - Empowering learners and educators with hands-on - project-based tools that enable creation and - real-world problem-solving. - </p> - </> - )} - {windowWidth < 355 && windowWidth >= 250 && ( - <h3 className="text-base sm:text-lg md:text-xl font-bold text-gray-100 font-AnonymousPro"> - Project Based Learning - </h3> - )} - </motion.div> - )} - - {/* Card on Bottom Right */} - {windowWidth >= 270 && ( - <motion.div - className="absolute bottom-2 right-2 bg-black/60 - backdrop-blur-sm rounded-lg sm:rounded-xl p-2.5 sm:p-4 md:p-6 shadow-lg - max-w-[180px] sm:max-w-[220px] md:max-w-xs transform hover:scale-105 - transition-all duration-300 ease-out z-10 border border-white/50" - whileHover={{ scale: 1.05 }} - > - {windowWidth >= 355 && ( - <> - <h3 className="text-base sm:text-lg font-bold mb-1 text-amber-100 font-AnonymousPro"> - Challenge and Fun: It's hard fun. - </h3> - <p className="text-white text-xs sm:text-sm leading-tight sm:leading-snug"> - Bringing interactive, meaningful experiences that make - education exciting and impactful. - </p> - </> - )} - {windowWidth < 355 && windowWidth >= 270 && ( - <h3 className="text-base sm:text-lg font-bold text-amber-100 font-AnonymousPro"> - Challenge and Fun: It's hard fun. - </h3> - )} - </motion.div> - )} - </div> - </motion.div> - </motion.section> - </main> - </div> - </> - ); -}; - -export default Info; diff --git a/src/components/JoinToggle.tsx b/src/components/JoinToggle.tsx deleted file mode 100644 index 35728900..00000000 --- a/src/components/JoinToggle.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useLocation, useNavigate } from 'react-router-dom'; -import { motion } from 'framer-motion'; - -const JoinToggle = () => { - const location = useLocation(); - const navigate = useNavigate(); - - // Determine active page - const isVolunteerPage = location.pathname === '/volunteer'; - const isDevPage = location.pathname === '/join-development'; - - return ( - <div className="pt-12 md:pt-20"> - <div className="flex flex-wrap items-center justify-center md:justify-between w-full max-w-6xl font-Oswald"> - {/* Left Side: JOIN (Always stays the same) */} - <div className="w-full md:w-1/2 flex justify-center md:justify-end pr-0 md:pr-12"> - <h1 className="text-6xl md:text-[10rem] font-extralight tracking-tight text-center md:text-right"> - JOIN - </h1> - </div> - - {/* Right Side: Volunteer & Development (Stacked) */} - <div className="w-full md:w-1/2 flex flex-col justify-center items-center md:items-start"> - {/* Volunteer (Active or Clickable) */} - <motion.h2 - className="text-4xl md:text-[5rem] font-extralight pb-1 md:pb-2 cursor-pointer transition-colors" - initial={{ opacity: 0.6, scale: 0.95 }} - animate={{ - color: isVolunteerPage ? '#EF4444' : '#D1D5DB', - opacity: isVolunteerPage ? 1 : 0.7, - scale: isVolunteerPage ? 1.1 : 1, - }} - transition={{ duration: 0.4, ease: 'easeInOut' }} - onClick={() => !isVolunteerPage && navigate('/volunteer')} - > - Volunteer - </motion.h2> - - {/* Divider Line */} - <div className="border-t border-gray-300 w-3/4 md:w-4/5"></div> - - {/* Development (Active or Clickable) */} - <motion.h2 - className="text-4xl md:text-[5rem] font-extralight pt-1 md:pt-2 cursor-pointer transition-colors" - initial={{ opacity: 0.6, scale: 0.95 }} - animate={{ - color: isDevPage ? '#EF4444' : '#D1D5DB', - opacity: isDevPage ? 1 : 0.7, - scale: isDevPage ? 1.1 : 1, - }} - transition={{ duration: 0.4, ease: 'easeInOut' }} - onClick={() => !isDevPage && navigate('/join-development')} - > - Development - </motion.h2> - </div> - </div> - </div> - ); -}; - -export default JoinToggle; diff --git a/src/components/Product.tsx b/src/components/Product.tsx deleted file mode 100644 index f7dbbbd6..00000000 --- a/src/components/Product.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { useState } from 'react'; -import { products, ProductType } from '@/constants/ProductsData'; -import { Carousel } from 'react-responsive-carousel'; -import 'react-responsive-carousel/lib/styles/carousel.min.css'; - -const Product = () => { - return ( - <section className="py-12 px-4"> - <div className="max-w-5xl mx-auto grid grid-cols-1 gap-12"> - {products.map((product, index) => ( - <ProductCard key={index} product={product} /> - ))} - </div> - </section> - ); -}; - -const ProductCard = ({ product }: { product: ProductType }) => { - const imageUrls = Object.values(product.colors); - const hasMultipleImages = imageUrls.length > 1; - const [currentImage, setCurrentImage] = useState(0); - - return ( - <div className="grid grid-cols-1 md:grid-cols-2 gap-8 border-b pb-10"> - {/* Product Image Carousel with custom hover controls */} - <div className="relative group w-full"> - <Carousel - selectedItem={currentImage} - onChange={(index) => setCurrentImage(index)} - showArrows={false} - showThumbs={false} - showStatus={false} - showIndicators={true} - infiniteLoop - useKeyboardArrows - swipeable - > - {imageUrls.map((img, idx) => ( - <div key={idx}> - <img - src={img} - alt={`${product.name} image ${idx + 1}`} - className="w-full rounded-lg shadow-md" - /> - </div> - ))} - </Carousel> - - {/* LEFT hover zone */} - {hasMultipleImages && currentImage > 0 && ( - <div - className="absolute left-0 top-0 h-full w-1/4 bg-gradient-to-r from-black/30 to-transparent opacity-0 group-hover:opacity-100 transition-all duration-300 cursor-pointer z-10" - onClick={() => setCurrentImage((prev) => prev - 1)} - > - <div className="absolute left-4 top-1/2 transform -translate-y-1/2 w-0 h-0 border-t-8 border-b-8 border-r-8 border-transparent border-r-white" /> - </div> - )} - - {/* RIGHT hover zone */} - {hasMultipleImages && currentImage < imageUrls.length - 1 && ( - <div - className="absolute right-0 top-0 h-full w-1/4 bg-gradient-to-l from-black/30 to-transparent opacity-0 group-hover:opacity-100 transition-all duration-300 cursor-pointer z-10" - onClick={() => setCurrentImage((prev) => prev + 1)} - > - <div className="absolute right-4 top-1/2 transform -translate-y-1/2 w-0 h-0 border-t-8 border-b-8 border-l-8 border-transparent border-l-white" /> - </div> - )} - </div> - - {/* Product Details */} - <div> - <h3 className="text-3xl font-semibold">{product.name}</h3> - <p className="text-gray-600 mt-2">{product.description}</p> - - <div className="mt-6"> - <a - href={product.link} - target="_blank" - rel="noopener noreferrer" - className="bg-blue-600 text-white px-6 py-3 rounded-lg text-lg shadow-md hover:bg-blue-700 transition" - > - Buy Now - </a> - </div> - </div> - </div> - ); -}; - -export default Product; diff --git a/src/components/ShareModal.tsx b/src/components/ShareModal.tsx deleted file mode 100644 index 3b96fd1c..00000000 --- a/src/components/ShareModal.tsx +++ /dev/null @@ -1,184 +0,0 @@ -import React from 'react'; - -interface ShareModalProps { - open: boolean; - onClose: () => void; - url: string; - title: string; - excerpt?: string; -} - -const shareOptions = [ - { - name: 'Copy Link', - action: async (url: string) => { - await navigator.clipboard.writeText(url); - alert('Link copied to clipboard!'); - }, - icon: ( - <svg - width="20" - height="20" - fill="none" - stroke="currentColor" - strokeWidth="2" - viewBox="0 0 24 24" - > - <path d="M10 14L21 3m0 0v7m0-7h-7" /> - <path d="M21 14v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h7" /> - </svg> - ), - }, - { - name: 'Twitter', - action: (url: string, title: string) => { - window.open( - `https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}&text=${encodeURIComponent(title)}`, - '_blank', - ); - }, - icon: ( - <img src="/assets/social/x.svg" alt="Twitter" width={20} height={20} /> - ), - }, - { - name: 'Facebook', - action: (url: string) => { - window.open( - `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`, - '_blank', - ); - }, - icon: ( - <img - src="/assets/social/facebook.svg" - alt="Facebook" - width={20} - height={20} - /> - ), - }, - { - name: 'WhatsApp', - action: (url: string, title: string) => { - window.open( - `https://api.whatsapp.com/send?text=${encodeURIComponent(title + ' ' + url)}`, - '_blank', - ); - }, - icon: ( - <img - src="/assets/social/whatsapp.svg" - alt="WhatsApp" - width={20} - height={20} - /> - ), - }, - { - name: 'LinkedIn', - action: (url: string, title: string) => { - window.open( - `https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(url)}&title=${encodeURIComponent(title)}`, - '_blank', - ); - }, - icon: ( - <img - src="/assets/social/linkedin.svg" - alt="LinkedIn" - width={20} - height={20} - /> - ), - }, - { - name: 'Mastodon', - action: (url: string, title: string) => { - window.open( - `https://mastodon.social/share?text=${encodeURIComponent(title + ' ' + url)}`, - '_blank', - ); - }, - icon: ( - <img - src="/assets/social/mastodon.svg" - alt="Mastodon" - width={20} - height={20} - /> - ), - }, -]; - -const ShareModal: React.FC<ShareModalProps> = ({ - open, - onClose, - url, - title, - excerpt, -}) => { - if (!open) return null; - - const handleWebShare = () => { - if (navigator.share) { - navigator.share({ title, text: excerpt, url }); - onClose(); - } - }; - - return ( - <div className="fixed inset-0 z-50 flex items-center justify-center bg-transparent transition-all backdrop-blur-sm"> - <div className="relative w-full max-w-sm mx-auto bg-gradient-to-br from-blue-50 via-white to-green-50 rounded-2xl shadow-2xl p-7 animate-fadeIn border border-blue-100"> - <button - className="absolute top-4 right-4 text-gray-500 hover:text-blue-600 bg-white rounded-full shadow p-1 cursor-pointer transition-colors duration-200 border border-gray-200" - onClick={onClose} - aria-label="Close" - style={{ fontSize: 20, lineHeight: 1 }} - > - <svg - width="20" - height="20" - fill="none" - stroke="currentColor" - strokeWidth="2" - viewBox="0 0 24 24" - > - <line x1="18" y1="6" x2="6" y2="18" /> - <line x1="6" y1="6" x2="18" y2="18" /> - </svg> - </button> - <h3 className="text-xl font-bold mb-4 text-blue-700 text-center"> - Share this post - </h3> - <div className="mb-5 text-xs text-gray-700 bg-white border border-gray-100 rounded px-3 py-2 break-all text-center select-all"> - {url} - </div> - <div className="flex flex-col gap-3"> - {typeof navigator.share === 'function' && ( - <button - onClick={handleWebShare} - className="w-full py-2 px-4 rounded-xl bg-gradient-to-r from-blue-600 to-green-600 text-white font-semibold hover:from-blue-700 hover:to-green-700 shadow transition cursor-pointer" - style={{ fontSize: '1rem' }} - > - Share via Device... - </button> - )} - {shareOptions.map((opt) => ( - <button - key={opt.name} - onClick={() => opt.action(url, title)} - className="w-full flex items-center gap-3 py-2 px-4 rounded-xl border border-gray-200 bg-white hover:bg-gradient-to-r hover:from-blue-100 hover:to-green-100 hover:shadow-lg transition-all duration-200 cursor-pointer text-gray-700 font-medium" - style={{ fontSize: '1rem' }} - > - <span className="flex-shrink-0">{opt.icon}</span> - <span className="flex-1 text-left">{opt.name}</span> - </button> - ))} - </div> - </div> - </div> - ); -}; - -export default ShareModal; diff --git a/src/components/Stats.tsx b/src/components/Stats.tsx deleted file mode 100644 index ee85594f..00000000 --- a/src/components/Stats.tsx +++ /dev/null @@ -1,192 +0,0 @@ -import { motion } from 'framer-motion'; -import { stats, statisticsData } from '@/constants/Stats.ts'; -import { - headerReveal, - numberCounter, - imageReveal, - container, - item, -} from '@/styles/Animations'; - -const Stats = () => { - return ( - <section className="max-w-7xl mx-auto py-10 sm:py-16 md:py-20 px-4 sm:px-6 bg-white"> - <div className="relative mb-12 sm:mb-16 md:mb-24"> - <div className="absolute left-0 top-1/2 w-full h-0.5 sm:h-1 bg-gradient-to-r from-red-500 via-yellow-500 to-blue-500 transform -translate-y-1/2 opacity-30"></div> - - <motion.div - className="relative z-10 text-center mx-auto max-w-2xl bg-white px-2 py-2 sm:py-4" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.3 }} - > - <motion.h1 variants={headerReveal} className="text-center"> - <motion.span - className="block text-black font-Caveat text-5xl sm:text-6xl md:text-7xl mb-1 sm:mb-2" - variants={headerReveal} - custom={1} - > - What - </motion.span> - <motion.div - className="text-transparent bg-clip-text bg-gradient-to-r - from-red-500 to-orange-500 font-Pacifico text-4xl sm:text-5xl md:text-6xl mb-1 sm:mb-2" - variants={headerReveal} - custom={2} - > - numbers - </motion.div> - <motion.span - className="text-black italic font-serif text-2xl sm:text-3xl md:text-4xl" - variants={headerReveal} - custom={3} - > - say for us? - </motion.span> - </motion.h1> - - <motion.p - className="text-gray-600 text-base sm:text-lg md:text-xl leading-relaxed font-Roboto mt-4 sm:mt-6" - variants={headerReveal} - custom={4} - > - Sugar Labs, founded in 2008, has had{' '} - <span className="italic">an impact on the lives of many</span>. Here - are some of the statistics we are tracking - </motion.p> - </motion.div> - </div> - - <motion.div - className="mb-8 sm:mb-12 md:mb-16" - variants={container} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.1 }} - > - <motion.div - className="flex flex-col lg:flex-row items-center bg-gradient-to-r from-green-50 to-green-100 rounded-xl sm:rounded-2xl overflow-hidden shadow-lg sm:shadow-xl border border-green-200" - variants={item} - whileHover="hover" - > - <div className="w-full lg:w-1/2 p-5 sm:p-8 lg:p-12"> - <h3 className="text-gray-700 text-xl sm:text-2xl font-medium mb-3 sm:mb-4 font-AnonymousPro"> - Kids whose lives have been enriched by using the Sugar Learning - Platform. - </h3> - <motion.div - className="text-5xl sm:text-6xl md:text-7xl lg:text-8xl font-bold mb-4 sm:mb-8 bg-gradient-to-r from-green-600 to-green-700 bg-clip-text text-transparent font-Caveat" - variants={numberCounter} - > - 3,000,000+ - </motion.div> - <div className="w-24 sm:w-32 h-0.5 sm:h-1 bg-gradient-to-r from-green-600 to-green-400 rounded-full"></div> - </div> - - <motion.div - className="w-full lg:w-1/2 h-48 sm:h-56 md:h-64 lg:h-96 relative" - variants={imageReveal} - > - <img - src={stats.kidlaptop} - alt="Student with laptop" - className="w-full h-full object-cover object-center" - /> - <div className="absolute inset-0 bg-gradient-to-r from-green-600/20 to-transparent"></div> - </motion.div> - </motion.div> - </motion.div> - - {/* Stats Grid */} - <motion.div - className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6 md:gap-8" - variants={container} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.1 }} - > - {statisticsData.slice(1).map((stat, index) => ( - <motion.div - key={index} - className={`rounded-lg sm:rounded-xl overflow-hidden shadow-md sm:shadow-lg hover:shadow-xl transition-all duration-300 ${stat.bgColor} border ${stat.borderColor}`} - variants={item} - whileHover={{ y: -5, transition: { duration: 0.2 } }} - > - <motion.div - className="h-36 sm:h-40 md:h-48 relative overflow-hidden" - variants={imageReveal} - > - <img - src={stat.imageSrc} - alt={stat.imageAlt} - className="w-full h-full object-cover object-center" - /> - <div - className={`absolute inset-0 opacity-10 bg-gradient-to-br ${stat.gradient}`} - ></div> - </motion.div> - <div className="p-4 sm:p-5 md:p-6"> - <h3 className="text-gray-700 text-lg sm:text-xl font-medium mb-2 sm:mb-3 font-AnonymousPro line-clamp-2 h-12 sm:h-14"> - {stat.title} - </h3> - <motion.div - className={`text-4xl sm:text-5xl md:text-6xl font-bold mb-3 sm:mb-4 bg-gradient-to-r ${stat.gradient} bg-clip-text text-transparent font-Caveat`} - variants={numberCounter} - > - {stat.value} - </motion.div> - <div - className={`w-16 sm:w-20 md:w-24 h-0.5 sm:h-1 bg-gradient-to-r ${stat.gradient} opacity-50 rounded-full mt-1 sm:mt-2`} - ></div> - </div> - </motion.div> - ))} - </motion.div> - - {/* Closing Section with Interactive Element */} - <motion.div - className="text-center mt-10 sm:mt-12 md:mt-16 pt-8 sm:pt-12 md:pt-16 border-t border-gray-200" - initial={{ opacity: 0, y: 20 }} - whileInView={{ opacity: 1, y: 0 }} - transition={{ duration: 0.8 }} - viewport={{ once: true }} - > - <h2 className="text-2xl sm:text-3xl md:text-4xl font-bold text-gray-800 mb-4 sm:mb-6"> - Join us and make a difference - </h2> - <p className="text-gray-600 max-w-2xl mx-auto mb-6 sm:mb-8 md:mb-10 px-4 text-sm sm:text-base md:text-lg"> - These numbers represent more than statistics - they represent lives - changed through education and technology. Sugar Labs continues to grow - and impact communities worldwide. - </p> - - {/* Interactive Stats Summary - Grid Layout */} - <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-2 sm:gap-3 md:gap-4 max-w-6xl mx-auto px-2"> - {statisticsData.map((stat, index) => ( - <motion.div - key={index} - className={`px-2 sm:px-3 md:px-4 py-2 sm:py-3 rounded-md sm:rounded-lg ${stat.bgColor} border ${stat.borderColor} flex flex-col items-center justify-center`} - whileHover={{ - scale: 1.05, - boxShadow: '0 4px 12px rgba(0,0,0,0.1)', - }} - transition={{ type: 'spring', stiffness: 400, damping: 10 }} - > - <span - className={`font-bold text-transparent bg-clip-text bg-gradient-to-r ${stat.gradient} text-base sm:text-xl md:text-2xl`} - > - {stat.value} - </span> - <span className="text-gray-700 text-2xs sm:text-xs md:text-sm text-center mt-0.5 sm:mt-1 line-clamp-1"> - {stat.title.split('.')[0].substring(0, 12)} - {stat.title.split('.')[0].length > 12 ? '...' : ''} - </span> - </motion.div> - ))} - </div> - </motion.div> - </section> - ); -}; - -export default Stats; diff --git a/src/components/Testimonials.tsx b/src/components/Testimonials.tsx deleted file mode 100644 index c76a3157..00000000 --- a/src/components/Testimonials.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import { motion } from 'framer-motion'; -import { Marquee } from '@/components/magicui/Marquee'; // Marquee for scrolling effect -import { testimonials } from '@/constants/Testimonials'; -import { stats } from '@/constants/Stats'; -import { - testimonialCard, - testimonialHeading, - decorativeElement, - testimonialText, - avatarReveal, - marqueeContainer, -} from '@/styles/Animations'; - -const ReviewCard = ({ - img, - name, - username, - body, - delay = 0, -}: { - img: string; - name: string; - username: string; - body: string; - delay?: number; -}) => { - return ( - <motion.div - className="bg-white dark:bg-gray-900 rounded-xl p-6 flex flex-col items-center text-center min-h-[250px] h-auto w-[350px] shadow-lg border border-gray-200 dark:border-gray-700 mx-2 justify-between" - variants={testimonialCard} - initial="hidden" - whileInView="visible" - whileHover="hover" - viewport={{ once: true, amount: 0.1 }} - transition={{ delay }} - > - {/* Quote Icon */} - <motion.img - src={stats.apostrophie} - alt="double-quotes" - className="w-10 h-10 self-start opacity-70" - variants={decorativeElement} - /> - - {/* Feedback Text */} - <motion.p - className="text-gray-700 dark:text-gray-300 mt-2" - variants={testimonialText} - > - {body} - </motion.p> - - {/* User Info */} - <div className="flex items-center mt-4 space-x-3 text-left"> - <motion.img - src={img} - alt={name} - className="w-12 h-12 rounded-full border border-gray-300" - variants={avatarReveal} - /> - <motion.div variants={testimonialText}> - <h3 className="text-lg font-semibold text-gray-900 dark:text-white"> - {name} - </h3> - <p className="text-sm text-gray-500 dark:text-gray-400"> - @{username} - </p> - </motion.div> - </div> - </motion.div> - ); -}; - -export function Testimonials() { - const firstRow = testimonials.slice(0, Math.ceil(testimonials.length / 2)); - const secondRow = testimonials.slice(Math.ceil(testimonials.length / 2)); - - return ( - <div className="w-full bg-gradient-to-b from-white-800 to-[#F5DDC8]"> - {/* Heading Section with Hearts */} - <motion.div - className="flex items-center justify-center gap-4 md:gap-6 mb-12" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.6 }} - variants={marqueeContainer} - > - {/* Left Heart */} - <motion.img - src={stats.leftHeart} - alt="Heart Left" - className="w-8 md:w-12 lg:w-16 fill-current text-red-500 border-none shadow-none" - variants={decorativeElement} - animate="float" - custom={1} - /> - - <div className="relative flex items-center justify-center gap-4 md:gap-6 lg:gap-8"> - {/* Left Apostrophe (Hidden Below 400px) */} - <motion.img - src={stats.apostrophie} - alt="Apostrophe Left" - className="w-8 md:w-12 lg:w-16 -translate-y-2 block max-[400px]:hidden" - variants={decorativeElement} - custom={2} - /> - - {/* Heading */} - <motion.h2 - className="font-bold tracking-wider font-Caveat text-3xl md:text-5xl lg:text-6xl text-gray-800 text-center" - variants={testimonialHeading} - > - <span className="text-black"> - Words of appreciation and - <br /> admiration from others. - </span> - </motion.h2> - - {/* Right Apostrophe (Flipped, Hidden Below 400px) */} - <motion.img - src={stats.apostrophie} - alt="Apostrophe Right" - className="w-8 md:w-12 lg:w-16 -translate-y-2 scale-x-[-1] block max-[400px]:hidden" - variants={decorativeElement} - custom={3} - /> - </div> - - {/* Right Heart */} - <motion.img - src={stats.rightHeart} - alt="Heart Right" - className="w-8 md:w-12 lg:w-16 fill-current text-red-500 border-none shadow-none" - variants={decorativeElement} - animate="float" - custom={4} - /> - </motion.div> - - {/* Testimonials Section */} - <motion.div - className="relative flex flex-col items-center justify-center w-full overflow-hidden mt-6" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.1 }} - variants={marqueeContainer} - > - {/* First Row (left to right) */} - <Marquee pauseOnHover className="w-full"> - {firstRow.map((review, index) => ( - <ReviewCard - key={review.username} - {...review} - delay={index * 0.05} - /> - ))} - </Marquee> - - {/* Second Row (right to left) */} - <Marquee reverse pauseOnHover className="w-full mt-4"> - {secondRow.map((review, index) => ( - <ReviewCard - key={review.username} - {...review} - delay={index * 0.05} - /> - ))} - </Marquee> - - <div className="pointer-events-none absolute inset-y-0 left-0 w-6 md:w-10 bg-gradient-to-r from-background"></div> - <div className="pointer-events-none absolute inset-y-0 right-0 w-6 md:w-10 bg-gradient-to-l from-background"></div> - </motion.div> - </div> - ); -} diff --git a/src/components/Try.tsx b/src/components/Try.tsx deleted file mode 100644 index 9bb35277..00000000 --- a/src/components/Try.tsx +++ /dev/null @@ -1,405 +0,0 @@ -import React, { useState, useRef, TouchEvent } from 'react'; -import { TryCard, ActivityCard } from '@/components/TryCard'; -import { TryCardData, Activities } from '@/constants/TryCardData'; -import { motion } from 'framer-motion'; -import { - fadeIn, - slideInLeft, - slideInRight, - slideInBottom, - staggerContainer, - subtleRise, - headerReveal, -} from '@/styles/Animations'; - -const Try: React.FC = () => { - const [currentCard, setCurrentCard] = useState(0); - const [touchStart, setTouchStart] = useState<number>(0); - const [touchEnd, setTouchEnd] = useState<number>(0); - const [isDragging, setIsDragging] = useState(false); - const [currentActivity, setCurrentActivity] = useState(0); - const carouselRef = useRef<HTMLDivElement>(null); - const activityCarouselRef = useRef<HTMLDivElement>(null); - - const handleSwipe = ( - direction: 'next' | 'prev', - setCurrent: React.Dispatch<React.SetStateAction<number>>, - length: number, - ) => { - if (direction === 'next') { - setCurrent((prev) => (prev + 1) % length); - } else { - setCurrent((prev) => (prev - 1 + length) % length); - } - }; - - const handleTouchStart = (e: TouchEvent<HTMLDivElement>) => { - setTouchStart(e.targetTouches[0].clientX); - setIsDragging(true); - }; - - const handleTouchMove = (e: TouchEvent<HTMLDivElement>) => { - setTouchEnd(e.targetTouches[0].clientX); - }; - - const handleTouchEnd = ( - setCurrent: React.Dispatch<React.SetStateAction<number>>, - length: number, - ) => { - setIsDragging(false); - const swipeThreshold = 50; - const swipeDistance = touchStart - touchEnd; - - if (Math.abs(swipeDistance) > swipeThreshold) { - if (swipeDistance > 0) { - handleSwipe('next', setCurrent, length); - } else { - handleSwipe('prev', setCurrent, length); - } - } - }; - - return ( - <motion.div - className="min-h-screen flex flex-col" - initial="hidden" - animate="visible" - variants={fadeIn} - > - <motion.main className="flex-grow bg-[#F6DEC9] px-3 sm:px-4 md:px-8 lg:px-16 py-6 sm:py-8 md:py-12 lg:py-16"> - <div className="max-w-6xl mx-auto space-y-6 sm:space-y-8"> - <motion.header - className="space-y-3 sm:space-y-4 md:space-y-6" - variants={staggerContainer} - > - <motion.h1 - className="text-3xl sm:text-4xl md:text-5xl lg:text-7xl font-bold flex flex-col sm:flex-row items-start sm:items-center" - variants={headerReveal} - > - <motion.span - className="text-white bg-[#975555] px-2 py-1 rounded-lg inline-block" - variants={slideInLeft} - > - EXPERIENCE - </motion.span> - <motion.span - className="text-black sm:ml-2 mt-1 sm:mt-0" - variants={slideInRight} - > - SUGAR - </motion.span> - </motion.h1> - <motion.div - className="space-y-2 sm:space-y-3 md:space-y-4" - variants={subtleRise} - > - <motion.p - className="text-[#975555] text-xl sm:text-2xl md:text-3xl lg:text-4xl font-bold leading-tight" - variants={fadeIn} - > - "Our educational tools can be experienced in a number of ways. - Try the ones that are best for you!" - </motion.p> - <motion.i - className="text-xs md:text-sm text-gray-700 block" - variants={fadeIn} - > - Whether you enjoy hands-on activities, visual learning, or - interactive coding, there's something for everyone. Explore - creative tools, enhance your problem-solving skills, and make - learning more engaging. - </motion.i> - </motion.div> - </motion.header> - - {/* Desktop Grid */} - <div className="hidden md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 lg:gap-8"> - {TryCardData.map((card, index) => ( - <TryCard key={index} {...card} /> - ))} - </div> - - {/* Mobile Carousel */} - <div className="md:hidden -mx-3 sm:-mx-2"> - <div className="relative px-3 sm:px-4"> - <div - ref={carouselRef} - className="overflow-hidden touch-pan-x" - onTouchStart={handleTouchStart} - onTouchMove={handleTouchMove} - onTouchEnd={() => - handleTouchEnd(setCurrentCard, TryCardData.length) - } - > - <div - className={`flex transition-transform duration-300 ease-out`} - style={{ - transform: `translateX(-${currentCard * 100}%)`, - willChange: 'transform', - }} - > - {TryCardData.map((card, index) => ( - <div - key={index} - className="w-full flex-shrink-0 px-2" - style={{ scrollSnapAlign: 'start' }} - > - <div - className={` - transform transition-all duration-300 - ${isDragging ? 'scale-98' : 'hover:scale-102'} - `} - > - <TryCard {...card} /> - </div> - </div> - ))} - </div> - </div> - - {/* Navigation Buttons */} - <div className="absolute top-1/2 -translate-y-1/2 left-1 right-1 flex justify-between pointer-events-none"> - <button - onClick={() => - handleSwipe('prev', setCurrentCard, TryCardData.length) - } - className="pointer-events-auto p-2 sm:p-3 bg-white/80 text-[#975555] rounded-full shadow-lg hover:bg-white transition-all" - aria-label="Previous" - > - <svg - className="w-4 h-4 sm:w-5 sm:h-5 md:w-6 md:h-6" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M15 19l-7-7 7-7" - /> - </svg> - </button> - <button - onClick={() => - handleSwipe('next', setCurrentCard, TryCardData.length) - } - className="pointer-events-auto p-2 sm:p-3 bg-white/80 text-[#975555] rounded-full shadow-lg hover:bg-white transition-all" - aria-label="Next" - > - <svg - className="w-4 h-4 sm:w-5 sm:h-5 md:w-6 md:h-6" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M9 5l7 7-7 7" - /> - </svg> - </button> - </div> - </div> - - {/* Dots Indicator */} - <div className="flex justify-center space-x-1 sm:space-x-2 mt-4 sm:mt-6"> - {TryCardData.map((_, index) => ( - <button - key={index} - onClick={() => setCurrentCard(index)} - className={`w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full transition-all duration-300 ${ - currentCard === index - ? 'bg-[#975555] w-4 sm:w-6' - : 'bg-[#975555]/30' - }`} - aria-label={`Go to slide ${index + 1}`} - /> - ))} - </div> - </div> - </div> - - <motion.div - className="max-w-6xl mx-auto space-y-6 sm:space-y-8 mt-12 sm:mt-14 md:mt-16" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.1 }} - variants={slideInBottom} - > - <motion.header - className="space-y-3 sm:space-y-4 md:space-y-6" - variants={staggerContainer} - > - <motion.h1 - className="text-3xl sm:text-4xl md:text-5xl lg:text-7xl font-bold flex flex-col sm:flex-row items-start sm:items-center" - variants={headerReveal} - > - <motion.span - className="text-white bg-[#975555] px-2 py-1 rounded-lg inline-block" - variants={slideInLeft} - > - ALREADY USING - </motion.span> - <motion.span - className="text-black sm:ml-2 mt-1 sm:mt-0" - variants={slideInRight} - > - SUGAR? - </motion.span> - </motion.h1> - <motion.div - className="space-y-2 sm:space-y-3 md:space-y-4" - variants={subtleRise} - > - <motion.p - className="text-[#975555] text-xl sm:text-2xl md:text-3xl lg:text-4xl font-bold leading-tight" - variants={fadeIn} - > - "We have many activities for you!" - </motion.p> - <motion.i - className="text-xs md:text-sm text-gray-700 block" - variants={fadeIn} - > - The Sugar Learning platform is a complete environment for - teaching and learning, which includes individual activities. If - you're already using the Sugar Desktop Environment, then you can - install from the activities below, which has links to some of - our most popular activities. - </motion.i> - </motion.div> - </motion.header> - - {/* Desktop Grid */} - <div className="hidden md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 lg:gap-8"> - {Activities.map((activity, index) => ( - <ActivityCard - key={index} - title={activity.title} - description={activity.description} - icon={activity.icon} - buttonText={activity.buttonText} - href={activity.href} - version={activity.version} - /> - ))} - </div> - - {/* Mobile Carousel */} - <div className="md:hidden -mx-3 sm:-mx-2"> - <div className="relative px-3 sm:px-4"> - <div - ref={activityCarouselRef} - className="overflow-hidden touch-pan-x" - onTouchStart={handleTouchStart} - onTouchMove={handleTouchMove} - onTouchEnd={() => - handleTouchEnd(setCurrentActivity, Activities.length) - } - > - <div - className={`flex transition-transform duration-300 ease-out`} - style={{ - transform: `translateX(-${currentActivity * 100}%)`, - willChange: 'transform', - }} - > - {Activities.map((activity, index) => ( - <div - key={index} - className="w-full flex-shrink-0 px-2" - style={{ scrollSnapAlign: 'start' }} - > - <div - className={` - transform transition-all duration-300 - ${isDragging ? 'scale-98' : 'hover:scale-102'} - `} - > - <ActivityCard - title={activity.title} - description={activity.description} - icon={activity.icon} - buttonText={activity.buttonText} - href={activity.href} - version={activity.version} - /> - </div> - </div> - ))} - </div> - </div> - - {/* Navigation Buttons */} - <div className="absolute top-1/2 -translate-y-1/2 left-1 right-1 flex justify-between pointer-events-none"> - <button - onClick={() => - handleSwipe('prev', setCurrentActivity, Activities.length) - } - className="pointer-events-auto p-2 sm:p-3 bg-white/80 text-[#975555] rounded-full shadow-lg hover:bg-white transition-all" - aria-label="Previous" - > - <svg - className="w-4 h-4 sm:w-5 sm:h-5 md:w-6 md:h-6" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M15 19l-7-7 7-7" - /> - </svg> - </button> - <button - onClick={() => - handleSwipe('next', setCurrentActivity, Activities.length) - } - className="pointer-events-auto p-2 sm:p-3 bg-white/80 text-[#975555] rounded-full shadow-lg hover:bg-white transition-all" - aria-label="Next" - > - <svg - className="w-4 h-4 sm:w-5 sm:h-5 md:w-6 md:h-6" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M9 5l7 7-7 7" - /> - </svg> - </button> - </div> - </div> - - {/* Dots Indicator */} - <div className="flex justify-center space-x-1 sm:space-x-2 mt-4 sm:mt-6"> - {Activities.map((_, index) => ( - <button - key={index} - onClick={() => setCurrentActivity(index)} - className={`w-2 h-2 sm:w-2.5 sm:h-2.5 rounded-full transition-all duration-300 ${ - currentActivity === index - ? 'bg-[#975555] w-4 sm:w-6' - : 'bg-[#975555]/30' - }`} - aria-label={`Go to slide ${index + 1}`} - /> - ))} - </div> - </div> - </motion.div> - </motion.main> - </motion.div> - ); -}; - -export default Try; diff --git a/src/components/TryCard.tsx b/src/components/TryCard.tsx deleted file mode 100644 index 57195478..00000000 --- a/src/components/TryCard.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; - -interface TryCardProps { - title: string; - description: string; - tryNowText: string; - tryNowHref: string; - learnMoreText: string; - learnMoreHref: string; - imagePath: string; - gradientClass?: string; -} - -interface ActivityCardProps { - title: string; - description: string; - icon: string; - buttonText: string; - href: string; - version?: string; -} - -export const ActivityCard: React.FC<ActivityCardProps> = ({ - title, - description, - icon, - buttonText, - href, - version, -}) => ( - <div className="bg-white rounded-xl sm:rounded-3xl p-4 sm:p-6 md:p-8 flex flex-col items-center text-center shadow-lg transition-transform hover:scale-105"> - <img - src={icon} - alt={title} - className="flex-1/3 w-16 h-16 sm:w-20 sm:h-20 md:w-24 md:h-24 mb-3 sm:mb-4" - /> - <h3 className="text-xl sm:text-2xl md:text-3xl font-bold mb-1 sm:mb-2"> - {title} - </h3> - - {version && ( - <p - className={`text-xs sm:text-sm mb-1 sm:mb-2 px-4 py-1 rounded-full inline-block ml-auto font-medium ${ - version === 'v4' - ? 'bg-pink-100 text-pink-700' - : version === 'v3' - ? 'bg-cyan-100 text-cyan-700' - : 'bg-gray-100 text-gray-600' - }`} - > - {version} - </p> - )} - - <p className="text-gray-600 text-sm sm:text-base mb-4 sm:mb-6"> - {description} - </p> - - <a href={href} className="w-full"> - <button className="w-full py-2 sm:py-3 px-4 sm:px-6 border-2 border-gray-900 rounded-full text-sm sm:text-base md:text-lg font-semibold hover:bg-gray-900 cursor-pointer hover:text-white transition-colors"> - {buttonText} - </button> - </a> - </div> -); - -export const TryCard: React.FC<TryCardProps> = ({ - title, - description, - tryNowText, - tryNowHref, - learnMoreText, - learnMoreHref, - imagePath, - gradientClass, -}) => ( - <div className="bg-white rounded-xl sm:rounded-2xl md:rounded-3xl shadow-[rgba(13,_38,_76,_0.19)_0px_9px_20px] hover:shadow-[rgba(13,_38,_76,_0.25)_0px_12px_28px] transition-all duration-500 overflow-hidden mx-auto w-full group h-full"> - <div className="p-4 sm:p-5 md:p-6 flex flex-col h-full"> - {/* Content Section */} - <div className="flex-1 flex flex-col space-y-3 sm:space-y-4"> - {/* Header */} - <div className="space-y-2 flex-1/4 sm:space-y-3 text-center w-full"> - <h2 className="text-lg sm:text-xl font-black text-gray-800 leading-tight bg-gradient-to-br from-gray-900 via-gray-800 to-gray-600 bg-clip-text group-hover:scale-[1.02] transition-transform duration-500"> - {title} - </h2> - <p className="text-gray-500 text-xs sm:text-sm leading-relaxed mx-auto font-medium tracking-wide"> - {description} - </p> - </div> - - {/* Buttons */} - <div className="space-y-2 sm:space-y-2.5 flex flex-col items-center pt-1 sm:pt-3"> - <a - href={tryNowHref} - className={`w-full text-white font-bold px-3 sm:px-4 md:px-5 py-2 sm:py-2.5 md:py-3 rounded-xl sm:rounded-2xl - transition-all duration-500 hover:scale-[1.02] hover:shadow-lg - active:scale-95 text-xs sm:text-sm backdrop-blur-sm relative overflow-hidden - ${gradientClass || 'bg-gradient-to-br from-blue-600 via-blue-700 to-blue-800'} - before:absolute before:inset-0 before:bg-white/20 before:translate-x-[-150%] before:skew-x-[45deg] - hover:before:translate-x-[150%] before:transition-transform before:duration-700 - `} - > - {tryNowText} - </a> - <Link - to={learnMoreHref} - className="w-full bg-gray-50/80 backdrop-blur-sm border-[1.5px] border-gray-100 rounded-xl sm:rounded-2xl px-3 sm:px-4 md:px-5 py-2 sm:py-2.5 md:py-3 - font-bold transition-all duration-500 hover:scale-[1.02] - hover:bg-gray-100/80 hover:border-gray-200 text-gray-700 text-xs sm:text-sm - active:scale-95 relative overflow-hidden - before:absolute before:inset-0 before:bg-gray-400/20 before:translate-x-[-150%] before:skew-x-[45deg] - hover:before:translate-x-[150%] before:transition-transform before:duration-700" - > - {learnMoreText} - </Link> - </div> - </div> - - {/* Image Section */} - <div className="-mx-4 sm:-mx-5 md:-mx-6 -mb-4 sm:-mb-5 md:-mb-6 mt-4 sm:mt-5 md:mt-6 relative overflow-hidden"> - <div className="absolute inset-0 bg-gradient-to-b from-white via-white/50 to-transparent h-8 sm:h-10 md:h-12 z-10" /> - <img - src={imagePath} - alt={title} - className="w-full h-36 sm:h-40 md:h-48 object-cover transform transition-all duration-700 - group-hover:scale-110 group-hover:rotate-1" - /> - <div className="absolute inset-0 bg-gradient-to-t from-black/20 to-transparent" /> - </div> - </div> - </div> -); diff --git a/src/components/TryMore3D.tsx b/src/components/TryMore3D.tsx deleted file mode 100644 index cf480494..00000000 --- a/src/components/TryMore3D.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import { Marquee } from '@/components/magicui/Marquee'; -import { - firstRow, - secondRow, - thirdRow, - fourthRow, -} from '@/constants/TryMore3D'; -import { motion } from 'framer-motion'; -import { - slideInLeft, - staggerContainer, - bounce, - fadeIn, - headerReveal, -} from '@/styles/Animations'; - -const ReviewCard = ({ - img, - title, - description, - buttonText, -}: { - img: string; - title: string; - description: string; - buttonText: string; -}) => { - return ( - <figure className="relative h-full w-36 cursor-pointer overflow-hidden rounded-xl border p-4 border-gray-950/[.1] bg-gray-950/[.01] hover:bg-gray-950/[.05] dark:border-gray-50/[.1] dark:bg-gray-50/[.10] dark:hover:bg-gray-50/[.15] flex flex-col items-center text-center"> - {/* SVG Icon */} - <img className="w-12 h-12 mb-2" alt={title} src={img} /> - - {/* Title */} - <figcaption className="text-lg font-semibold dark:text-white"> - {title} - </figcaption> - - {/* Description */} - <p className="text-xs font-medium dark:text-white/40">{description}</p> - - {/* Button */} - <button className="mt-4 px-3 py-1 border rounded-lg border-gray-950 dark:border-gray-50 text-sm font-medium dark:text-white"> - {buttonText} - </button> - </figure> - ); -}; - -export function TryMore() { - return ( - <div className="relative flex flex-col lg:flex-row h-auto lg:h-96 w-full items-center justify-center gap-6 lg:gap-4 overflow-hidden [perspective:300px] px-4 sm:px-6 md:px-10 lg:pl-20 bg-gradient-to-b from-[#F5DDC8] to-white-800"> - <div className="height- 30px"></div> - - {/* Left Side Content */} - <motion.div - className="w-full lg:w-1/2 text-center lg:text-left" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.3 }} - variants={staggerContainer} - > - <motion.h2 - className="text-3xl sm:text-4xl font-extrabold text-[#975555] dark:text-[#975555]" - variants={headerReveal} - > - <motion.span variants={slideInLeft} custom={0}> - Check out the <br className="hidden lg:block" /> - </motion.span> - <motion.span variants={slideInLeft} custom={1}> - remaining hundreds <br className="hidden lg:block" /> - </motion.span> - <motion.span variants={slideInLeft} custom={2}> - of activities! - </motion.span> - </motion.h2> - <motion.p - className="mt-4 text-base sm:text-lg text-gray-700 dark:text-gray-300" - variants={fadeIn} - custom={3} - > - Important: Please know that in order to install and try them, you need - to be running the Sugar Desktop Environment. If you don't have that - already, please reconsider your other options to explore Sugar. Try - Sugar! - </motion.p> - <motion.a - href="https://v4.activities.sugarlabs.org/" - target="_blank" - rel="noopener noreferrer" - > - <motion.button - className="mt-6 px-6 py-3 bg-indigo-600 text-white font-medium rounded-lg hover:bg-indigo-700 transition" - variants={bounce} - custom={4} - whileHover={{ - scale: 1.05, - backgroundColor: '#4338ca', - boxShadow: - '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', - }} - whileTap={{ scale: 0.95 }} - > - Go to Sugar Activity page - </motion.button> - </motion.a> - </motion.div> - - {/* Marquee Section */} - <div - className="flex flex-col lg:flex-row items-center gap-4 max-[1040px]:hidden" - style={{ - transform: - 'translateX(0px) translateY(0px) translateZ(0px) rotateX(10deg) rotateY(-5deg) rotateZ(10deg)', - }} - > - <Marquee - pauseOnHover - vertical - className="[--duration:20s] w-full lg:w-auto" - > - {firstRow.map((review) => ( - <ReviewCard key={review.title} {...review} /> - ))} - </Marquee> - <Marquee - reverse - pauseOnHover - vertical - className="[--duration:20s] w-full lg:w-auto" - > - {secondRow.map((review) => ( - <ReviewCard key={review.title} {...review} /> - ))} - </Marquee> - <Marquee - reverse - pauseOnHover - vertical - className="[--duration:20s] w-full lg:w-auto" - > - {thirdRow.map((review) => ( - <ReviewCard key={review.title} {...review} /> - ))} - </Marquee> - <Marquee - pauseOnHover - vertical - className="[--duration:20s] w-full lg:w-auto" - > - {fourthRow.map((review) => ( - <ReviewCard key={review.title} {...review} /> - ))} - </Marquee> - </div> - <div className="height- 20px"></div> - </div> - ); -} diff --git a/src/components/TryNow/FeatureSection.tsx b/src/components/TryNow/FeatureSection.tsx deleted file mode 100644 index 8a9f71f8..00000000 --- a/src/components/TryNow/FeatureSection.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { useState } from 'react'; -import { motion } from 'framer-motion'; -import { Carousel } from 'react-responsive-carousel'; -import 'react-responsive-carousel/lib/styles/carousel.min.css'; -import { featureSectionAnimations } from '@/styles/Animations'; - -interface FeatureData { - title: string; - subtitle: string; - quote: string; - description: string; - images?: { src: string; alt: string }[]; - note?: string; -} - -const FeatureSection = ({ data }: { data: FeatureData }) => { - const [currentImage, setCurrentImage] = useState(0); - - return ( - <motion.section - className="w-[90%] mx-auto py-10 flex flex-col md:flex-row items-center gap-10" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - variants={featureSectionAnimations.section} - > - {/* Left Side: Text Content */} - <motion.div - className="md:w-1/2 text-center md:text-left" - variants={featureSectionAnimations.textContainer} - > - <h1 className="text-5xl font-bold text-blue-600">{data.title}</h1> - <h2 className="text-4xl font-bold text-black mt-2">{data.subtitle}</h2> - <p className="text-lg font-semibold mt-4">{data.quote}</p> - <p className="text-gray-700 mt-4">{data.description}</p> - </motion.div> - - {/* Right Side: Image Carousel */} - <motion.div - className="md:w-1/2 flex flex-col justify-center items-center relative" - variants={featureSectionAnimations.imageContainer} - > - {data.images && data.images.length > 0 ? ( - <Carousel - selectedItem={currentImage} - onChange={(index) => setCurrentImage(index)} - showThumbs={false} - showStatus={false} - infiniteLoop - autoPlay - interval={3000} - transitionTime={600} - emulateTouch - dynamicHeight - > - {data.images.map((image, index) => ( - <motion.div key={index} className="w-full max-w-lg"> - <motion.img - src={image.src} - alt={image.alt} - className="w-full rounded-lg shadow-md" - initial="hidden" - animate="visible" - whileHover="hover" - variants={featureSectionAnimations.image} - /> - </motion.div> - ))} - </Carousel> - ) : ( - <motion.div - className="w-full max-w-lg h-64 bg-gray-300 rounded-lg flex items-center justify-center" - initial="hidden" - animate="visible" - variants={featureSectionAnimations.image} - > - <p className="text-gray-500">No Image Available</p> - </motion.div> - )} - </motion.div> - - {/* Optional Note */} - {data.note && ( - <motion.p - className="text-black font-bold mt-6 text-center w-full" - initial="hidden" - whileInView="visible" - viewport={{ once: true }} - variants={featureSectionAnimations.note} - > - {data.note} - </motion.p> - )} - </motion.section> - ); -}; - -export default FeatureSection; diff --git a/src/components/TryNow/LogoCards.tsx b/src/components/TryNow/LogoCards.tsx deleted file mode 100644 index 988a492b..00000000 --- a/src/components/TryNow/LogoCards.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { motion } from 'framer-motion'; -import { logoCardAnimations } from '@/styles/Animations'; - -interface LogoCard { - logo: string; - title: string; - description: string[]; - buttons?: { text: string; link: string }[]; -} - -const LogoCards = ({ data }: { data: LogoCard[] }) => { - return ( - <section className="w-[90%] mx-auto py-6 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6"> - {data.map((card, index) => ( - <motion.div - key={index} - className="bg-white shadow-lg rounded-xl p-6 flex flex-col items-center text-center border border-blue-500" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - variants={logoCardAnimations.card} - custom={index} - whileHover="hover" - > - {/* Logo */} - <motion.div - className="w-24 h-24 bg-yellow-300 flex items-center justify-center rounded-full" - whileHover="hover" - variants={logoCardAnimations.logoContainer} - > - <img src={card.logo} alt={card.title} className="w-12 h-12" /> - </motion.div> - - {/* Title */} - <h3 className="text-xl font-bold text-blue-600 mt-4">{card.title}</h3> - - {/* Divider */} - <hr className="w-full my-3 border-gray-300" /> - - {/* Description */} - <ul className="text-gray-600 text-sm text-left list-disc list-inside"> - {card.description.map((point, i) => ( - <li key={i}>{point}</li> - ))} - </ul> - - {/* Buttons */} - {card.buttons && ( - <div className="mt-4 flex flex-wrap gap-2 justify-center"> - {card.buttons.map((btn, i) => ( - <motion.a - key={i} - href={btn.link} - target="_blank" - rel="noopener noreferrer" - className="px-4 py-2 bg-blue-600 text-white font-bold rounded-full shadow-md hover:bg-blue-700 transition duration-200" - whileHover="hover" - whileTap="tap" - variants={logoCardAnimations.button} - > - {btn.text} - </motion.a> - ))} - </div> - )} - </motion.div> - ))} - </section> - ); -}; - -export default LogoCards; diff --git a/src/components/TryNow/NumberedCard.tsx b/src/components/TryNow/NumberedCard.tsx deleted file mode 100644 index a5517b39..00000000 --- a/src/components/TryNow/NumberedCard.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React from 'react'; -import { motion } from 'framer-motion'; -import { numberedCardAnimations } from '@/styles/Animations'; - -interface NumberedCardProps { - number: string; - title: string; - description: string; - image?: string; - borderColor: string; - link?: string; -} - -const NumberedCard: React.FC<NumberedCardProps> = ({ - number, - title, - description, - image, - borderColor, - link, -}) => { - return ( - <motion.a - href={link} - target="_blank" - rel="noopener noreferrer" - className="relative flex flex-col items-center text-center p-6 rounded-2xl shadow-md cursor-pointer no-underline" - style={{ border: `2px solid ${borderColor}` }} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - variants={numberedCardAnimations.card} - whileHover="hover" - > - {/* Number Circle */} - <motion.div - className="absolute -top-6 w-12 h-12 flex items-center justify-center rounded-full text-white text-xl font-bold" - style={{ backgroundColor: borderColor }} - variants={numberedCardAnimations.numberCircle} - > - {number} - </motion.div> - - {/* Title */} - <h3 className="text-lg font-semibold mt-6">{title}</h3> - - {/* Description */} - <p className="text-gray-700 mt-2">{description}</p> - - {/* Conditionally Render Image */} - {image && ( - <motion.img - src={image} - alt={title} - className="w-full h-auto mt-4 rounded-lg" - variants={numberedCardAnimations.image} - /> - )} - </motion.a> - ); -}; - -export default NumberedCard; diff --git a/src/components/TryNow/Paragraph.tsx b/src/components/TryNow/Paragraph.tsx deleted file mode 100644 index 6c2fb53a..00000000 --- a/src/components/TryNow/Paragraph.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import React from 'react'; -import { motion } from 'framer-motion'; -import { paragraphAnimations } from '@/styles/Animations'; -import DOMPurify from 'dompurify'; -import { renderContentWithLinks } from '@/utils/renderlinks-utils'; - -interface ParagraphProps { - title: string; - content: string; - button?: string | null; - buttonLink?: string | URL; - links?: { text: string; url: string }[] | null; -} - -const Paragraph: React.FC<ParagraphProps> = ({ - title, - content, - button, - buttonLink, - links, -}) => { - const contentPoints = content.includes('\n') - ? content.split('\n') - : [content]; - - return ( - <motion.section - className="w-[90%] mx-auto text-center my-10" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - variants={paragraphAnimations.section} - > - {/* Styled Title */} - <motion.h2 - className="text-4xl font-semibold border-b-2 border-gray-300 inline-block pb-2 font-[Caveat]" - variants={paragraphAnimations.text} - > - {title} - </motion.h2> - - {/* Render Content as a List if Multiple Lines Exist */} - {contentPoints.length > 1 ? ( - <ul className="text-gray-700 mt-4 list-disc list-inside text-left"> - {contentPoints.map((point, index) => ( - <motion.li - key={index} - className="mb-2" - custom={index} - variants={paragraphAnimations.listItem(index)} - > - <span - dangerouslySetInnerHTML={{ - __html: DOMPurify.sanitize( - renderContentWithLinks(point.trim(), links), - ), - }} - /> - </motion.li> - ))} - </ul> - ) : ( - <motion.p - className="text-gray-700 mt-4" - variants={paragraphAnimations.text} - > - <span - dangerouslySetInnerHTML={{ - __html: DOMPurify.sanitize( - renderContentWithLinks(content, links), - ), - }} - /> - </motion.p> - )} - - {/* Conditional Button Rendering */} - {button && ( - <motion.button - className="mt-4 bg-blue-600 text-white font-bold py-2 px-6 rounded-full shadow-lg hover:bg-blue-700 transition" - whileHover="hover" - variants={paragraphAnimations.button} - onClick={() => window.open(buttonLink, '_blank')} - > - {button} - </motion.button> - )} - </motion.section> - ); -}; - -export default Paragraph; diff --git a/src/components/TryNow/StepsToUse.tsx b/src/components/TryNow/StepsToUse.tsx deleted file mode 100644 index 9f752c9d..00000000 --- a/src/components/TryNow/StepsToUse.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import 'react-responsive-carousel'; -import { Carousel } from 'react-responsive-carousel'; -import { steps } from '@/constants/TryNowData/bootableSoasData'; -import { useState } from 'react'; -import DOMPurify from 'dompurify'; -import { renderContentWithLinks } from '@/utils/renderlinks-utils'; - -const StepsToUse = () => { - const [currentStep, setCurrentStep] = useState(0); - - return ( - <section className="w-[90%] mx-auto py-8"> - <h2 className="text-3xl font-bold text-center text-black mb-6"> - Steps to Boot Sugar on a Stick - </h2> - - <div className="relative w-full sm:w-[80%] md:w-[70%] lg:w-[60%] mx-auto"> - <Carousel - selectedItem={currentStep} - onChange={(index) => setCurrentStep(index)} - showArrows={false} - showThumbs={false} - showStatus={false} - showIndicators={true} - useKeyboardArrows - infiniteLoop - > - {steps.map((step, index) => ( - <div key={index} className="relative text-center"> - {/* TEXT CONTENT */} - <div className="text-lg font-semibold text-gray-600"> - Step {index + 1} - </div> - <h3 className="text-2xl font-semibold text-black mt-1"> - {step.title} - </h3> - <p - className="text-gray-700 mt-2" - dangerouslySetInnerHTML={{ - __html: DOMPurify.sanitize( - renderContentWithLinks(step.description, step.links), - ), - }} - /> - - {/* IMAGE + HOVER ARROWS */} - <div className="relative group mx-auto mt-4 rounded-lg shadow-lg overflow-hidden"> - <img - src={step.image} - alt={step.title} - className="w-full h-auto rounded-lg" - /> - - {/* LEFT HOVER AREA */} - {index > 0 && ( - <div - className="absolute left-0 top-0 h-full w-1/4 bg-gradient-to-r from-black/30 to-transparent opacity-0 group-hover:opacity-100 transition-all duration-300 cursor-pointer z-10" - onClick={() => setCurrentStep(currentStep - 1)} - > - <div className="absolute left-2 top-1/2 transform -translate-y-1/2 w-0 h-0 border-t-8 border-b-8 border-r-8 border-transparent border-r-white"></div> - </div> - )} - - {/* RIGHT HOVER AREA */} - {index < steps.length - 1 && ( - <div - className="absolute right-0 top-0 h-full w-1/4 bg-gradient-to-l from-black/30 to-transparent opacity-0 group-hover:opacity-100 transition-all duration-300 cursor-pointer z-10" - onClick={() => setCurrentStep(currentStep + 1)} - > - <div className="absolute right-2 top-1/2 transform -translate-y-1/2 w-0 h-0 border-t-8 border-b-8 border-l-8 border-transparent border-l-white"></div> - </div> - )} - </div> - </div> - ))} - </Carousel> - </div> - </section> - ); -}; - -export default StepsToUse; diff --git a/src/components/TryNow/TeamSection.tsx b/src/components/TryNow/TeamSection.tsx deleted file mode 100644 index aa4e835e..00000000 --- a/src/components/TryNow/TeamSection.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React from 'react'; -import { motion } from 'framer-motion'; -import { teamSectionAnimations } from '@/styles/Animations'; - -interface TeamMember { - name: string; - role: string; - description: string; - image: string; - bgColor: string; -} - -const TeamSection: React.FC<{ members: TeamMember[] }> = ({ members }) => { - return ( - <motion.section - className="w-[90%] mx-auto text-center py-12" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - variants={teamSectionAnimations.section} - > - {/* Title */} - <motion.h1 - className="text-5xl font-[Caveat] font-bold" - variants={teamSectionAnimations.heading} - > - Music Blocks Offline Edition - </motion.h1> - - <motion.h2 - className="text-4xl font-[Caveat] font-bold mt-2" - variants={teamSectionAnimations.heading} - > - and <br /> Curriculum Development Team - </motion.h2> - - <motion.hr - className="w-24 border-t-2 border-gray-500 mx-auto mt-4" - variants={teamSectionAnimations.heading} - /> - - {/* Grid Layout for Members */} - <motion.div - className="grid md:grid-cols-2 gap-10 mt-12 bg-gray-100 p-10 rounded-lg" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - variants={teamSectionAnimations.section} - > - {members.map((member, index) => ( - <motion.div - key={index} - className="flex flex-col md:flex-row items-center bg-white shadow-lg rounded-lg p-6" - variants={teamSectionAnimations.memberCard} - > - {/* Member Image */} - <motion.img - src={member.image} - alt={member.name} - className="w-32 h-32 rounded-full object-cover border-4 border-gray-300" - variants={teamSectionAnimations.memberImage} - /> - - {/* Member Info */} - <div className="md:ml-6 text-left mt-4 md:mt-0"> - <h3 - className="text-lg font-bold px-3 py-1 rounded-lg inline-block" - style={{ backgroundColor: member.bgColor }} - > - {member.name} - </h3> - <p className="text-gray-700 mt-2">{member.description}</p> - </div> - </motion.div> - ))} - </motion.div> - </motion.section> - ); -}; - -export default TeamSection; diff --git a/src/components/magicui/Marquee.tsx b/src/components/magicui/Marquee.tsx deleted file mode 100644 index 7a959d2a..00000000 --- a/src/components/magicui/Marquee.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { cn } from '@/lib/utils'; -import { ComponentPropsWithoutRef } from 'react'; - -interface MarqueeProps extends ComponentPropsWithoutRef<'div'> { - /** - * Optional CSS class name to apply custom styles - */ - className?: string; - /** - * Whether to reverse the animation direction - * @default false - */ - reverse?: boolean; - /** - * Whether to pause the animation on hover - * @default false - */ - pauseOnHover?: boolean; - /** - * Content to be displayed in the marquee - */ - children: React.ReactNode; - /** - * Whether to animate vertically instead of horizontally - * @default false - */ - vertical?: boolean; - /** - * Number of times to repeat the content - * @default 4 - */ - repeat?: number; -} - -export function Marquee({ - className, - reverse = false, - pauseOnHover = false, - children, - vertical = false, - repeat = 4, - ...props -}: MarqueeProps) { - return ( - <div - {...props} - className={cn( - 'group flex overflow-hidden p-2 [--duration:40s] [--gap:1rem] [gap:var(--gap)]', - { - 'flex-row': !vertical, - 'flex-col': vertical, - }, - className, - )} - > - {Array(repeat) - .fill(0) - .map((_, i) => ( - <div - key={i} - className={cn('flex shrink-0 justify-around [gap:var(--gap)]', { - 'animate-marquee flex-row': !vertical, - 'animate-marquee-vertical flex-col': vertical, - 'group-hover:[animation-play-state:paused]': pauseOnHover, - '[animation-direction:reverse]': reverse, - })} - > - {children} - </div> - ))} - </div> - ); -} diff --git a/src/components/shared/NavigationLinks.tsx b/src/components/shared/NavigationLinks.tsx deleted file mode 100644 index a257d1d7..00000000 --- a/src/components/shared/NavigationLinks.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import { useEffect, useState, useRef } from 'react'; -import { - navigationSections, - navigationConfig, - navigationStyles, -} from '@/constants/aboutUs/navigation'; - -const NavigationLinks = () => { - const [activeSection, setActiveSection] = useState( - navigationConfig.defaultActiveSection, - ); - const [lastClickedSection, setLastClickedSection] = useState(''); - const foundSections = useRef<Record<string, boolean>>({}); - - useEffect(() => { - console.log('Checking for all section elements...'); - - navigationSections.forEach((section) => { - const element = document.getElementById(section.id); - foundSections.current[section.id] = !!element; - - if (!element) { - console.warn( - `Section with ID "${section.id}" not found in the document!`, - ); - } else { - console.log(`Found section: ${section.id}`); - } - }); - }, []); - - useEffect(() => { - const handleScroll = () => { - const sectionElements = navigationSections.map((section) => ({ - id: section.id, - element: document.getElementById(section.id), - })); - - const currentSection = sectionElements.find((section) => { - if (!section.element) return false; - - const rect = section.element.getBoundingClientRect(); - return ( - rect.top <= navigationConfig.activeDetectionOffset && - rect.bottom >= 50 - ); - }); - - const roadmapSection = sectionElements.find( - (s) => s.id === 'roadmap' && s.element, - ); - const isNearBottom = - window.innerHeight + window.scrollY >= document.body.offsetHeight - 100; - - if (isNearBottom && roadmapSection && roadmapSection.element) { - setActiveSection('roadmap'); - } else if (currentSection) { - setActiveSection(currentSection.id); - } else if (lastClickedSection) { - setActiveSection(lastClickedSection); - } - }; - - handleScroll(); - - window.addEventListener('scroll', handleScroll); - window.addEventListener('resize', handleScroll); - - return () => { - window.removeEventListener('scroll', handleScroll); - window.removeEventListener('resize', handleScroll); - }; - }, [lastClickedSection]); - - const scrollToSection = (sectionId: string) => { - let element = document.getElementById(sectionId); - - setLastClickedSection(sectionId); - setActiveSection(sectionId); - - if (!element && sectionId === 'roadmap') { - const alternativeIds = ['road-map', 'road_map', 'Roadmap', 'ROADMAP']; - - for (const altId of alternativeIds) { - element = document.getElementById(altId); - if (element) { - console.log(`Found roadmap with alternative ID: ${altId}`); - break; - } - } - - if (!element) { - const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); - for (const heading of headings) { - if (heading.textContent?.toLowerCase().includes('roadmap')) { - element = - heading.closest('section') || - heading.closest('div') || - heading.parentElement; - console.log('Found roadmap section via heading text'); - break; - } - } - } - - if (!element) { - console.log( - 'Roadmap section not found - scrolling to bottom of the page', - ); - window.scrollTo({ - top: document.documentElement.scrollHeight, - behavior: 'smooth', - }); - return; - } - } - - if (element) { - const navBar = document.querySelector('header, nav:first-of-type'); - const offsetTop = navBar ? navBar.getBoundingClientRect().height : 0; - window.scrollTo({ - top: element.offsetTop - offsetTop - navigationConfig.scrollOffset, - behavior: 'smooth', - }); - } else { - console.error( - `Section with ID "${sectionId}" not found in the document!`, - ); - } - }; - - return ( - <nav - className={navigationStyles.container} - style={{ top: `${navigationConfig.stickyTopPosition}px` }} - > - <ul className={navigationStyles.list}> - {navigationSections.map(({ id, label }) => ( - <li key={id}> - <button - onClick={() => scrollToSection(id)} - className={` - ${navigationStyles.button.base} - ${ - activeSection === id - ? navigationStyles.button.active - : navigationStyles.button.inactive - } - `} - > - {label} - <span - className={` - ${navigationStyles.indicator.base} - ${ - activeSection === id - ? navigationStyles.indicator.active - : navigationStyles.indicator.inactive - } - `} - /> - </button> - </li> - ))} - </ul> - </nav> - ); -}; - -export default NavigationLinks; diff --git a/src/components/shared/SectionContainer.tsx b/src/components/shared/SectionContainer.tsx deleted file mode 100644 index 130d8d87..00000000 --- a/src/components/shared/SectionContainer.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { motion } from 'framer-motion'; -import { ReactNode } from 'react'; - -interface SectionContainerProps { - id: string; - children: ReactNode; - reverse?: boolean; -} - -const SectionContainer = ({ - id, - children, - reverse = false, -}: SectionContainerProps) => { - return ( - <motion.section - id={id} - className={`flex flex-col ${reverse ? 'md:flex-row-reverse' : 'md:flex-row'} gap-12 items-start py-16 px-4 md:px-8`} - initial="hidden" - whileInView="visible" - viewport={{ once: true, margin: '-100px' }} - variants={{ - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { - staggerChildren: 0.2, - delayChildren: 0.1, - }, - }, - }} - > - {children} - </motion.section> - ); -}; - -export default SectionContainer; diff --git a/src/components/shared/SectionTitle.tsx b/src/components/shared/SectionTitle.tsx deleted file mode 100644 index 2a82fac5..00000000 --- a/src/components/shared/SectionTitle.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { motion } from 'framer-motion'; -import { ReactNode } from 'react'; - -const fadeInUp = { - hidden: { opacity: 0, y: 20 }, - visible: { opacity: 1, y: 0, transition: { duration: 0.6 } }, -}; - -interface SectionTitleProps { - children: ReactNode; -} - -const SectionTitle = ({ children }: SectionTitleProps) => { - return ( - <motion.h3 - className="text-3xl md:text-4xl font-bold mb-6" - variants={fadeInUp} - > - {children} - </motion.h3> - ); -}; - -export default SectionTitle; diff --git a/src/constants/Banner.ts b/src/constants/Banner.ts deleted file mode 100644 index a37c090d..00000000 --- a/src/constants/Banner.ts +++ /dev/null @@ -1,79 +0,0 @@ -export interface BannerConfig { - title: string; - description?: string; - buttonText: string; - buttonLink: string; - theme?: 'primary' | 'success' | 'warning' | 'sale' | 'info'; - isExternalLink?: boolean; -} - -export interface IconProps { - theme: 'primary' | 'success' | 'warning' | 'sale' | 'info'; -} - -export const bannerConfigs = { - donation: { - title: 'Help us reach our next fundraising milestone.', - description: - 'Through every.org, we accept donations via credit card, ACH, PayPal, crypto, stocks, DAF, and Venmo.', - buttonText: 'Donate Now', - buttonLink: '/donate', - theme: 'primary' as const, - }, - - sale: { - title: 'Have you seen our merchandise?', - description: - 'Check out t-shirts, hoodies, and bootable USB sticks, all with the official Sugar Labs logo.', - buttonText: 'Shop Now', - buttonLink: '/products', - theme: 'info' as const, - }, - - limitedOffer: { - title: 'Interested in joining the community?', - description: - 'Learn more about the first steps to volunteering for Sugar Labs.', - buttonText: 'Learn more', - buttonLink: '/volunteer', - theme: 'info' as const, - }, - - announcement: { - title: 'This is our new website!', - description: - "We've launched our new website. If you found something missing, please let us know in a GitHub issue.", - buttonText: 'Report an issue', - buttonLink: 'https://github.com/sugarlabs/www-v2', - theme: 'info' as const, - isExternalLink: true, - }, - - successStory: { - title: - 'Learn more about Sugar Labs through a Sugar Story, told by members of our community.', - description: - '"Sugar Stories" are stories told by members of the Sugar Labs community.', - buttonText: 'Read Story', - buttonLink: '/news/sugar-stories', - theme: 'success' as const, - }, - - webinar: { - title: 'Live online events', - description: - 'Join us Fridays, starting 4/25/25 at 17:00 UTC (1:00pm EDT) to celebrate our website launch and learn more about Sugar Labs.', - buttonText: 'Subscribe for reminders', - buttonLink: 'https://www.youtube.com/@SugarlabsOrg-EN', - theme: 'info' as const, - isExternalLink: true, - }, - - feedback: { - title: 'We value your feedback', - description: 'Take our short survey and help us improve your experience.', - buttonText: 'Give Feedback', - buttonLink: '/contact-us', - theme: 'info' as const, - }, -}; diff --git a/src/constants/Donation.ts b/src/constants/Donation.ts deleted file mode 100644 index 747d0184..00000000 --- a/src/constants/Donation.ts +++ /dev/null @@ -1,69 +0,0 @@ -import Image from '/assets/Images/DonatePic.png'; -import Arrow from '/assets/Icons/arrow.svg'; -import PdfIcon from '/assets/Icons/pdf-icon.svg'; - -interface donationData { - heading: string; - subHeading: string; - paragraph: string; - url: string; - urlMonth: string; - buttonText: string; -} - -export const Img = [Image, Arrow, PdfIcon]; - -export const donationData: donationData = { - heading: 'Support and Empower Those in Need', - paragraph: - "Support Sugar Labs and make a difference in children's education. Sugar Labs has brought educational software and authentic problem-solving to millions in the US and across the globe.", - subHeading: 'Donate to Sugar Labs to make a positive impact', - url: 'https://www.every.org/sugar-labs?suggestedAmounts=17,37,57&frequency=ONCE#donate', - urlMonth: - 'https://www.every.org/sugar-labs?suggestedAmounts=17,37,57&frequency=MONTHLY#donate', - buttonText: 'Donate now', -}; - -export const IMPACT_STATS = [ - { - value: '300+', - title: 'Educational Tools', - description: - "We've created over three-hundred tools for learning that are used around the globe, helping students develop critical thinking and technical skills.", - }, - { - value: '1000s', - title: 'Mentorship Hours', - description: - "We've mentored students for thousands of hours, guiding young developers at critical points in their development and helping them become leaders.", - }, - { - value: 'Global', - title: 'Educational Impact', - description: - "We've assisted schools in bringing project-based learning activities into their classrooms, empowering youth with technology skills worldwide.", - }, -]; - -export const FINANCIAL_FILINGS = [ - { - year: '2023', - link: 'assets/tax-filings/2023-Form-990EZ.pdf', - }, - { - year: '2022', - link: 'assets/tax-filings/2022-Form-990EZ.pdf', - }, - { - year: '2021', - link: 'assets/tax-filings/2021-Form-990EZ.pdf', - }, - { - year: '2020', - link: 'assets/tax-filings/2020-Form-990EZ.pdf', - }, - { - year: '2019', - link: 'assets/tax-filings/2019-Form-990EZ.pdf', - }, -]; diff --git a/src/constants/Footer.ts b/src/constants/Footer.ts deleted file mode 100644 index 7b685b12..00000000 --- a/src/constants/Footer.ts +++ /dev/null @@ -1,92 +0,0 @@ -import GithubIcon from '/assets/social/github.svg'; -import XIcon from '/assets/social/x.svg'; -import InstagramIcon from '/assets/social/instagram.svg'; -import LinkedinIcon from '/assets/social/linkedin.svg'; -import FacebookIcon from '/assets/social/facebook.svg'; -import YoutubeIcon from '/assets/social/youtube.svg'; -import MastodonIcon from '/assets/social/mastodon.svg'; -import MediumIcon from '/assets/social/medium.svg'; - -export const socialLinks = [ - { - name: 'GitHub', - href: 'https://github.com/sugarlabs', - icon: GithubIcon, - }, - { - name: 'X', - href: 'https://x.com/sugar_labs', - icon: XIcon, - }, - { - name: 'Instagram', - href: 'https://www.instagram.com/sugarlabsforall/', - icon: InstagramIcon, - }, - { - name: 'LinkedIn', - href: 'https://www.linkedin.com/company/sugar-labs', - icon: LinkedinIcon, - }, - { - name: 'Facebook', - href: 'https://www.facebook.com/SugarLabsforall/timeline/', - icon: FacebookIcon, - }, - { - name: 'YouTube', - href: 'https://www.youtube.com/channel/UCfsR9AEb7HuPRAc14jfiI6g/featured', - icon: YoutubeIcon, - }, - { - name: 'Mastodon', - href: 'https://mastodon.social/@sugar_labs', - icon: MastodonIcon, - }, - { - name: 'Medium', - href: 'https://medium.com/@sugarlabs', - icon: MediumIcon, - }, -]; - -export const resourceLinks = [ - { to: '/more/culture', text: 'Culture and pedagogy' }, - { to: '/more/students', text: 'For Students' }, - { to: '/more/school-admin', text: 'For School Administrators' }, - { to: '/more/parents', text: 'For Parents' }, - { to: '/join-development', text: 'For Developers' }, - { to: '/news/sugar-stories', text: 'Sugar Stories' }, - { to: '/musicblocks', text: 'Music Blocks' }, - { to: '/turtleblocks', text: 'Turtle Blocks JS' }, -]; - -export const developmentLinks = [ - { to: '/join-development', text: 'Read about development' }, - { - href: 'https://buttondown.com/sugarlabs', - text: 'Join mailing list', - }, - { href: 'https://help.sugarlabs.org/en/', text: 'Documentation' }, - { - href: 'https://matrix.to/#/#sugar:matrix.org', - text: 'Chat with us on Matrix', - }, - { - href: 'https://wiki.sugarlabs.org/go/Development_Team/Source_Code', - text: 'Development code', - }, - { href: 'https://translate.sugarlabs.org/', text: 'Translation Platform' }, - { - href: 'https://wiki.sugarlabs.org/go/Welcome_to_the_Sugar_Labs_wiki', - text: 'Sugar Labs Wiki', - }, -]; - -export const quickLinks = [ - { to: '/about-us', text: 'About Us' }, - { to: '/volunteer', text: 'Get Involved' }, - { to: '/donate', text: 'Donate to Sugar Labs' }, - { to: '/leadership', text: 'Leadership and Governance' }, - { to: '/contact-us', text: 'Contact Us' }, -]; diff --git a/src/constants/Header.ts b/src/constants/Header.ts deleted file mode 100644 index fccf3625..00000000 --- a/src/constants/Header.ts +++ /dev/null @@ -1,21 +0,0 @@ -export const navigationData = { - dropdowns: { - about: { - label: 'About', - items: [ - { label: 'About Us', path: '/about-us' }, - { label: 'Leadership', path: '/leadership' }, - { label: 'Contact Us', path: '/contact-us' }, - { label: 'FAQs', path: '/faqs' }, - ], - }, - }, - - links: [ - { label: 'News', path: '/news' }, - { label: 'Merchandise', path: '/products' }, - { label: 'Donate', path: '/donate' }, - { label: 'Join Development', path: '/join-development' }, - { label: 'Volunteer', path: '/volunteer' }, - ], -}; diff --git a/src/constants/Info.ts b/src/constants/Info.ts deleted file mode 100644 index 0272448a..00000000 --- a/src/constants/Info.ts +++ /dev/null @@ -1,50 +0,0 @@ -import teachImage from '/assets/Images/teach.jpg'; -import teach1Image from '/assets/Images/teach1.jpg'; -import discussImage from '/assets/Images/discuss.jpeg'; -import teach2Image from '/assets/Images/teach2.jpeg'; -import learnImage from '/assets/Images/learn.jpg'; - -export interface ImageConfig { - src: string; - alt: string; - caption?: string; -} - -interface HeroContent { - title: string; - description: string; -} - -export const heroContent: HeroContent = { - title: 'SUGAR LABS', - description: `Whether you're a young learner, teacher, or a budding developer, - we believe Sugar Labs has something for you. Read on to learn more - about our award-winning Sugar Learning Platform and how to join our - diverse community of teachers and learners.`, -}; - -export const images: Record<string, ImageConfig> = { - main: { - src: teachImage, - alt: 'Sugar Labs Learning Environment', - }, - bottom1: { - src: teach2Image, - alt: 'Sugar Labs Collaboration', - caption: 'Collaborative Learning Environment', - }, - bottom2: { - src: teach1Image, - alt: 'Sugar Labs Teaching', - caption: 'Interactive Teaching Tools', - }, - bottom3: { - src: discussImage, - alt: 'Sugar Labs Learning', - caption: 'Global Learning Community', - }, -}; - -export const mission = { - learnImage, -}; diff --git a/src/constants/Leadership.ts b/src/constants/Leadership.ts deleted file mode 100644 index 7ea0efad..00000000 --- a/src/constants/Leadership.ts +++ /dev/null @@ -1,95 +0,0 @@ -export interface Director { - id: number; - name: string; - bio: string; - imageUrl: string; - position: string; - socialLinks?: { - linkedin?: string; - github?: string; - wiki?: string; - }; -} - -export interface DirectorCardProps { - director: Director; -} - -export interface SocialLinkProps { - href: string; - aria: string; - icon: React.ReactNode; -} - -export const directors: Director[] = [ - { - id: 1, - name: 'Claudia Urrea', - position: 'Treasurer, Sugar Labs', - bio: "Claudia Urrea is the Senior Associate Director for pK-12 at the MIT Abdul Latif Jameel World Education Lab (J-WEL). Claudia was born in Colombia, where she received an undergraduate degree in Computer Science from EAFIT University. Claudia received her master's degree in Educational Media and Technology from Boston University, and her doctorate degree from the MIT Media Laboratory. Her Ph.D. thesis studied the implications of one-to-one learning in a rural setting in Costa Rica. Claudia worked for 5 years as the Director of Learning for One Laptop Per Child, collaborating with SugarLabs in that role. She has been in the board of SugarLabs since 2010.\n\nFor the past 25 years, Claudia has helped multiple governments and non-government agencies- The New York Academy of Sciences, Schlumberger Excellence in Education Development, International Development Research Centre, among others- to empower and support schools and communities of learners to evolve from traditional teaching methods into progressive learning environments. She has also a research scientist position with the Lifelong Kindergarten group at the MIT Media Lab. She has taught several classes at the Harvard Summer Program and Early Childhood Development program at Tufts University.", - imageUrl: 'assets/Images/BoardMembers/Claudia.png', - socialLinks: { - linkedin: 'https://www.linkedin.com/in/claudia-urrea-ph-d-0335041/', - wiki: 'https://wiki.sugarlabs.org/go/User:Claudia_Urrea', - }, - }, - { - id: 2, - name: 'Devin Ulibarri', - position: 'Executive Director, Sugar Labs', - bio: "Devin Ulibarri has been involved in Sugar Labs for over a decade. Ulibarri has been involved in education for twenty years, and he's advocated for free/libre/open (FLO) source software, particularly in education, for the past decade. For two years from 2022 to 2024, he worked as Outreach and Communications Coordinator at the Free Software Foundation.\n\nAt Sugar Labs, Ulibarri has worked closely with Walter Bender to create Music Blocks visual programming language. In addition to this, he's mentored for Google Summer of Code (GSoC) and Google Code-In (GCI), and he regularly teaches students as young as five years old using a rich variety of Sugar tools. Ulibarri plays classical guitar, and he is the Dungeon Master for his family on the weekends.", - imageUrl: 'assets/Images/BoardMembers/Devin.png', - socialLinks: { - github: 'https://github.com/pikurasa', - linkedin: 'https://www.linkedin.com/in/devin-ulibarri-76277a300/', - wiki: 'https://wiki.sugarlabs.org/go/User:Pikurasa', - }, - }, - { - id: 3, - name: 'Samson Goddy', - position: 'Board Member, Sugar Labs', - bio: 'Samson is an open source advocate who is very passionate about Edtech. He is currently working with International Telecommunication Union (ITU) to bring more African girls into Technology. He is the co-founder of Open Source Community Africa, a movement that promotes and educate everything open source within Africa.', - imageUrl: 'assets/Images/BoardMembers/Samson.jpeg', - socialLinks: { - github: 'https://github.com/samswag', - linkedin: 'https://www.linkedin.com/in/samsongoddy/', - wiki: 'https://wiki.sugarlabs.org/go/User:Samson_Goddy', - }, - }, - { - id: 4, - name: 'Sebastian Silva', - position: 'Board Member, Sugar Labs', - bio: 'Sebastian Silva learned Logo as a 5-year-old child in a workshop in Lima in the 1980s. Later, he taught himself Basic, Pascal, Python, JS, etc... but most importantly, through exploring GNU/Linux, he became enamoured with the philosophy of Software Freedom. He went on to study Psychology to satisfy his curiosity. Soon, he was involved with the original Sugar deployments on OLPC laptops in Peru, Colombia, and Uruguay - organizing local groups to promote software freedom in the region. SomosAzucar initiative (a SL local lab) was responsible for the addition of Quechua, Aymara and Awajún system locales to GLIBC in order to support these deployments. Currently, Silva works as Senior Programming Coach at Laboratoria, a feminist organization. In his spare time, he has written a few programming-learning gadgets such as SUPER-8 and Jappy Creator, and he\'s the Software Curator for the laptop-deployment projects of Repurpose-IT.org. He misses having a viable constructivist learning environment that "free desktops" can use, so he has returned to the Sugar Labs board.', - imageUrl: 'assets/Images/BoardMembers/Silva.png', - socialLinks: { - github: 'https://github.com/icarito', - wiki: 'https://wiki.sugarlabs.org/go/User:Sebastian', - }, - }, - { - id: 5, - name: 'Sumit Srivastava', - position: 'Board Member, Sugar Labs', - bio: 'Sumit Srivastava is a recipient of Stability AI supercomputer grant for open source AI research and is currently working on a new AI project called Cotyper. Prior to this, he started a leading medical search engine and was a part of the leading talent investor Entrepreneur First. He is a maintainer of the Music Blocks programming language. Sumit started many learning groups in Asia where people learn by doing and get iterative feedback. For fun, he plays ukulele and flute, and he builds things like livestreaming software and air purifiers.', - imageUrl: 'assets/Images/BoardMembers/Sumit.jpeg', - socialLinks: { - github: 'https://github.com/sum2it', - linkedin: 'https://www.linkedin.com/in/sumsri/', - wiki: 'https://wiki.sugarlabs.org/go/User:Sum2it', - }, - }, - { - id: 6, - name: 'Walter Bender', - position: 'Secretary, Sugar Labs', - bio: 'Founder of Sugar Labs and co-founder of One Laptop Per Child (OLPC), Walter Bender has more than thirty years experience as an academic advisor at MIT. He has more than forty years experience as a software developer. Author of numerous learning tools, Bender is the original author of Turtle Blocks and Music Blocks, as well as many Sugar Activities.', - imageUrl: 'assets/Images/BoardMembers/Walter.png', - socialLinks: { - github: 'https://github.com/walterbender', - linkedin: 'https://www.linkedin.com/in/walterbender/', - wiki: 'https://wiki.sugarlabs.org/go/User:Walter', - }, - }, -]; diff --git a/src/constants/MarkdownFiles/authors/aditya-singh.md b/src/constants/MarkdownFiles/authors/aditya-singh.md deleted file mode 100644 index 97ac1b1b..00000000 --- a/src/constants/MarkdownFiles/authors/aditya-singh.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: "Aditya Kumar Singh" -slug: "aditya-singh" -title: "GSoC'25 Contributor" -organization: "SugarLabs" -description: "GSoC'25 Contributor at SugarLabs" -avatar: "https://avatars.githubusercontent.com/u/128071145?v=4" - ---- - - -<!--markdownlint-disable--> - -# About Aditya Kumar Singh - -Hi! I'm Aditya Kumar Singh, a passionate software developer and open-source enthusiast from India, I'm currently pursuing my Bachelor's in Information Technology. I'm excited to be working with Sugar Labs as a GSoC 2025 contributor, where I'm enhancing the 3D Human Body and Stickman Animation Activities for Sugarizer. - -## Experience - -- **GSoC 2025 Contributor at Sugar Labs** - Working on Sugarizer Human Activity Pack enhancing the 3D Human Body Activity with anatomical layer toggling, Doctor Mode, and multiplayer support, and building a Stickman Animator with AI-based pose estimation. - -## Current Projects - -- **3D Human Body Activity (Sugarizer)** - A fully interactive anatomical learning tool using Three.js, localized UI, and collaborative learning features. - -- **Stickman Animation Activity (Sugarizer)** - A creative animation tool where users can build motion sequences using a skeletal system, with onion skinning, AI-based pose estimation, and video export. - - -## Connect with Me - -- **GitHub**: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) -- **Email**: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) -- **LinkedIn**: [Aditya Kumar Singh](https://linkedin.com/in/adityakrsingh26) -- **Website**: [aditya-singh.me](https://aditya-singh.me) -- **Discord**: [praise_dark_lord](https://discord.com/users/praise_dark_lord) diff --git a/src/constants/MarkdownFiles/authors/aman-chadha.md b/src/constants/MarkdownFiles/authors/aman-chadha.md deleted file mode 100644 index 532b3bba..00000000 --- a/src/constants/MarkdownFiles/authors/aman-chadha.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: "Aman Chadha" -slug: "aman-chadha" -title: "DMP'25 Contributor" -organization: "SugarLabs" -description: "DMP'25 Contributor at SugarLabs" -avatar: "https://avatars.githubusercontent.com/u/79802170?v=4" ---- - -<!--markdownlint-disable--> - -# About Aman Chadha - -I am a DMP 2025 contributor working with Sugar Labs on enhancing Music Blocks' internationalization system using AI-supported translation. I'm passionate about building intelligent systems, developer tools, and creative educational platforms that empower users across languages. - -## Experience - -- Contributor at Sugar Labs (DMP '25) - -## Current Projects - -- **JS Internationalization with AI Translation Support**: - Integrating a modern i18n workflow in Music Blocks and enhancing it with AI-powered fallback translations, context-aware retrieval, and part-of-speech–informed RAG models. - -## Connect with Me - -- **GitHub**: [@ac-mmi](https://github.com/ac-mmi) -- **Email**: [aman.chadha.mmi@gmail.com](mailto:aman.chadha.mmi@gmail.com) - diff --git a/src/constants/MarkdownFiles/authors/amannaik247.md b/src/constants/MarkdownFiles/authors/amannaik247.md deleted file mode 100644 index ae12120c..00000000 --- a/src/constants/MarkdownFiles/authors/amannaik247.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: "Aman Naik" -slug: "amannaik247" -title: "DMP'25 Contributor" -organization: "SugarLabs" -description: "DMP'25 Contributor at SugarLabs" -avatar: "https://avatars.githubusercontent.com/u/168978808?v=4" ---- - -<!--markdownlint-disable--> - -# About Aman Naik - -I’m someone who loves building smart tools that make life a little easier—whether it’s a chatbot that talks like Lord Krishna or a system that helps forecast real-time prices. I’ve explored everything from AI and machine learning to satellite data and creative writing prompts. I enjoy blending tech with storytelling, finding joy in both solving real problems and crafting meaningful experiences. For me, coding isn’t just logic, it’s a way to create things that connect with people. - -## Experience - -- DMP'25 contributor for SugarLabs -- Active Open Source Contributor - -## Current Projects - -Adding an AI-assistant to the Write Activity - -## Connect with Me - -- **GitHub**: [@amannaik247](https://github.com/amannaik247) -- **Email**: [amancodes247@gmail.com](mailto:your.email@example.com) -- **LinkedIn**: [Aman Naik](https://linkedin.com/in/aman-naik) \ No newline at end of file diff --git a/src/constants/MarkdownFiles/authors/anvita-prasad.md b/src/constants/MarkdownFiles/authors/anvita-prasad.md deleted file mode 100644 index 0776a6bd..00000000 --- a/src/constants/MarkdownFiles/authors/anvita-prasad.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: "Anvita Prasad" -slug: "anvita-prasad" -title: "DMP'25 Contributor" -organization: "SugarLabs" -description: "DMP'25 Contributor at SugarLabs" -avatar: "https://avatars.githubusercontent.com/u/147875261?s=400&u=e784808241accea1d4c664bba0ce7bd6ca000662&v=4" ---- - -<!--markdownlint-disable--> - -# About Anvita Prasad - -Anvita is a DMP 2025 contributor at SugarLabs, working on improving synth and sample features in Music Blocks. A second-year Computer Science student at IIIT Kancheepuram and passionate open-source contributor, she strives to create meaningful and impactful experiences that bridge technology and creativity. - -## Experience - -- **DMP 2025**: Improving synth and sample features in Music Blocks -- **Sugar Labs Member**: Active contributor to Sugar's developer tooling and educational platforms -- **Music Theory**: Completed Grade 4 in Trinity music theory - -## Current Projects - -- Improving Synth and Sample Features in Music Blocks -- Music Blocks Developer - -## Connect with Me - -- **GitHub**: [@AnvitaPrasad](https://github.com/AnvitaPrasad) -- **Email**: [anvita.prasad1@gmail.com](mailto:anvita.prasad1@gmail.com) -- **LinkedIn**: [Anvita Prasad](https://www.linkedin.com/in/anvita-prasad) -- **Website**: [anvitaprasad.netlify.app](https://anvitaprasad.netlify.app/) \ No newline at end of file diff --git a/src/constants/MarkdownFiles/authors/bishoy-wadea.md b/src/constants/MarkdownFiles/authors/bishoy-wadea.md deleted file mode 100644 index ea221f08..00000000 --- a/src/constants/MarkdownFiles/authors/bishoy-wadea.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: "Bishoy Wadea" -slug: "bishoy-wadea" -title: "GSoC'25 Contributor" -organization: "SugarLabs" -description: "GSoC'25 Contributor at SugarLabs" -avatar: "https://avatars.githubusercontent.com/u/108888519?s=400&u=084aa7be2ae3aedd1cf38175557820a49b7efa93&v=4" ---- - -<!--markdownlint-disable--> - -# About Bishoy Wadea - -I am **Bishoy Wadea**, a Google Summer of Code 2025 contributor with Sugar Labs, developing a suite of math games to make learning more engaging and interactive. With prior experience at Microsoft and currently an R&D engineer at Siemens, I am passionate about building open-source tools that make complex ideas fun and approachable for learners. - -## Experience - -- **GSoC 2025**: Developing interactive math games for Sugar Labs. -- **R&D Backend Engineer Intern – Siemens**: Contributing to backend systems with a focus on performance, reliability, and scalability. -- **Microsoft Summer Engineering Program**: Built and optimized a 7TB data pipeline. - -## Current Projects - -- Developing 10 interactive math games for Sugar Labs. - - -## Connect with Me - -- **GitHub**: [@bishoywadea](https://github.com/Bishoywadea) -- **Email**: [bishoyw.fathy@gmail.com](mailto:bishoyw.fathy@gmail.com) -- **LinkedIn**: [Bishoy Wadea](https://www.linkedin.com/in/bishoy-wadea-27b016250/) \ No newline at end of file diff --git a/src/constants/MarkdownFiles/authors/diwangshu-kakoty.md b/src/constants/MarkdownFiles/authors/diwangshu-kakoty.md deleted file mode 100644 index 2412584b..00000000 --- a/src/constants/MarkdownFiles/authors/diwangshu-kakoty.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: "Diwangshu Kakoty" -slug: "diwangshu-kakoty" -title: "GSoC'25 Contributor" -organization: "SugarLabs" -description: "Member and GSoC'25 Contributor at SugarLabs" -avatar: "https://avatars.githubusercontent.com/u/142284646?s=400&u=81be7e66ba1d554e6928fe267d68af5e2a90e359&v=4" ---- - -<!--markdownlint-disable--> - -# About Diwangshu Kakoty - -Hi, I'm Diwangshu - a B.Tech student and lifelong learner in computer science. I'm a dedicated contributor, community member, and a 2025 Google Summer of Code intern with SugarLabs, where I’m working on the project "AI Tools for Reflection." My passion lies in creativity and building meaningful solutions that benefit society, and I see coding as my way to bring those ideas to life. - - -## Experience - -- **GSoC 2025**: AI Tools for Reflection Learning -- **SugarLabs Member**: Active contributor to various projects -- C, JS and Python development - -## Current Projects - -- AI Tools for Reflection Learning -- Music Blocks 3 development - - -## Connect with Me - -- **GitHub**: [@Commanderk3](https://github.com/Commanderk3) -- **Email**: [diwangshukakoty@gmail.com](mailto:diwangshukakoty@gmail.com) -- **LinkedIn**: [Diwangshu Kakoty](https://www.linkedin.com/in/diwangshu-kakoty/) -- **Twitter**: [@redCoder101](https://twitter.com/redCoder101) -- **Discord**: [commanderk3](https://discord.com/users/commanderk3) \ No newline at end of file diff --git a/src/constants/MarkdownFiles/authors/elwin-li.md b/src/constants/MarkdownFiles/authors/elwin-li.md deleted file mode 100644 index 8e497e5a..00000000 --- a/src/constants/MarkdownFiles/authors/elwin-li.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: "Elwin Li" -slug: "elwin-li" -title: "GSoC'25 Contributor" -organization: "SugarLabs" -description: "GSoC'25 Contributor at SugarLabs" -avatar: "https://i.ibb.co/rGyw3WZM/Untitled-design-1.png" ---- - -<!--markdownlint-disable--> - -# About Elwin Li - -Elwin is a Google Summer of Code 2025 contributor for Sugarlabs, working on bridging the gap between text-based coding and block coding in MusicBlocks. - -## Experience - -- **GSoC 2025**: Enhancing the JSeditor through adding code to block conversion, and fully functional debugger - -## Current Projects - -- [Code to Block conversion](https://github.com/sugarlabs/musicblocks/pull/4707) (Completed) -- Debugger (WIP) -- Syntax highlighting (WIP) - -## Connect with Me - -- **GitHub**: [@ebeetles](https://github.com/ebeetles) -- **Gmail**: [elwin.s.li@gmail.com](mailto:elwin.s.li@gmail.com) -- **LinkedIn**: [Elwin Li](https://www.linkedin.com/in/elwinsli/) - diff --git a/src/constants/MarkdownFiles/authors/harshit-verma.md b/src/constants/MarkdownFiles/authors/harshit-verma.md deleted file mode 100644 index aea91806..00000000 --- a/src/constants/MarkdownFiles/authors/harshit-verma.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: "Harshit Verma" -slug: "harshit-verma" -title: "Member and DMP'25 Contributor" -organization: "Sugar Labs" -description: "Member and DMP'25 Contributor at Sugar Labs" -avatar: "https://avatars.githubusercontent.com/u/169194753?v=4" ---- - -<!--markdownlint-disable--> - -# About Harshit Verma - -I'm Harshit Verma, a Computer Science Engineering student with a passion for technology, problem-solving, and building innovative software solutions. -I'm currently exploring various areas of computer science, including software development, AI/ML, and system design. I enjoy turning ideas into code and continuously learning new tools and technologies to sharpen my skills. Whether it's contributing to open-source, building personal projects, or debugging complex systems, I'm always up for a challenge that helps me grow as a developer. - -## Experience - -- **DMP 2025**: LLM-Powered Debugger for Pippy -- **SugarLabs Member**: Member and Contributor to various projects -- **Hactoberfest 2024:** Contributed to Open-Source projects - -## Current Projects - -- LLM-Powered Debugger for Pippy -- Music Blocks Developer -- Sugar Labs website development - -## Connect with Me - -- **GitHub**: [@therealharshit](https://github.com/therealharshit) -- **Email**: [therealharshit014@gmail.com](mailto:therealharshit014@gmail.com) -- **LinkedIn**: [Harshit Verma](https://linkedin.com/in/therealharshit) diff --git a/src/constants/MarkdownFiles/authors/justin-charles.md b/src/constants/MarkdownFiles/authors/justin-charles.md deleted file mode 100644 index 890da10d..00000000 --- a/src/constants/MarkdownFiles/authors/justin-charles.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: "Justin Charles" -slug: "justin-charles" -title: "Member and DMP'25 Contributor" -organization: "Sugar Labs" -description: "Member and DMP'25 Contributor at Sugar Labs" -avatar: https://avatars.githubusercontent.com/u/143245796?s=400&u=56426d9e56b5d8ee545ba6b753e300d90e994eaa&v=4 ---- - -<!--markdownlint-disable--> - -# About Justin Charles - -I'm Justin Charles, an enthusiastic Computer Science student passionate about open-source, creative coding, and building impactful developer tools. -As a contributor at Sugar Labs and a participant in DMP 2025, I’m focused on improving the developer experience through intelligent tooling and user-centric design. I thrive on collaborative environments and believe in writing clean, maintainable code that scales. - -## Experience - -- **DMP 2025**: Enhancing Debugger Capabilities for Pippy using LLMs -- **Sugar Labs Member**: Active contributor to Sugar's developer tooling and educational platforms -- **Open Source Contributor**: Regular participant in Hacktoberfest and community-led initiatives - -## Current Projects - -- MusicBlocks-v4 Masonry Module -- Music Blocks Developer - -## Connect with Me - -- GitHub: [@justin212407](https://github.com/justin212407) -- Gmail: [charlesjustin2124@gmail.com](mailto:charlesjustin2124@gmail.com) -- LinkedIn: [Justin Charles](https://www.linkedin.com/in/justin-c-663840297/) diff --git a/src/constants/MarkdownFiles/authors/krish-pandya.md b/src/constants/MarkdownFiles/authors/krish-pandya.md deleted file mode 100644 index a61e7ca3..00000000 --- a/src/constants/MarkdownFiles/authors/krish-pandya.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: "Krish Pandya" -slug: "krish-pandya" -title: "Maintainer and GSoC'25 Contributor" -organization: "SugarLabs" -description: "GSoC'25 Contributor at SugarLabs working on GTK4 migration" -avatar: "https://avatars.githubusercontent.com/u/135974627?s=400&u=d8834bf3a691f090819069974b42cf936a93b0e7&v=4" ---- - -<!--markdownlint-disable--> - -# About Krish Pandya - -I'm Krish, aka MostlyK, a B.Tech student in Electronics and Communication Engineering at IIITH. While my degree might say ECE, I've completely fallen down the open source rabbit hole. I believe in doing things right the first time, even if it takes longer, and I approach problems by understanding the "why" behind changes, not just the "what." - -## Experience - -- Systems engineering and graphics programming -- Open source development and contribution -- C/Python development -- Linux and System Adminstration - -## Current Projects - -- **GSoC 2025**: GTK4 migration for Sugar Labs desktop environment -- Modular architecture and newer build system design for Sugar -- Sugar-AI and it's implementation along with other fun stuff. - -## Connect with Me - -- **GitHub**: [@mostlykiguess](https://github.com/mostlykiguess) -- **Email**: [krishpandya93@gmail.com](mailto:krishpandya93@gmail.com) -- **LinkedIn**: [Krish Pandya](https://www.linkedin.com/in/krish-pandya-020aaa261/) -- **Mastodon**: [@mostlyk](https://mastodon.social/@mostlyk) diff --git a/src/constants/MarkdownFiles/authors/mebin-thattil.md b/src/constants/MarkdownFiles/authors/mebin-thattil.md deleted file mode 100644 index 7ffd7c80..00000000 --- a/src/constants/MarkdownFiles/authors/mebin-thattil.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: "Mebin Thattil" -slug: "mebin-thattil" -title: "GSoC'25 Contributor" -organization: "SugarLabs" -description: "GSoC'25 Contributor at SugarLabs" -avatar: "https://mebin.shop/mebin-380.png" ---- - -<!--markdownlint-disable--> - -# About Mebin Thattil - -Hey, I'm Mebin 👋🏻! I'm a first year student at PES University, Bangalore, India, currently pursuing a BTech in Computer Science. I’ve had a deep passion for tech ever since I was 10, when I first learned in a CS class that you could write a couple of lines of code and build a (barely functional) website. That simple idea sparked something in me, and over the years, my love for computer science has only grown—especially while building a bunch of cool things along the way. - -I'm going to spend my summer working on the [Speak Activity](https://github.com/sugarlabs/speak). I will be refactoring the chatbot in the speak activity to use Gen-AI. - -About a month ago, I launched my personal portfolio website: [mebin.in](https://mebin.in/). It runs on an 8-year-old Raspberry Pi sitting at home 🤩, so apologies in advance if the site is occasionally slow or down (power cuts are a real pain). I ocassionally write blogs there. - -I'm also building a Bluesky client in the Nim programming language. I'm a strong advocate for education in technology. In the past, I built a web application aimed at connecting students in rural areas with those in urban areas to help foster a free and open peer-to-peer learning ecosystem. - -## Connect with Me - -- **GitHub**: [@mebinthattil](https://github.com/mebinthattil) -- **Website**: [mebin.in](https://mebin.in/) -- **Email**: [mail@mebin.in](mailto:mail@mebin.in) -- **LinkedIn**: [Mebin Thattil](https://www.linkedin.com/in/mebin-thattil/) diff --git a/src/constants/MarkdownFiles/authors/muhammad-haroon.md b/src/constants/MarkdownFiles/authors/muhammad-haroon.md deleted file mode 100644 index fc81b596..00000000 --- a/src/constants/MarkdownFiles/authors/muhammad-haroon.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: "Muhammad Haroon" -slug: "muhammad-haroon" -title: "Member & SSoC'25 Contributor" -organization: "Sugar Labs" -description: "Member & SSoC'25 Contributor at Sugar Labs" -avatar: "/assets/Developers/Muhammad Haroon/muhammadharoon.jpg" ---- - -<!--markdownlint-disable--> - -# About Muhammad Haroon - -Hi, I’m Muhammad Haroon, a final year student at NED University Karachi, Pakistan, pursuing a degree in Computer Information & Systems Engineering. - -I have been actively contributing to Sugar Labs for a long time not just in code, but also in documentation and by assisting new contributors. - -This summer, I’ve been selected for Sugar Summer of Code (SSoC) 2025. This is the first time Sugar Labs is running this program, and I’m proud to be a pilot candidate. I’ll be working on Generative AI Instrument Sample Generation for Music Blocks, which will give students endless options for sound samples. - -## Experience - -- **SSoC 2025**: Generative AI Instrument Sample Generation for Music Blocks -- **Sugar Labs Member**: Active contributor to various projects - -## Current Projects - -- Generative AI Instrument Sample Generation for Music Blocks -- Sugar Labs website development - -## Connect with Me - -- **GitHub**: [@haroon10725](https://github.com/haroon10725) -- **Email**: [haroongondal347@gmail.com](mailto:haroongondal347@gmail.com) -- **LinkedIn**: [Muhammad Haroon](https://www.linkedin.com/in/muhammad-haroon-7003b923b/) \ No newline at end of file diff --git a/src/constants/MarkdownFiles/authors/nikhil-bhatt.md b/src/constants/MarkdownFiles/authors/nikhil-bhatt.md deleted file mode 100644 index f7687b9a..00000000 --- a/src/constants/MarkdownFiles/authors/nikhil-bhatt.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: "Nikhil Bhatt" -slug: "nikhil-bhatt" -title: "GSoC'25 Contributor" -organisation: "Sugarlabs" -description: "GSoc'25 Contributor, learning through code" -avatar: "https://avatars.githubusercontent.com/u/154296996?s=400&u=985121a969ea993a325f2690d74a0712f0599309&v=4" ---- - -<!--markdownlint-disable--> - -# About Nikhil Bhatt -Nikhil Bhatt is a Google Summer of Code 2025 contributor and full stack product developer with a strong focus on building impactful, scalable tools. - -## Experience - -- **GSoC 2025**: Music Blocks v3 Backend Development - -## Current Projects - -- Git backend for Musicblocks - - -## Connect with Me - -- **GitHub**: [BeNikk](https://github.com/BeNikk) -- **Email**: [bhattnik442@gmail.com](mailto:bhattnik442@gmail.com) -- **LinkedIn**: [Nikhil bhatt](https://www.linkedin.com/in/nikhil-bhatt-3b37a0255/) -- **Twitter**: [Nikhil](https://twitter.com/Be_Nikkk) diff --git a/src/constants/MarkdownFiles/authors/om-santosh-suneri.md b/src/constants/MarkdownFiles/authors/om-santosh-suneri.md deleted file mode 100644 index 16123df6..00000000 --- a/src/constants/MarkdownFiles/authors/om-santosh-suneri.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: "Om Santosh Suneri" -slug: "om-santosh-suneri" -title: "GSoC'25 Contributor" -organization: "SugarLabs" -description: "Maintainer and GSoC'25 Contributor at SugarLabs" -avatar: "https://avatars.githubusercontent.com/u/142336291?s=400&u=6f66e785309c44a70de1f634e768c60a47de3c1c&v=4" ---- - -<!--markdownlint-disable--> - -# About Om Santosh Suneri - -Suneri is a passionate open-source contributor and a Google Summer of Code 2025 contributor with SugarLabs. He is currently developing the AI-powered Debugger for Music Blocks, a project he originally conceptualized during one of SugarLabs’ biweekly community meetings. This innovative tool aims to assist learners and educators by automatically detecting and explaining errors in Music Blocks projects using LLMs and vector-based retrieval techniques. With a strong interest in the intersection of educational tools and artificial intelligence, Suneri is dedicated to building solutions that make learning to code more accessible and engaging for users of all ages. - -## Experience - -- **GSoC 2025**: AI-powered Debugger for Music Blocks -- **SugarLabs Maintainer**: Active contributor to various projects - -## Current Projects - -- AI-powered Debugger for Music Blocks -- SugarLabs website development -- Music Blocks Developer - - -## Connect with Me - -- **GitHub**: [@omsuneri](https://github.com/omsuneri) -- **Gmail**: [omsuneri@gmail.com](mailto:omsuneri@gmail.com) -- **LinkedIn**: [Om Santosh Suneri](https://www.linkedin.com/in/om-santosh-suneri-736767166/) -- **Twitter**: [@suneri_om](https://x.com/suneri_om) diff --git a/src/constants/MarkdownFiles/authors/safwan-sayeed.md b/src/constants/MarkdownFiles/authors/safwan-sayeed.md deleted file mode 100644 index c983ee34..00000000 --- a/src/constants/MarkdownFiles/authors/safwan-sayeed.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: "Safwan Sayeed" -slug: "safwan-sayeed" -title: "Maintainer and GSoC'25 Contributor" -organization: "SugarLabs" -description: "Maintainer and GSoC'25 Contributor at SugarLabs" -avatar: "https://avatars.githubusercontent.com/u/111475221?s=400&u=084aa7be2ae3aedd1cf38175557820a49b7efa93&v=4" ---- - -<!--markdownlint-disable--> - -# About Safwan Sayeed - -Safwan is a dedicated maintainer and Google Summer of Code 2025 contributor at SugarLabs, working primarily on the Music Blocks 4 Program Engine development. With a passion for educational technology and open-source development, Safwan contributes to making programming more accessible to learners worldwide. - -## Experience - -- **GSoC 2025**: Music Blocks 4 Program Engine development -- **SugarLabs Maintainer**: Active contributor to various projects - -## Current Projects - -- Music Blocks 4 Program Engine -- SugarLabs website development - - -## Connect with Me - -- **GitHub**: [@sa-fw-an](https://github.com/sa-fw-an) -- **Email**: [isafwansayeed@gmail.com](mailto:isafwansayeed@gmail.com) -- **LinkedIn**: [Safwan Sayeed](https://linkedin.com/in/safwan-sayeed-6a3a482a9) -- **Twitter**: [@safwan_say](https://x.com/safwan_say) -- **Website**: [www.safwansayeed.live](https://safwansayeed.live) \ No newline at end of file diff --git a/src/constants/MarkdownFiles/authors/saumya-shahi.md b/src/constants/MarkdownFiles/authors/saumya-shahi.md deleted file mode 100644 index baaa0887..00000000 --- a/src/constants/MarkdownFiles/authors/saumya-shahi.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: "Saumya Shahi" -slug: "saumya-shahi" -title: "GSoC'25 Contributor" -organization: "SugarLabs" -description: "GSoC'25 Contributor at SugarLabs" -avatar: "https://avatars.githubusercontent.com/u/147405306?v=4" ---- - -<!--markdownlint-disable--> - -# About Saumya Shahi - -Saumya is a GSoC 2025 contributor at SugarLabs, currently working on the Masonry Module for Music Blocks. A second-year Computer Science student at IIIT Kottayam with a specialization in Cybersecurity, Saumya is passionate about building intuitive and impactful user experiences. - -Beyond open source, Saumya actively explores quantum computing and cryptographic systems, and has contributed to research in quantum cryptanalysis under DRDO CQC. - -## Experience - -- **GSoC 2025**: Developing the Masonry Module for Music Blocks, a visual programming environment. -- **Quantum Cryptanalysis Research Intern**: DRDO CQC at NITK, working on cipher distinguishers using quantum algorithms - -## Current Projects - -- Music Blocks Masonry Module -- Quantum Feistel cryptanalysis - -## Connect with Me - -- **GitHub**: [@saumyashahi](https://github.com/saumyashahi) -- **Email**: [saumya23bcy18@iiitkottayam.ac.in](mailto:saumya23bcy18@iiitkottayam.ac.in) -- **LinkedIn**: [Saumya Shahi](https://linkedin.com/in/saumya-shahi) diff --git a/src/constants/MarkdownFiles/authors/shubham-singh.md b/src/constants/MarkdownFiles/authors/shubham-singh.md deleted file mode 100644 index 213f06b7..00000000 --- a/src/constants/MarkdownFiles/authors/shubham-singh.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: "Shubham Singh" -slug: "shubham-singh" -title: "Maintainer and GSoC'25 Contributor" -organization: "SugarLabs" -description: "Maintainer and GSoC'25 Contributor at SugarLabs" -avatar: "https://avatars.githubusercontent.com/u/174003514?s=400&u=e43600ba24f563f3799388137119ae119c74ffac&v=4" ---- - -<!--markdownlint-disable--> - -# About Shubham - -Shubham Singh is a passionate developer, open-source contributor, and Google Summer of Code 2025 contributor at SugarLabs. As a core contributor, he brings together creativity and functionality, optimizing both the user experience and technical performance of projects. Shubham is currently working on enhancing educational tools, with a focus on accessibility, interactivity, and meaningful design—empowering learners globally through open-source innovation. - - -## Experience - -- **GSoC 2025**: Music Blocks v3 color sensor development -- **SugarLabs Maintainer**: Active contributor to various projects - -## Current Projects - -- Music Blocks v3 Development of Color Sensor. -- SugarLabs website development - - -## Connect with Me - -- **GitHub**: [@FirePheonix](https://github.com/FirePheonix) -- **Email**: [shubhsoch@gmail.com](mailto:shubhsoch@gmail.com) -- **LinkedIn**: [Shubham Singh](https://www.linkedin.com/in/shubham-singh-8a5643198/) -- **Twitter**: [@shubhamm069](https://x.com/shubhamm069) -- **Website**: -- **Discord**: [ctrlaltresett](https://discord.com/users/Shubham#0418) \ No newline at end of file diff --git a/src/constants/MarkdownFiles/more/culture.md b/src/constants/MarkdownFiles/more/culture.md deleted file mode 100644 index d2d25593..00000000 --- a/src/constants/MarkdownFiles/more/culture.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Culture and Pedagogy -slug: culture -author: Sugar Labs Team -lastUpdated: 2025-03-07 -category: Education ---- -<!-- markdownlint-disable --> - -## What makes Sugar different? -It would be nice to define what we are talking about when we say "Sugar," since we have multiple platforms. For example, is this page dedicated to Sugar as a desktop environment, or do we want to make this broader to include web apps, Sugarizer, etc.? - -- **Sugar facilitates sharing and collaboration**: children can write articles, share books, or make music together with a single mouse click. -- **Activities, not applications**: Sugar activities are applicable beyond the scope of the classroom and even Sugar itself. -- **Automatic backup of Activity work**: No worrying about files or folders. Sugar’s Journal makes it almost impossible to lose any data. -- **The Journal records everything you do**: It is a place to reflect upon and evaluate your work. -- **Sugar runs on most computer hardware**, including slower machines. -- **Sugar is Free (Libre) Software**: It is written in Python and easily customized. -- **Sugar is documented by its users**: It is easy to use, and teachers worldwide have created a wealth of pedagogical materials for it. -- **Sugar is written by its users**: 50% of the updates to our latest release came directly from our users. - - It would be nice to have a link here, for reference. - -## What are the benefits of using Sugar? -- **Hundreds of tools for discovery**: Exploring, expressing, and sharing through online research, writing, coding, and more. -- **Built-in collaboration system**: Peer-to-peer learning; always-on support; and single-click sharing. - - What is "always-on support"? -- **A built-in portfolio assessment tool** called Journal that serves as a forum for discussion between children, parents, and teachers. -- **A discoverable learning platform**: It uses simple means to reach complex ends. - - What do we mean by "discoverable"? That we can use the platform to discover ideas? -- **Designed for local appropriation**: Sugar has built-in tools for making changes and improvements and a growing global community of support. - - Twenty-five languages are currently available. -- **An emphasis on learning through doing and debugging**: Engages learners better to tackle authentic problems. -- **Available in a wide variety of forms**: As part of GNU/Linux distributions, as well as LiveCD, LiveUSB, and in a virtual machine for Windows and Mac machines. - -## What are the Sugar advantages? -- **Pedagogical framework** centered around Constructionism learning and founded on student empowerment. -- **Collaboration and journaling features**, uniquely designed by educators for educators and learners. -- **Hundreds of activities**. -- **Large and committed community** of developers, teachers, and learners from all around the globe. - - Perhaps it would be nice to have numbers here, if possible. -- **24/7 community support**. - - What do we mean by this? That we are available by Matrix/IRC? -- **Online and in-person training and workshops available**. -- **Handouts available to use in the classroom**. -- **Teacher-driven development**, rapidly expanding every day. -- **Easily localizable and customizable**. -- **Free/Libre software**: No licensing fees. -- **A global project**: No single point of dependency or failure. - -## A *learning-centric* approach -At Sugar Labs, we strive for a *learning-centric* approach, where teachers mentor students as they engage with powerful ideas, or *instructing less and learning more*. - -At Sugar Labs, we give children access to *knowledge*—through media such as electronic books, the world-wide web, and multimedia—but, more importantly, we give them the tools they need to *create*, to learn about learning, to put knowledge to use, and engage in reflection and critical dialogue. - -With Sugar, we help learners *acquire knowledge* so that they grow as active consumers, critics, and *creators of knowledge*; Sugar welcomes them as members of a vibrant learning community. - -Plus, cross-community collaboration between technologists and teachers ensures that the ideals of student empowerment, freedom, sharing, open critique, and transparency will remain an integral part of Sugar—one that touches the lives of children and their communities all across the world’s classrooms. - -## The Free (Libre) Software culture -The Sugar pedagogy is embodied in the culture of Free/Libre Software; teachers and students are empowered with both the freedom to actively participate and the freedom to be critical. - -Criticism of ideas is a powerful force in learning, as well as in fostering economic development; unleashing this potential is an important part of our mission. diff --git a/src/constants/MarkdownFiles/more/markdown-test.md b/src/constants/MarkdownFiles/more/markdown-test.md deleted file mode 100644 index ccac4784..00000000 --- a/src/constants/MarkdownFiles/more/markdown-test.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 'Markdown Test Page' -slug: 'markdown-test' -category: 'MarkdownData' ---- -<!-- markdownlint-disable --> -# The Ultimate Markdown Test Document (NOTE: THIS IS AI GENERATED) - -## Basic Formatting - -This text is **bold** and this is *italic*. You can also have ~~strikethrough text~~ and ==highlighted text== for emphasis. - -You can add super^script^ and sub~script~ text when needed. - -## Links and Code - -Visit [our website](https://example.com) for more information. - -Here's some `inline code` within a paragraph for demonstration. - -### Code Block Example - -Below is an example of a JavaScript function: - -```javascript -// Returns a greeting for the provided name - -function greet(name) { - - return `Hello, ${name}!`; - -} - -console.log(greet("Markdown")); -``` - -## Lists - -### Unordered Lists - -- First item -- Second item -- Third item - -### Ordered Lists - -1. First ordered item -2. Second ordered item -3. Third ordered item - -### Task Lists - -- [ ] Uncompleted task -- [x] Completed task -- [ ] Another pending task - -## Tables - -| Feature | Supported | Notes | -|----------------|-----------|-------------------------------------| -| Headers | ✅ | With anchor links | -| Bold/Italic | ✅ | Basic formatting | -| Code Blocks | ✅ | With language support | -| Tables | ✅ | Responsive design | -| Lists | ✅ | Unordered, ordered, task lists | - -## Blockquotes with Proper Nesting - -> This is a simple blockquote. - -> This is a multi-line blockquote that continues on the next line. -> This is a multi-line blockquote that continues on the next line. - -## Images with Captions - - - -## Horizontal Rules - -Above this text is regular content. - ----- - -Below is separated by a horizontal rule. - -## Special Features - -### Collapsible Sections - -:::details Click to see hidden content -This content is hidden by default until the user clicks the summary. - -Here you can write additional **markdown content**, include lists, or even code. -Enjoy the hidden content! -::: - -### YouTube Embed - -[youtube: MM-H69cHYMk] - -### Emoji Support - -:smile: I'm happy to see this working! -:rocket: Let's launch this feature! -:warning: Be careful with this syntax. -:thumbsup: Looks good to me! -:heart: Love this feature! -:fire: This is awesome! -:star: Five-star quality! -:info: Here's some information. -:check: This is correct! -:x: This is wrong. - -## Combined Examples - -> This blockquote contains **bold text** and a [link](https://example.com) to example.com. - -- List item with **bold** and *italic* text. -- Item with a [link](https://example.com) and `inline code`. -- Item with ==highlighted text== that stands out. - -## Advanced Typography Test - -Water is H~2~O and an ordinal number like 5^th^ is very common. - -This paragraph includes ~~strikethrough text~~ and ==highlighted text== to denote important information. - -## Paragraphs with Line Breaks - -This is a paragraph with -line breaks that are preserved as spaces within the paragraph. - -This is another paragraph -after a blank line. - -### Final Thoughts - -This Markdown file has been designed to demonstrate multiple aspects of our custom Markdown parser. Every section shows different capabilities from formatting to embedded media. - -Thank you for reading this detailed Markdown test document! :heart: \ No newline at end of file diff --git a/src/constants/MarkdownFiles/more/parents.md b/src/constants/MarkdownFiles/more/parents.md deleted file mode 100644 index 9ed2e56d..00000000 --- a/src/constants/MarkdownFiles/more/parents.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Sugar Labs For Parents -slug: parents -author: Sugar Labs Team -lastUpdated: 2025-03-07 -category: Education ---- -<!-- markdownlint-disable --> - -## Background -The Sugar Learning Platform (Sugar) was first developed as the software platform for the One Laptop per Child (OLPC) program, a spin-off project from the MIT Media Lab in 2006. - -The founders of OLPC, Nicholas Negroponte, Seymour Papert, and Walter Bender, promoted the idea that learning is not a luxury and that a lack of an educated society is not just an inconvenience. Learning is fundamental to a free society that aspires to be both prosperous and sustainable. All societies value the role that education plays in economic development, and education is essential to the survival of democratic societies. - -Seymour Papert and Cynthia Solomon, co-inventors of the Logo programming language (along with Wally Feurzeig), described their pioneering efforts to use the Logo language as a vehicle for introducing children to computational thinking. They defined it in terms of heuristics: things to think with and reflect upon. - -In 1971, Papert and Solomon published *“20 Things to do with a Computer”*, a catalog of project ideas ranging from robotics to music to visual arts. This work foreshadowed what today is often referred to as the *Maker Movement*. Almost 50 years ago, children were using Logo as a tool for the autonomous construction of meaningful artifacts and pursuing mastery in solving personally meaningful problems. - ---- - -## Sugar Pedagogy -> **“Learning is hard fun.”** – Marvin Minsky -> **“A six-year-old child can become an expert.”** – Marvin Minsky - -In a 2008 essay questioning “general” education, Marvin Minsky proposed that we *“re-aim our schools towards encouraging children to pursue more focused hobbies and specialties—to provide them with more time for (and earlier experience with) developing more powerful sets of mental skills, which they later can extend to more academic activities.”* - -Minsky encourages children to construct multi-level *cognitive towers*, built upon: -- Instinctive reactions -- Learned reactions -- Deliberate thinking -- Reflective thinking -- Self-reflective thinking -- Self-conscious reflection - -These levels span agencies specializing in areas such as gaining knowledge from experience, planning and causal attribution, the construction of models, and identifying values and ideals. - -A focus on achieving meaningful goals—not just the accumulation of simple knowledge objects—exercises all levels in a cognitive tower, helping children *develop proficiencies that can be used in other domains*. As a model for learning, the levels within Minsky’s cognitive towers represent broadly applicable skills. - -Minsky’s towers are inherently complex and require a learner to be motivated and persistent in their construction—a process he once described as *"hard fun."* - -This aligns with research by Daniel Pink, who reviewed four decades of studies showing that motivation for learning comes from: -1. **Autonomy** – the freedom to explore and express ideas -2. **Mastery** – confidence and space to develop expertise -3. **Purpose** – authentic problem-solving opportunities - -A key insight of Minsky, Papert, and Solomon is to give children tools they can explore, master, and apply to problems they care about. Children using Sugar are **motivated learners**, pursuing meaningful goals that help them build their own “cognitive towers.” \ No newline at end of file diff --git a/src/constants/MarkdownFiles/more/school-admin.md b/src/constants/MarkdownFiles/more/school-admin.md deleted file mode 100644 index a381f558..00000000 --- a/src/constants/MarkdownFiles/more/school-admin.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Sugar Labs For School Administrators -slug: school-admin -author: Sugar Labs Team -lastUpdated: 2025-03-07 -category: Education ---- -<!-- markdownlint-disable --> - -## Student and teacher agency - -Sugar provides the user with affordances (things we designed for the possibility of taking action by the user) and pathways to engage in developing skills. Sugar is not instructional curricula in part because curricula tend to reflect very local norms and needs, and as a consequence, are resistant to global solutions. - -Also, Sugar reflects an explicit rejection of instruction as a pedagogical framework. With Sugar, we try to give agency to the learner, knowing that in all likelihood, the institution of school would likely be trying to take away agency. At each design decision point, we asked ourselves: -- *How will this impact the learning?* -- *How will this impact the autonomy and agency of the learner and the teacher?* - -Agency is made possible in part because of the choice of a software license, the **General Public License (GPL)**, which ensures that the learner has permission to both use Sugar and to modify it. - -We go a step further by giving the learner affordances to engage in software development and debugging, i.e., to exploit the license. We provide a context for encouraging the learner to take initiative, both by deliberately leaving the platform “incomplete” and by providing a social norm in which it is expected to take initiative. Even if it were possible to make Sugar “complete”, we would have chosen not to. We wanted there always to be “itches” needing to be scratched. - -In a related design decision, Sugar was never intended to be an endpoint in and of itself. Rather, we envisioned it as a waypoint along a lifelong journey of learning. We encourage our users to outgrow Sugar and even provide them with a means of advancing from the Sugar desktop, with its tools for exploration, to the **GNOME desktop**, with its more powerful tools for production. - ---- - -## What using Sugar can do for your students and school? - -The **Sugar Learning Platform** was designed to promote collaborative learning through tools and activities that encourage critical thinking. Sugar puts an emphasis on divergent thinking. A related goal is to make that thinking visible to the learner. - -Sugar equally promotes cultures of **expression and reflection**. With Sugar, we provide teachers and learners with a collection of open-ended tools and activities, applicable to problems of their own choosing. - -### Sugar offers an alternative to traditional “office-desktop” software based on three affordances: - -1. **Sharing:** - Collaboration is a first-order experience. The interface always shows the presence of other learners who are available for collaboration. Sugar allows users to dialog, support, critique, and share ideas with each other. - -2. **Reflecting:** - A "journal" records each learner’s activity. It is a built-in space for reflection and assessment of progress. - -3. **Discovering:** - Sugar tries to accommodate a wide variety of users with different levels of skill in terms of reading and language and different levels of experience with computing by providing activities with a "low floor" and, where possible, "no ceiling." - -> **“The only time collaboration is called cheating is when you are in school.” – Walter Bender** - -Sugar drew inspiration for its activities and the fluid interface between activities from observing how the **free software community** collaborates. Software developers chat, socialize, play games, share media, and collaborate on media creation and programming in both formal and informal settings. - -Sugar users are given access to a variety of commonly used tools for collaboration, e.g., **Chat and IRC**. By default, the IRC application opens into the `#sugar` channel on `irc.freenode.net`, where Sugar developers discuss their work. - ---- - -## Reflection and assessment in the context of Sugar and interoperability with school administrative systems - -In the early days of the development of the Sugar user interface, one of the biggest points of contention with the OLPC advisory board was when we told them that we were not going to use **file browsing** as the primary mode of navigation. We were asked, -*"How will the children learn to use Windows?"* -Our response was, *"Why do they need to learn to use Windows?"* - -Instead of browsing a filesystem, Sugar gives the user a **journal or notebook** into which one’s work is “kept” rather than “saved.” The interface tries to keep things that offer value automatically in the Sugar journal. - -The primary function of the journal is as a **time-based view** of the activities of a learner. As with physical media, such as pen on paper, no explicit "saving" step is needed. The individual journal entries are treated much like pages in a **laboratory notebook**. - -### Assessment in Sugar: -- **Digital Portfolio:** - Sugar journal entries are directly incorporated into **digital portfolios** to support reflection that can help students (as well as teachers and parents) be aware of their own learning. -- **Impact Measurement:** - Sugar acknowledges the need for **measurement and evaluation**. Sugar does not take a position on high-stake testing but advocates for an evaluation that looks more broadly than standardized tests. -- **Custom Metadata for Journal Entries:** - Teachers can know what tools a student may have used and how many iterations they made in creating an artifact. - ---- - -## Where to get resources? - -For more information, visit the **official Sugar Labs website** and explore its resources on **collaborative learning, development tools, and community support**. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/more/students.md b/src/constants/MarkdownFiles/more/students.md deleted file mode 100644 index 88b7bc3d..00000000 --- a/src/constants/MarkdownFiles/more/students.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Student Learning Goals and Sugar -slug: students -author: Sugar Labs Team -lastUpdated: 2025-03-07 -category: Education ---- -<!-- markdownlint-disable --> - -## Student Learning Goals and Sugar - -> *"Learning with Sugar is something a child does, not something that is done to or for a child." – Walter Bender* - -Sugar is a collection of hundreds of tools designed to introduce children to programming, computational thinking, and problem-solving. Sugar has no set curriculum; its best practice is to immerse children in problem-solving and debugging. Children are given agency to work on problems they are passionate about in a context where there is an expectation that there were no predetermined solutions or prescribed paths to a solution. - -As Solomon observed, *“debugging is the greatest learning opportunity of the 21st century.”* While engaged in problem-solving, children are developing and refining the algorithms employed by the agents in the various levels of their cognitive towers. - -While computation and coding are at the heart of Sugar, Sugar is not a programming curriculum: computational thinking goes well beyond the realm of learning to code. While the specific algorithms they discuss—searching, sorting, optimal stopping, predicting, etc.—are useful in and of themselves, the real power of computational thinking lies in its systematic approach to debugging and problem-solving. - -Learning that problems can be addressed systematically is the underlying **“powerful idea”** of programming. The process of writing and then repairing or **debugging** a program provides a basis for active learning through trial and error, regardless of what the problem that is actually being solved. - ---- - -## Learning with Pages in the Wiki - -These books are recommended as a rich source of ideas on how to use Sugar in and out of the classroom: - -- **Sdenka book** -- **Bender, W., Kane, C., Cornish, J., Donahue, N.** (2012). *Learning to Change the World: The Social Impact of One Laptop per Child.* Palgrave Macmillan. -- **Christian, B. and Griffiths, T.** (2016). *Algorithms to Live By: The Computer Science of Human Decisions.* Henry Holt and Co. -- **Hetland, L., Winner, E., Veenema S., and Sheridan, K.M.** (2007). *Studio Thinking: The Real Benefits of Visual Arts Education.* Teachers College Press. -- **Papert, S. & Solomon, C.** (1971). *Twenty Things to Do with a Computer.* *Artificial Intelligence Memo No. 248* and *Logo Memo No. 3.* -- **Pink, D.** (2009). *Drive: The Surprising Truth About What Motivates Us.* Riverhead Press. -- **Stefanakis, E.** (2002). *Multiple Intelligences and Portfolios: A Window into the Learner's Mind.* Greenwood Press. -- **Trinidad, G.** (2013). *Física con XO.* \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2008-05-15-New-foundation-focused-on-taking-the-Sugar-user-interface-to-the-next-level-of-usability-and-utility.md b/src/constants/MarkdownFiles/posts/2008-05-15-New-foundation-focused-on-taking-the-Sugar-user-interface-to-the-next-level-of-usability-and-utility.md deleted file mode 100644 index 87f129a1..00000000 --- a/src/constants/MarkdownFiles/posts/2008-05-15-New-foundation-focused-on-taking-the-Sugar-user-interface-to-the-next-level-of-usability-and-utility.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: "New foundation focused on taking the Sugar user interface to the next level of usability and utility" -category: "PRESS RELEASE" -date: "2008-05-15" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -Cambridge, Mass., May 15, 2008 — Sugar Labs Foundation is being established to further extend Sugar, the highly acclaimed open-source “learn learning” software platform originally developed for the One Laptop per Child (OLPC) XO laptop. Sugar is the core of the XO laptop’s human-computer interface; it provides a fun, easy-to-use, social experience that promotes sharing and learning. - -Sugar Labs will focus on providing a software ecosystem that enhances learning on the XO laptop as well as other laptops distributed by companies such as the ASUS Eee PC. Consistent with OLPC’s mission to provide opportunities for learning, an independent Sugar Labs Foundation can deliver learning software to other hardware vendors and, consequently, reach more children. - -Sugar Labs will take a proven learning concept to the next level of refinement, stability, and cohesiveness, and will be a unifying catalyst for free and open-source learning systems across multiple distribution and hardware platforms. The Labs will support a community of developers focused on learning, as well as support for the learners themselves. The Sugar platform has already been bundled with the most recent releases of the Ubuntu and Fedora GNU/Linux distributions. - -Walter Bender, former president of software and content at OLPC, is helping launch Sugar Labs, working closely with developers and community members from around the world who have played lead roles in developing the Sugar user interface (UI). Prior to OLPC, Bender was executive director and a founding member of the Media Lab at MIT. He has participated in much pioneering research in electronic publishing and personalized, interactive multimedia. - -In order to provide a rich learning experience to as many of the world’s children as possible, it is critical not just to provide computers to children, but also to ensure that the software maximizes their potential for engaging in learning activities: exploration, expression, and collaboration. By being independent of any specific hardware platform and by remaining dedicated to the principles of free and open-source software, Sugar Labs ensures that others can develop diverse interfaces and applications from which governments and schools can choose. An independent Sugar Labs ensures that the community can continue the development of a highly innovative interface that is already engaging children in learning in more than two dozen countries worldwide. - -“This is a very exciting time in the development of software for children’s education,” said Walter Bender. “In the first generation of the Sugar UI, the free and open-source community has demonstrated an exceptional ability to create a platform that enables children to explore the world, share their discoveries, and express themselves. As a separate foundation, we will be able to advance Sugar’s development even further and make it available on multiple distributions and hardware platforms.” - -Many of the core Sugar developers are participating in the launch, including Marco Pesenti Gritti, Bert Freudenberg, Simon Schampijer, Bernardo Innocenti, Aaron Kaplan, Christoph Derndorfer, and Tomeu Vizoso. - -Bert Freudenberg, one of the developers of the Etoys activity, commented, “Expanding Sugar to more hardware platforms gives a great boost to all developers of educational software. Sugar is the first system specifically aimed at helping children to learn while supporting a rich variety of contributed applications. As third-party developers, my colleagues at Viewpoints Research Institute look forward to a great relationship with Sugar Labs.” - -Tomeu Vizoso added, “Sugar has been brought to maturity by OLPC and a relatively small team of community supporters. The time has come to unlock Sugar’s potential as a global education project; the creation of Sugar Labs is the next step — expanding upon a project where people from all around the world can contribute to improving education, with the assurance that their efforts will be of benefit to everyone.” diff --git a/src/constants/MarkdownFiles/posts/2008-12-09-Sugar-Labs-joins-the-Software-Freedom-Conservancy.md b/src/constants/MarkdownFiles/posts/2008-12-09-Sugar-Labs-joins-the-Software-Freedom-Conservancy.md deleted file mode 100644 index 0f63fdb0..00000000 --- a/src/constants/MarkdownFiles/posts/2008-12-09-Sugar-Labs-joins-the-Software-Freedom-Conservancy.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: "Sugar Labs joins the Software Freedom Conservancy" -category: "PRESS RELEASE" -date: "2008-12-09" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -Boston, MA, December 9, 2008 — Sugar Labs today announced its membership in the Software Freedom Conservancy, an organization of free and open-source software projects. Sugar Labs supports the free and open-source desktop environment, Sugar, originally created for the One Laptop per Child Project (OLPC). The Sugar community now has an active global developer base that is focused on engaging young children in learning through computing and the Internet. As a member of the Conservancy, the Sugar community will work to accelerate the adoption of the Sugar learning platform and strengthen the project by attracting new industry members and community contributors. - -In May 2008, the Sugar project became independent of OLPC, making Sugar available to a wider community of developers and users. Subsequently, Sugar has been ported to Debian, Ubuntu, and other GNU/Linux distributions. Sugar can now run on almost any computer hardware. In October 2008, Sugar Labs released Sugar Version 0.82, which features enhanced usability and stability. In November, Sugar announced the availability of the pre-alpha version of “Sugar on a Stick,” a LiveUSB image of Sugar that gives children access to Sugar on any computer using just a USB key. Joining the Conservancy is an important milestone in the path toward making Sugar available to children everywhere. - -Founded in March 2006, the Conservancy allows developers of its member projects to unite under a common organization that provides much-needed administrative services. This structure spares each software project the burden of starting and maintaining its own independent non-profit organization. Sugar Labs has joined as the Conservancy’s fifteenth member project. diff --git "a/src/constants/MarkdownFiles/posts/2009-03-16-La-Asociaci\303\263n-sin-fines-de-lucro-Sugar-Labs-Anuncia-su-Nueva-Versi\303\263n-de-la-Plataforma-de-Aprendizaje-Sugar-para-Ni\303\261os-que-Funciona-en-Notebooks-y-PCs.md" "b/src/constants/MarkdownFiles/posts/2009-03-16-La-Asociaci\303\263n-sin-fines-de-lucro-Sugar-Labs-Anuncia-su-Nueva-Versi\303\263n-de-la-Plataforma-de-Aprendizaje-Sugar-para-Ni\303\261os-que-Funciona-en-Notebooks-y-PCs.md" deleted file mode 100644 index a3711dec..00000000 --- "a/src/constants/MarkdownFiles/posts/2009-03-16-La-Asociaci\303\263n-sin-fines-de-lucro-Sugar-Labs-Anuncia-su-Nueva-Versi\303\263n-de-la-Plataforma-de-Aprendizaje-Sugar-para-Ni\303\261os-que-Funciona-en-Notebooks-y-PCs.md" +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: "La Asociación sin fines de lucro Sugar Labs Anuncia su Nueva Versión de la Plataforma de Aprendizaje Sugar para Niños que Funciona en Notebooks y PCs" -category: "PRESS RELEASE" -date: "2009-03-16" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -[PDF](/assets/post-assets/press/SugarLabsPR_es_20090316.pdf) - -Cambridge, MA, March 16, 2009: Sugar Labs™ anuncia que la versión 0.84 de la Plataforma de Aprendizaje de Sugar para la XO-1 de OLPC, las PCs de aula y los notebooks ya se encuentra disponible. Diseñada desde un principio para los niños, el entorno Sugar es usado aproximadamente por un millón de estudiantes, cuyas edades fluctúan entre los 5 y 12 años, en aproximadamente 40 países durante todos los días del calendario escolar. Esta versión mejorada se caracteriza por poseer nuevas Actividades colaborativas. Asimismo, y en respuesta a la retroalimentación brindada por los docentes, posee la capacidad para detener y reanudar las Actividades con facilidad, lo cual permite ahorrar tiempo en el aula. - -Walter Bender, Director Ejecutivo de Sugar Labs, comentó lo siguiente: “Nos encontramos muy emocionados con este lanzamiento que funciona en un mayor número de PCs que antes y posee Actividades nuevas y únicas para que los niños investiguen juntos, tales como la Actividad Mapa Mental, una herramienta de pensamiento crítico que se usa para crear diagramas que representan conceptos e ideas que se encuentran relacionados y dispuestos alrededor de una palabra clave o de una idea central y la Actividad Portafolio, una herramienta de evaluación que brinda mayor facilitad para que tanto los docentes como los padres de familia revisen el progreso que realiza el niño.” - -Igualmente, el Diario Sugar, que proporciona un back up automático y el historial del trabajo de los estudiantes, posee nuevas características a fin de permitirles tomar apuntes o hacer comentarios respecto a su trabajo, así como volver a visitar y revisar proyectos anteriores. Por su parte, la nueva Actividad Infoslicer (Selecciona y Corta Información) permite a los docentes seleccionar el contenido de páginas Web con facilidad y rapidez para editarlo, organizarlo y distribuirlo como material pedagógico. De igual modo, para los estudiantes mayores que tienen curiosidad por saber cómo funcionan las computadoras, la función Vista de Código es actualmente general para todas las Actividades. - -La Plataforma de Aprendizaje Sugar es un software libre y de código abierto y se encuentra disponible para ser descargado en www.sugarlabs.org. Sugar, la interfaz originaria de la XO-1 de OLPC de uso diario en todo el mundo, ha sido traducida a 26 idiomas y tiene 50 idiomas más en proceso de traducción. El apoyo comunitario se encuentra disponible en línea las 24 horas al día/7 días a la semana. Sugar se encuentra disponible en las principales distribuciones GNU/Linux, las últimas computadoras con virtualización Apple Macintosh™ y las PCs Windows™ ejecutadas vía un Live CD de GNU/Linux que no modifica el disco duro. Igualmente, en el tercer trimestre del 2009, se ha programado el lanzamiento de Sugar en formato de tarjeta de memoria (memoria flash) extraíble, una versión de Live USB diseñada para simplificar el uso de Sugar en el aula. - -La plataforma de aprendizaje de Sugar forma parte de la colección permanente del Museo de Arte Moderno de Nueva York. Asimismo, en los International Design Excellence Awards ’08 (Premios Internacionales a la Excelencia en Diseño 2008) le fue otorgada una medalla de plata. Su innovador enfoque “centrado en el aprendizaje” ha recibido elogios por parte de los docentes a nivel mundial. Las Actividades de Sugar, exclusivas de la plataforma, permiten a los alumnos estudiar y crear juntos. Los estudiantes aprenden tanto del docente como de otros alumnos. - -El Sr. Bender comentó lo siguiente: “Sugar 0.84 representa un paso importante a medida que se trabaja para lograr la versión 1.0 de Sugar en formato de tarjeta de memoria extraíble que simplificará, en gran medida, la evaluación y el uso de Sugar en el aula. Asimismo, este formato de tarjeta de memoria extraíble hace posible que Sugar se ejecute a partir de un simple formato de memoria USB en casi cualquier computadora actual desde las notebooks (computadora portátil) hasta las desktops (computadora personal), así como en la mayoría de PCs más antiguas, sin interferir con las instalaciones de software preexistente.” - -“A medida que nos aproximamos al millón de niños “aprendiendo a aprender” con Sugar en la XO-1 de OLPC, solicitamos voluntarios que se unan a nosotros — un reto para los programadores, diseñadores, traductores e implementadores”, refirió el Sr. Bender. “Necesitamos especialmente probadores de software que nos ayuden a hacer de Sugar en formato de tarjeta de memoria extraíble una sólida solución que se encuentre disponible dondequiera que exista una computadora.” diff --git "a/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs,-organisation-\303\240-but-non-lucratif,-annonce-la-sortie-de-la-nouvelle-version-de-la-plateforme-d\342\200\231apprentissage-pour-enfants-Sugar-pour-PC-et-netbooks.md" "b/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs,-organisation-\303\240-but-non-lucratif,-annonce-la-sortie-de-la-nouvelle-version-de-la-plateforme-d\342\200\231apprentissage-pour-enfants-Sugar-pour-PC-et-netbooks.md" deleted file mode 100644 index d4a15c03..00000000 --- "a/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs,-organisation-\303\240-but-non-lucratif,-annonce-la-sortie-de-la-nouvelle-version-de-la-plateforme-d\342\200\231apprentissage-pour-enfants-Sugar-pour-PC-et-netbooks.md" +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: "Sugar Labs, organisation à but non lucratif, annonce la sortie de la nouvelle version de la plateforme d’apprentissage pour enfants Sugar pour PC et netbooks" -category: "PRESS RELEASE" -date: "2009-03-16" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - - -[PDF](/assets/post-assets/press/SugarLabsPR_fr_20090316.pdf) - -Cambridge, MA, le 16 mars 2009: Sugar Labs™ annonce la sortie de la version 0.84 de sa plateforme d’apprentissage Sugar destinée au XO-1 du projet One Laptop Per Child, aux micro-ordinateurs des établissements scolaires, et aux ordinateurs netbook. Conçu pour enfants de A à Z, l’environnement Sugar est utilisé par près d’un million d’élèves de 5 à 12 ans dans plus de 40 pays, tous les jours. Cette nouvelle version contient de nouvelles Activités Sugar à faire à plusieurs en travail collaboratif et, à la demande des professeurs, prévoit la possibilité d’interrompre et de reprendre facilement les Activités, pour gagner du temps en classe. - -Walter Bender, Directeur Exécutif de Sugar Labs, a dit: "Cette nouvelle version est compatible avec beaucoup plus de PC qu’auparavant, et contient de nouvelles Activités que les enfants adoreront découvrir ensemble, comme l’Activité Mindmap, un outil qui développe l’esprit critique et permet de créér des diagrammes représentant des mots et des idées à partir d’un mot-clé central, et l’Activité Portfolio, un outil d’évaluation permettant aux professeurs et aux parents d’établir très simplement les progrès réalisés par l’enfant. Le Journal Sugar, qui fournit une sauvegarde automatique et un historique du travail de l’élève, comporte de nouvelles fonctionnalités permettant aux élèves d’annoter plus facilement leurs travaux, et de reprendre ou réviser des projets déjà réalisés. La nouvelle activité Infoslicer permet aux professeurs de sélectionner rapidement et facilement du contenu pris sur internet, de le modifier et de le remettre en forme pour le redistribuer comme documents pédagogiques. Et pour les élèves plus grands qui veulent savoir comment marchent les ordinateurs, la fonction View Source (voir code source) a été généralisée à toutes les Activités.” - -La plateforme d’apprentissage Sugar est un logiciel libre. Elle peut être téléchargée sur le site www.sugarlabs.org. Interface d’origine du projet One Laptop Per Child déjà utilisé quotidiennement dans le monde entier, Sugar a déjà été traduite dans 26 langues et 50 autres doivent suivre. Un soutien technique de la communauté est disponible en ligne 24h/24, 7 jours/7. Sugar est disponible sur toutes les grandes distributions GNU/Linux, les ordinateurs Apple Macintosh™ récents avec virtualisation, et pour PC sous Windows™ via un liveCD GNU/Linux, qui ne touche pas au disque dur. Sugar on a Stick, une version liveUSB censée simplifier l’utilisation de Sugar en classe, doit sortir au 3e trimestre 2009. - -La plateforme d’apprentissage Sugar fait partie de la collection permanente du Musée d’Art Moderne de New York, et a reçu la médaille d’argent au Palmarès 2008 de l’excellence du design international (International Design Excellence Awards). Son approche innovante, centrée sur l’apprentissage, a été saluée par les enseignants du monde entier. Les Activités Sugar, disponibles exclusivement sur cette plateforme, permettent aux élèves d’étudier et de créér ensemble: les étudiants apprennent du professeur mais aussi les uns des autres. - -Selon M. Bender, “Sugar 0.84 est une étape importante vers la version 1.0 de Sugar on a Stick, qui va considérablement simplifier l’évaluation et l’utilisation de Sugar en classe. Avec Sugar on a Stick, on pourra lancer Sugar à partir d’une simple clé USB sur la plupart des ordinateurs récents, des netbooks aux ordinateurs de bureau, et aussi sur la plupart des vieux PC, sans perturber les logiciels déjà installés.” - -“Alors que nous nous approchons du millionième enfant “apprenant à apprendre” avec Sugar sur le XO-1 de One Laptop per Child, nous appelons de nouveau bénévoles à venir nous aider à relever ce défi éducatif: développeurs, concepteurs, traducteurs, et déployeurs”, a déclaré M. Bender. “Nous avons notamment besoin de testeurs pour nous aider à faire de Sugar on a Stick une solution robuste qui fonctionnera avec n’importe quel ordinateur.” diff --git a/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs-Nonprofit-Announces-New-Version-of-Sugar-Learning-Platform-for-Children,-Runs-on-Netbooks-and-PCs.md b/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs-Nonprofit-Announces-New-Version-of-Sugar-Learning-Platform-for-Children,-Runs-on-Netbooks-and-PCs.md deleted file mode 100644 index 93977c6a..00000000 --- a/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs-Nonprofit-Announces-New-Version-of-Sugar-Learning-Platform-for-Children,-Runs-on-Netbooks-and-PCs.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: "Sugar Labs Nonprofit Announces New Version of Sugar Learning Platform for Children, Runs on Netbooks and PCs" -category: "PRESS RELEASE" -date: "2009-03-16" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -[PDF](/assets/post-assets/press/SugarLabsPR_en_20090316.pdf) - -Cambridge, MA, March 16, 2009: Sugar Labs™ announces the availability of version 0.84 of the Sugar Learning Platform for the One Laptop Per Child XO-1, classroom PCs, and netbook computers. Designed from the ground up for children, the Sugar computer environment is used by almost one-million students aged 5 to 12 in over 40 countries every school day. This improved version features new collaborative Sugar Activities and, in response to teacher feedback, the ability to easily suspend and resume Activities, saving time in the classroom. - -Walter Bender, Executive Director of Sugar Labs, commented: “We’re excited about this release, which runs on more PCs than before and has great new Activities for kids to explore together such as a Mindmap Activity, a critical-thinking tool used to create diagrams representing words and ideas around a central keyword, and a Portfolio Activity, an assessment tool that makes it even simpler for teachers and parents to review a child’s progress. The Sugar Journal, which provides automatic backup and history of students’ work, has new features to make it easier for students to annotate their work and to revisit and revise past projects. The new Infoslicer Activity enables teachers to quickly and easily select web-based content to edit, package, and distribute as teaching materials. And for older students curious about how computers work, the View Source function is now universal to all Activities.” - -The Sugar Learning Platform is free open-source software; it is available for download at www.sugarlabs.org. The native interface of the One Laptop Per Child project’s XO-1 in daily use around the globe, Sugar has been translated into 26 languages with 50 more languages underway. 24/7 community support is available online. Sugar is available on major GNU/Linux distributions, recent Apple Macintosh™ computers with virtualization, and Windows™ PCs via a GNU/Linux liveCD, which doesn’t touch the hard disk. Sugar on a Stick, a liveUSB version designed to simplify classroom use of Sugar, is scheduled for release in Q3 2009. - -The Sugar Learning Platform is part of the permanent collection of the Museum of Modern Art in New York and was awarded a silver medal in the International Design Excellence Awards ’08. Its innovative “learning-centric” approach has earned praise from educators worldwide. Sugar Activities, unique to the platform, allow students to study and create together; students learn both from the teacher and from each other. - -Mr. Bender commented, “Sugar 0.84 is an important step as we work toward version 1.0 of Sugar on a Stick, which will greatly simplify evaluation and use of Sugar in the classroom. Sugar on a Stick will start Sugar from a simple USB memory stick on nearly any recent computer from netbooks to desktops, and most older PCs as well, without interfering with pre-existing software installations.” - -“As we approach the one-millionth child ‘learning to learn’ with Sugar on the OLPC XO-1, we call for volunteers to join us—a challenge to educate for developers, designers, translators, and deployers,” Mr. Bender said. “In particular, we need testers to help us make Sugar on a Stick a robust solution available anywhere there is a computer.” diff --git "a/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs-k\303\274ndigt-neue-Version-von-Sugar-an\342\200\224die-Lernplattform-f\303\274r-Kinder-l\303\244uft-auf-Netbooks-und-PCs.md" "b/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs-k\303\274ndigt-neue-Version-von-Sugar-an\342\200\224die-Lernplattform-f\303\274r-Kinder-l\303\244uft-auf-Netbooks-und-PCs.md" deleted file mode 100644 index dcad9a0b..00000000 --- "a/src/constants/MarkdownFiles/posts/2009-03-16-Sugar-Labs-k\303\274ndigt-neue-Version-von-Sugar-an\342\200\224die-Lernplattform-f\303\274r-Kinder-l\303\244uft-auf-Netbooks-und-PCs.md" +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: "Sugar Labs kündigt neue Version von Sugar an—die Lernplattform für Kinder läuft auf Netbooks und PCs" -category: "PRESS RELEASE" -date: "2009-03-16" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -[PDF](/assets/post-assets/press/SugarLabsPR_de_20090316.pdf) - -Cambridge, MA, 16. März, 2009: Sugar Labs™ hat die Version 0.84 der Lernplattform Sugar freigegeben. Die Software ist auf dem XO-1 von One Laptop Per Child, PCs und Netbooks einsetzbar. Die speziell für Kinder entwickelte Plattform wird von fast einer Million Schülern im Alter von 5 bis 12 Jahren in über 40 Ländern täglich im Schulunterricht eingesetzt. - -Walter Bender, Geschäftsführer von Sugar Labs, sagt hierzu: “Wir sind gespannt auf die neue Version, die auf mehr PCs läuft als zuvor und neue, interessante Activities zum gemeinsamen Erkunden beinhaltet. Zum Beispiel die Mindmap Activity, ein Werkzeug zum Erstellen von Diagrammen, die Beziehungen zwischen einem Schlüsselwort und diesem zugeordneten Begriffen aufzeigen. Oder die Portfolio Activity, ein Bewertungswerkzeug, das es Lehrern und Eltern einfacher macht, den Fortschritt eines Kindes zu beurteilen. Das Journal, eine Art Tagebuch, das dem Schüler die chronologische Aufzeichnung seiner Aktivitäten bereitstellt, wurde erweitert. Der Schüler hat es nun leichter seine Arbeiten zu kommentieren und seine Projekte zu überarbeiten. Die neue Infoslicer Activity ermöglicht es Lehrern, schnell und einfach web-basierte Inhalte zu editieren, zusammenzustellen und als Lehrmaterial bereitzustellen. Schüler, die an der Funktionsweise eines Computers interessiert sind, können die View Source Funktion nutzen um tiefere Einblicke zu erhalten. Außerdem wurde in der Entwicklung der Software auf Verbesserungsvorschläge von Lehrern eingegangen. So ist es nun einfacher, vorangegangene Activities fortzuführen, wodurch im Unterricht Zeit eingespart werden kann. - -Die Lernplattform Sugar ist Open Source Software und kann von www.sugarlabs.org heruntergeladen werden. Sugar wurde in 26 Sprachen übersetzt und 50 weitere Übersetzungen sind in Bearbeitung. Die Sugar-Gemeinschaft ist Online immer für Fragen und Anregungen offen. Die Plattform ist erhältlich in allen größeren Linux-Distributionen. Sugar kann als Live-System unter Windows™ von einem CD-Image gestartet werden und kann auf Apple Macintosh™ Computern virtualisiert ausgeführt werden. Sugar on a Stick, ein Live-System, das von USB-Speichermedien gestartet wird, und den Einsatz in Computerlaboren erleichtern soll, wird voraussichtlich im dritten Quartal von 2009 erscheinen. - -Die Lernplattform Sugar ist Teil der ständigen Ausstellung des Museum of Modern Art in New York. 2008 erhielt sie die Silber-Medaille des International Design Excellence Awards in der Kategorie Interactive Product Experiences. Ihr innovativer lernorientierter Ansatz erhielt weltweites Lob von Pädagogen. Sugar Activities, die einmalig für diese Plattform sind, ermöglichen es den Schülern gemeinsam zu lernen und kreativ zu werden, Schüler können sowohl von ihrem Lehrer als auch voneinander lernen. - -Bender fügt hinzu: “Sugar 0.84 ist ein wichtiger Schritt im Hinblick auf die Version 1.0 von Sugar on a Stick, die die Evaluation und die Anwendung von Sugar im Unterricht vereinfachen wird. Sugar on a Stick lädt Sugar von einem USB-Speichermedium auf nahezu jedem gängigen Computer, ob Netbook oder Desktop PC, ohne dabei mit der bereits installierten Software in Konflikt zu geraten.” - -“Weil bald das millionste Kind mit Sugar auf dem OLPC XO-1 ‘lernt zu lernen’ laden wir alle Freiwilligen dazu ein, mitzumachen—eine Herausforderung für Entwickler, Pädagogen, Designer, Übersetzer und Anwender,” sagt Bender. “Vor allem brauchen wir Software-Tester, die uns helfen aus Sugar on a Stick eine Alternative zu vorhandener Software auf allen verfügbaren Computern zu machen.” diff --git "a/src/constants/MarkdownFiles/posts/2009-04-22-Sugar-Labs-Announces-Beta\342\200\2211-of-Sugar-on-a-Stick,-LiveUSB-Version-of-Sugar-Learning-Platform-for-Children.md" "b/src/constants/MarkdownFiles/posts/2009-04-22-Sugar-Labs-Announces-Beta\342\200\2211-of-Sugar-on-a-Stick,-LiveUSB-Version-of-Sugar-Learning-Platform-for-Children.md" deleted file mode 100644 index 55b3c19a..00000000 --- "a/src/constants/MarkdownFiles/posts/2009-04-22-Sugar-Labs-Announces-Beta\342\200\2211-of-Sugar-on-a-Stick,-LiveUSB-Version-of-Sugar-Learning-Platform-for-Children.md" +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: "Sugar Labs Announces Beta‑1 of Sugar on a Stick, LiveUSB Version of Sugar Learning Platform for Children" -category: "PRESS RELEASE" -date: "2009-04-22" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -[PDF](/assets/post-assets/press/SugarLabsPR_en_20090422.pdf) - -Cambridge, MA, April 22, 2009: Sugar Labs™ announces the availability for testing of Sugar on a Stick Beta‑1. This version of the free open-source Sugar Learning Platform, available at [www.sugarlabs.org](http://www.sugarlabs.org) for loading on any 1 Gb or greater USB stick, is designed to facilitate exploration of the award-winning Sugar interface beyond its original platform, the One Laptop per Child XO‑1, to such varied hardware as aging PCs and recent Macs to the latest netbooks. - -Teachers and parents interested in trying Sugar with children can download the Sugar on a Stick beta‑1 file from the Sugar Labs website and load it onto a USB stick by following the instructions at [wiki.sugarlabs.org/go/Sugar_on_a_Stick](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick). - -Walter Bender, Executive Director of Sugar Labs, said: “Sugar is perfectly suited for children in the classroom with its simple, colorful interface, built-in collaboration, and open architecture. Sugar on a Stick lets you start a computer with Sugar and store a child’s data on the stick without touching the host computer’s hard disk. Sugar’s Activities such as Write, a shared word processor, and the recently announced InfoSlicer Activity, which enables teachers to easily collect and package web-based content for the classroom, benefit fully from Sugar’s collaboration features.” - -Caroline Meeks of Solution Grove ([www.solutiongrove.com](http://www.solutiongrove.com)), the Sugar on a Stick project manager, commented: “We’re counting on teachers to help us improve Sugar on a Stick as we work towards our Version‑1 release scheduled for Q3 2009. We just presented Sugar on a Stick at the FOSS VT conference (<http://www.ncose.org/node/47>) where it generated great interest, and our real-world tests at local sites with varied aging PCs have been very encouraging.” - -Sugar testers are invited to send bug information and constructive criticism to [feedback@sugarlabs.org](mailto:feedback@sugarlabs.org). “We won’t be able to reply to every message,” continued Ms. Meeks, “but we will read every one in order to make Sugar on a Stick a reliable learning tool in budget-stretched classrooms by the fall.” diff --git "a/src/constants/MarkdownFiles/posts/2009-04-22-Sugar-Labs-annonce-la-b\303\252ta-1-de-Sugar-on-a-Stick,-version-LiveUSB-de-Sugar,-la-plate-forme-d\342\200\231apprentissage-pour-enfants.md" "b/src/constants/MarkdownFiles/posts/2009-04-22-Sugar-Labs-annonce-la-b\303\252ta-1-de-Sugar-on-a-Stick,-version-LiveUSB-de-Sugar,-la-plate-forme-d\342\200\231apprentissage-pour-enfants.md" deleted file mode 100644 index 6f0417e3..00000000 --- "a/src/constants/MarkdownFiles/posts/2009-04-22-Sugar-Labs-annonce-la-b\303\252ta-1-de-Sugar-on-a-Stick,-version-LiveUSB-de-Sugar,-la-plate-forme-d\342\200\231apprentissage-pour-enfants.md" +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: "Sugar Labs annonce la bêta-1 de Sugar on a Stick, version LiveUSB de Sugar, la plate-forme d’apprentissage pour enfants" -category: "PRESS RELEASE" -date: "2009-04-22" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - - -[PDF](/assets/post-assets/press/SugarLabsPR_fr_20090422.pdf) - -Cambridge, MA, April 22, 2009: Sugar Labs™ annonce la disponibilité pour tests de la version Bêta-1 de Sugar on a Stick. Cette version du logiciel libre Sugar Learning Platform, disponible sur www.sugarlabs.org pour téléchargement dans n’importe quelle clef USB de 1 Go ou plus, a été conçue pour permettre d’explorer la célèbre interface Sugar au-delà de sa plate-forme d’origine, le XO-1 de One Laptop per Child, sur toutes sortes d’ordinateurs, des PCs anciens aux Macintosh récents en passant par les nouveaux netbooks. - -Les enseignants et parents qui veulent essayer Sugar avec des enfants peuvent télécharger le fichier bêta-1 de Sugar on a Stick sur le site web de Sugar Labs et le charger sur une clef USB en suivant les instructions sur [wiki.sugarlabs.org/go/Sugar_on_a_Stick](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick). - -Walter Bender, le directeur exécutif de Sugar Labs, a dit : “Sugar est parfaitement adapté aux élèves avec son interface simple et vivante, pensée pour le travail en commun, et avec son architecture ouverte. Sugar on a Stick vous permet de démarrer un ordinateur avec Sugar et de stocker les données de l’enfant dans la clef sans toucher au disque dur de l’ordinateur hôte. Les Activités de Sugar telles que Write, un traitement de texte partagé, et l’Activité InfoSlicer annoncé récemment, qui permet aux enseignants de collectionner et réunir facilement des contenus du web pour la classe, bénéficient pleinement des caractéristiques collaboratives de Sugar.” - -Caroline Meeks de Solution Grove ([www.solutiongrove.com](http://www.solutiongrove.com)), gestionnaire du projet Sugar on a Stick, a commenté : “Nous comptons sur les enseignants pour nous aider à améliorer Sugar on a Stick tandis que nous continuons à travailler sur la Version-1 prévue pour le troisième trimestre 2009. Nous venons de présenter Sugar on a Stick à la conférence FOSS VT (<http://www.ncose.org/node/47>) où il a suscité beaucoup d’intérêt, et nos tests sur le terrain avec des PCs variés et anciens ont été très encourageants.” - -Les testeurs de Sugar sont invités à envoyer des informations sur tout bogue et autres critiques constructives à l’adresse suivante : [feedback@sugarlabs.org](mailto:feedback@sugarlabs.org). “Nous ne pourrons pas répondre à chaque message,” a continué Mme Meeks, “mais nous allons lire chacun afin de rendre Sugar on a Stick un outil fiable dans les classes qui manquent de ressources d’ici la rentrée.” diff --git a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-Announces-Immediate-Availability-of-Sugar-on-a-Stick;-Learning-Platform-Runs-on-Any-PC-or-Netbook-In-The-Classroom.md b/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-Announces-Immediate-Availability-of-Sugar-on-a-Stick;-Learning-Platform-Runs-on-Any-PC-or-Netbook-In-The-Classroom.md deleted file mode 100644 index 43bd9262..00000000 --- a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-Announces-Immediate-Availability-of-Sugar-on-a-Stick;-Learning-Platform-Runs-on-Any-PC-or-Netbook-In-The-Classroom.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: "Sugar Labs Announces Immediate Availability of Sugar on a Stick; Learning Platform Runs on Any PC or Netbook In The Classroom" -category: "PRESS RELEASE" -date: "2009-06-24" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -LinuxTag, Berlin, June 24, 2009: Sugar Labs™, nonprofit provider of the Sugar Learning Platform to over one-million children worldwide, announces the immediate availability of Sugar on a Stick v1 Strawberry. Available free for download at [www.sugarlabs.org](http://www.sugarlabs.org), Sugar on a Stick can be loaded onto an ordinary 1GB USB flash drive and used to reboot any PC or netbook directly into the award-winning Sugar environment. It runs on recent Macs with a helper CD and in Windows using virtualization. Sugar on a Stick is designed to work with a School Server that can provide content distribution, homework collection, backup services, Moodle integration, and filtered access to the Internet. Today’s Strawberry release is meant for classroom testing; [feedback](mailto:feedback@sugarlabs.org) will be incorporated into the next version, available towards the end of 2009. - -“One year after its founding, Sugar Labs is delivering on its education promise for its second million learners,” commented Walter Bender, founder and executive director. “Sugar is preferred because it is a superior learning experience for young children: engaging while being affordable. Sugar on a Stick is a great way to try Sugar without touching your computer’s hard disk. It is also well suited to slower, older PCs and low-powered netbooks. There is a version for the OLPC XO-1 and it will ship with the newer XO-1.5 laptops in the fall.” - -Sugar on a Stick provides a coherent and consistent computing experience. It reduces costs by providing flexibility in hardware choices, allowing schools to keep their existing investment in hardware. Learners can benefit from the increased household ownership of computers; by bringing Sugar on a Stick home, every student has a consistent, comparable computing environment that parents can share in as well. It also provides off-line access to applications and content as not every learner has Internet access at home. - -As part of an ongoing effort to make Sugar on a Stick classroom-ready, Sugar Labs has been awarded a $20,000 grant from the Gould Charitable Foundation to implement Sugar at the Gardner Pilot Academy, a public elementary school located in one of the most culturally and linguistically diverse sections of Boston, Massachusetts. - -Learning Activities are at the heart of Sugar. Sugar on a Stick includes 40 Activities to interest young learners such as Read, Write, Paint, and Etoys. Hundreds more Activities are available free for download at the [Sugar Activity Library](http://activities.sugarlabs.org). Most “Sugarized” Activities have student collaboration built-in; students and teachers work, play, and learn on the same Activities together. The Sugar Learning Platform is open, so by leveraging the work of other open source projects, existing software for children can be integrated; for example, the acclaimed GCompris suite of 100 Activities developed over the past five years by Bruno Coudoin was recently added to Sugar, including Activities such as Chess, Geography, and Sudoku. Teachers and parents interested in Sugar’s Activities and its modern interface for children can watch short videos on the recently opened [Sugar Labs Dailymotion channel](http://www.dailymotion.com/sugarlabs). - -Visitors to LinuxTag are welcome to speak with Sugar Labs contributors at booth 7.2a 110a. diff --git "a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-annonce-la-disponibilit\303\251-imm\303\251diate-de-\302\253-Sugar-on-a-Stick-\302\273,-une-plate-forme-d\342\200\231apprentissage-qui-fonctionne-sur-n\342\200\231importe-quel-PC-ou-netbook-dans-la-salle-de-classe.md" "b/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-annonce-la-disponibilit\303\251-imm\303\251diate-de-\302\253-Sugar-on-a-Stick-\302\273,-une-plate-forme-d\342\200\231apprentissage-qui-fonctionne-sur-n\342\200\231importe-quel-PC-ou-netbook-dans-la-salle-de-classe.md" deleted file mode 100644 index f2ce0ef9..00000000 --- "a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-annonce-la-disponibilit\303\251-imm\303\251diate-de-\302\253-Sugar-on-a-Stick-\302\273,-une-plate-forme-d\342\200\231apprentissage-qui-fonctionne-sur-n\342\200\231importe-quel-PC-ou-netbook-dans-la-salle-de-classe.md" +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: "Sugar Labs annonce la disponibilité immédiate de « Sugar on a Stick », une plate-forme d’apprentissage qui fonctionne sur n’importe quel PC ou netbook dans la salle de classe" -category: "PRESS RELEASE" -date: "2009-06-24" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - - -LinuxTag, Berlin, 24 Juin 2009: Sugar Labs™, fournisseur à but non-lucratif de la plate-forme pédagogique Sugar à plus d’un million d’enfants dans le monde, annonce la disponibilité immédiate de « Sugar on a Stick v1 Strawberry » (« Bâtonnet de Sucre v1 Fraise »). Logiciel libre disponible en téléchargement gratuit sur [www.sugarlabs.org](http://www.sugarlabs.org), Sugar on a Stick peut être chargé sur une clef USB 1Gb ordinaire et utilisée pour rebooter n’importe quel PC ou netbook dans l’environnement Sugar. Celui-ci tourne sur les Macs récents avec un CD de support et dans Windows en utilisant la virtualisation. Sugar on a Stick est conçu pour marcher avec un serveur d’école qui peut dispenser des contenus, des collections de devoirs à la maison, des services de sauvegarde, l’intégration de Moodle, et un filtrage de l’accès à internet. La version « Fraise » d’aujourd’hui est destinée à être testée dans la salle de classe ; les [retours d’expérience](mailto:feedback@sugarlabs.org) seront intégrés dans la prochaine version, disponible vers la fin 2009. - -« Un an après sa fondation, Sugar Labs tient ses promesses pédagogiques pour son second million d’apprenants », commente Walter Bender, fondateur et directeur exécutif. « Sugar est choisi parce qu’il permet une expérience d’apprentissage supérieure pour les jeunes enfants qui l’explorent, tout en étant abordable. Sugar on a Stick est une formidable manière de tester Sugar sans toucher au disque dur de votre ordinateur. C’est aussi bien adapté aux ordinateurs plus lents, aux vieux PCs et aux netbooks peu puissants. Il y a une version pour le XO-1 d’OLPC et cela sera expédié avec les nouveaux XO-1.5 à partir de l’automne. » - -Sugar on a Stick fournit une expérience informatique cohérente et conforme. Il réduit les coûts en rendant souple les choix des matériels, permettant aux écoles de conserver leur investissement existant en matériel. Les apprenants peuvent bénéficier du taux grandissant des ordinateurs familials ; en rentrant à la maison avec Sugar on a Stick, chaque étudiant possède son environnement habituel que les parents peuvent partager aussi. Il fournit aussi un accès différé aux applications et contenus, utile pour des apprenants dépourvus d’un accès Internet à la maison. - -L’effort pour rendre Sugar on a Stick prêt pour la salle de classe continue ; Sugar Labs a décerné une subvention de $20.000 de la Gould Charitable Foundation pour implémenter Sugar au Gardner Pilot Academy, une école primaire publique située dans un quartier populaire et multiculturel de Boston dans l’état de Massachusetts. - -Les Activités pour apprendre sont au cœur de Sugar. Sugar on a Stick est fourni avec 40 Activités intéressantes pour des jeunes apprenants tels que Lire, Écrire, Dessiner, et EToys. Des centaines d’autres Activités sont disponibles gratuitement sur la [Bibliothèque d’Activités Sugar](http://activities.sugarlabs.org). La plupart d’activités « sucrées » offrent la collaboration en natif ; les étudiants et enseignants travaillent, jouent, et apprennent ensemble sur les mêmes Activités. La plate-forme d’apprentissage Sugar est ouverte et bénéficie des travaux d’autres projets ; des logiciels existants peuvent être intégrés. Par exemple, plus de 100 activités tels que Échecs, Géographie, et Sudoku de la suite acclamée GCompris développée depuis cinq ans par Bruno Coudoin ont été ajoutés récemment à Sugar. Des enseignants et parents qui s’intéressent aux activités de Sugar et à son interface moderne pour enfants peuvent visionner de courtes vidéos sur le nouveau canal [Dailymotion de Sugar Labs](http://www.dailymotion.com/sugarlabs). - -Les visiteurs à LinuxTag sont invités à dialoguer avec des contributeurs de Sugar Labs au stand 7.2a 110a. diff --git "a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-annuncia-l\342\200\231immediata-disponibilit\303\240-di-Sugar-on-a-Stick;-La-Piattaforma-di-Apprendimento-in-grado-di-funzionare-su-qualsiasi-PC-o-Netbook-disponibile-in-classe.md" "b/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-annuncia-l\342\200\231immediata-disponibilit\303\240-di-Sugar-on-a-Stick;-La-Piattaforma-di-Apprendimento-in-grado-di-funzionare-su-qualsiasi-PC-o-Netbook-disponibile-in-classe.md" deleted file mode 100644 index f8f45335..00000000 --- "a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-annuncia-l\342\200\231immediata-disponibilit\303\240-di-Sugar-on-a-Stick;-La-Piattaforma-di-Apprendimento-in-grado-di-funzionare-su-qualsiasi-PC-o-Netbook-disponibile-in-classe.md" +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: "Sugar Labs annuncia l’immediata disponibilità di Sugar on a Stick; La Piattaforma di Apprendimento in grado di funzionare su qualsiasi PC o Netbook disponibile in classe" -category: "PRESS RELEASE" -date: "2009-06-24" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -Berlino, 24 Giugno, 2009: Sugar Labs, la realtà no-profit che ha sviluppato la Piattaforma di Apprendimento Sugar (Sugar Learning Platform) utilizzata da più di un milione di bambini nel mondo intero, annuncia l’immediata disponibilità di "Sugar on a Stick" v1 Strawberry. Disponibile in forma libera e gratuita dal sito [www.sugarlabs.org](http://www.sugarlabs.org), Sugar on a Stick può essere caricato su una normale chiavetta USB da almeno 1Gb e utilizzandola per avviare direttamente il sistema Sugar in qualunque PC o netbook. Può essere utilizzato anche sui più recenti sistemi Mac con l’ausilio di un CD di avvio, e all’interno di sistemi Windows attraverso la virtualizzazione. “Sugar on a Stick” è stato progettato per l’utilizzo insieme ad uno School Server che fornisce distribuzione di contenuti, raccolta di elaborati, servizi di backup, integrazione con la piattaforma Moodle, e accesso protetto ad Internet. La versione odierna di “Sugar on a Stick” v1 Strawberry è pensata per la sperimentazione in classe ([feedback](mailto:feedback@sugarlabs.org)); la prossima versione sarà rilasciata entro la fine del 2009. - -"Ad un anno dalla fondazione, Sugar Labs sta rilasciando quanto promesso per il suo secondo milione di studenti" commenta Walter Bender, fondatore e direttore esecutivo. "Sugar viene preferito perché offre grandi opportunità educative ai giovani allievi: attraente e di facile approccio. Sugar on a Stick è un modo eccezionalmente semplice per provare Sugar senza dover installare nulla sul proprio computer. Si tratta inoltre di una soluzione ottima per computer vecchi, lenti o per netbook non particolarmente potenti. Esiste una versione specifica per OLPC XO-1 e questa sarà la versione distribuita con i nuovi XO-1.5 laptop a partire dal prossimo autunno." - -Sugar on a Stick fornisce un ambiente coerente e consistente per le attività. Permette una riduzione di costi offrendo adattabilità a molteplici soluzioni hardware, permettendo alle scuole di conservare e riutilizzare gli investimenti in hardware effettuati nel passato. Gli studenti potranno beneficiare della accresciuta possibilità di utilizzare anche a casa i propri strumenti didattici; portando a casa “Sugar on a Stick”, ogni studente ritroverà il proprio ambiente di lavoro scolastico abituale, anche utilizzando computer di famigliari. Permetterà inoltre ad ogni utilizzatore di continuare a utilizzare le proprie applicazioni e contenuti anche off-line, posto che non tutti possano disporre di connessioni ad internet a casa. - -Come supporto allo sforzo di rendere “Sugar on a Stick” pronto per l’utilizzo in classe, Sugar Labs ha ricevuto un sussidio di $20,000 da parte della Gould Charitable Foundation per rilasciare Sugar presso la Gardner Pilot Academy, una scuola elementare pubblica situata in una delle aree di Boston, Massachusetts, caratterizzata da una grande varietà culturale e linguistica. - -Le Attività di Apprendimento sono il cuore di Sugar. “Sugar on a Stick” include 40 attività preinstallate per catturare l’interesse dei giovani studenti, fra queste Leggi, Scrivi, Disegna, e l’ambiente Etoys. Altre centinaia di attività sono disponibili per essere liberamente scaricate dalla [Sugar Activity Library](http://activities.sugarlabs.org). La maggior parte delle attività "Sugarized" possiedono funzionalità di collaborazione native; gli studenti ed i docenti possono lavorare, giocare ed imparare tutti insieme condividendo le stesse attività. La “Sugar Learning Platform” è aperta, quindi approfittando del lavoro di altri progetti OpenSource, software didattico per bambini già esistente può essere integrato; per esempio, la famosa suite GCompris comprendente più di 100 attività didattiche e ludiche sviluppata nel corso degli scorsi cinque anni da Bruno Coudoin è stata recentemente integrata, comprendendo fra le altre Attività come Scacchi, Geografia e Sudoku. Docenti e genitori interessati a valutare le attività di Sugar e la sua innovativa interfaccia utente specificamente progettata per i bambini possono visionare i filmati disponibili sul canale recentemente attivato da [Sugar Labs su Dailymotion](http://www.dailymotion.com/sugarlabs). - -I partecipanti a LinuxTag sono caldamente invitati ad incontrare i collaboratori di Sugar Labs presso lo stand 7.2a 110a. diff --git "a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-anuncia-la-disponibilidad-inmediata-de-Sugar-On-A-Stick-(Sugar-en-un-pendrive).-El-plataforma-de-aprendizaje-funciona-en-casi-cualquier-PC-o-port\303\241til.md" "b/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-anuncia-la-disponibilidad-inmediata-de-Sugar-On-A-Stick-(Sugar-en-un-pendrive).-El-plataforma-de-aprendizaje-funciona-en-casi-cualquier-PC-o-port\303\241til.md" deleted file mode 100644 index 705e7999..00000000 --- "a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-anuncia-la-disponibilidad-inmediata-de-Sugar-On-A-Stick-(Sugar-en-un-pendrive).-El-plataforma-de-aprendizaje-funciona-en-casi-cualquier-PC-o-port\303\241til.md" +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: "Sugar Labs anuncia la disponibilidad inmediata de Sugar On A Stick (Sugar en un pendrive). El plataforma de aprendizaje funciona en casi cualquier PC o portátil que hay en el aula." -category: "PRESS RELEASE" -date: "2009-06-24" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -LinuxTag, Berlín, 24 de junio de 2009: Sugar Labs™, proveedor sin fines de lucro de la plataforma de aprendizaje de Sugar a más de un millón de niños en todo el mundo, anuncia la disponibilidad inmediata de Sugar on a Stick (SoaS) v1 Strawberry (Fresa). Disponible para su descarga gratuita en [www.sugarlabs.org](www.sugarlabs.org), SoaS se puede cargar en una pendrive USB de 1 GB y se utiliza para reiniciar casi cualquier PC, o usar directamente en el portátil y entrar a Sugar, el ambiente premiado de aprendizaje. Funciona en los últimos equipos Mac con la ayuda de un CD y en Windows usando la virtualización. - -Sugar on a Stick está diseñado para trabajar con un servidor de colegio que puede proporcionar la distribución de contenidos, el recojo de tareas, los servicios de copia de seguridad, la integración de Moodle y la filtración del acceso a Internet. El Strawberry de hoy está listo para probarse en las escuelas. [Comentarios](mailto:feedback@sugarlabs.org) se incorporarán en la próxima versión, disponible a finales de 2009. - -"Un año después de su fundación, Sugar Labs está cumpliendo su promesa de educación para su segundo millón de estudiantes", comentó Walter Bender, fundador y director ejecutivo. "Sugar es preferido porque ofrece una excelente experiencia de aprendizaje para los niños pequeños: divertida y económica. Sugar on a Stick es una gran manera de probar Sugar sin tocar el disco duro de la computadora. También es muy adecuado para las computadoras más lentas, más antiguas y para las portátiles pequeñas de baja potencia. Existe una versión para la OLPC XO-1 y se suministrará con las nuevas computadoras portátiles XO-1.5 en el otoño." - -Sugar on a Stick ofrece una experiencia coherente y consistente. Reduce costos, proporcionando flexibilidad en opciones de tipos de computadoras, permitiendo que las escuelas mantengan sus inversiones existentes en sus aparatos. Para los que tienen computadora en casa, pueden llevar el Sugar on a Stick consigo. Cada estudiante tiene un ambiente de computación coherente y comparable que los padres pueden compartir también. Además, proporciona acceso fuera de línea a aplicaciones y contenido para los alumnos que no tienen acceso a Internet en casa. - -Como parte de un esfuerzo continuo para hacer Sugar on a Stick listo para las aulas, Sugar Labs ha recibido una subvención de 20.000 dólares de la Fundación de Beneficencia Gould para aplicar un proyecto piloto de Sugar en la Academia Gardner, una escuela primaria ubicada en una de las más cultural y lingüísticamente diversas secciones de Boston, Massachusetts. - -Actividades dirigidas al aprendizaje están en el corazón de Sugar. Sugar on a Stick incluye 40 actividades de interés para los jóvenes estudiantes tales como Leer, Escribir, Pintura y Etoys. Cientos de actividades están disponibles para su descarga gratuita en la [biblioteca de Actividades de Sugar](http://activities.sugarlabs.org). La mayoría de las actividades "Sugarized" han incorporado la colaboración de estudiantes. Los alumnos y profesores trabajan, juegan y aprenden juntos en las mismas actividades. - -La plataforma de aprendizaje de Sugar es abierta. Por lo tanto, Sugar utiliza el trabajo de otros proyectos de código abierto. El software existente para los niños se puede integrar a Sugar. Por ejemplo, el reconocido GCompris, junto con 100 actividades desarrolladas en los últimos cinco años por Bruno Coudoin, fueron añadidos recientemente a Sugar; incluye actividades como Ajedrez, Geografía y Sudoku. Los maestros y padres de familia interesados en las Actividades de Sugar y su interfaz moderna pueden ver videos cortos en el recientemente inaugurado canal de [Sugar Labs Dailymotion](http://www.dailymotion.com/sugarlabs). - -Los visitantes a LinuxTag son bienvenidos a hablar con los contribuyentes de Sugar Labs en el mostrador 7.2a 110a. \ No newline at end of file diff --git "a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-gibt-die-Ver\303\266ffentlichung-von-Sugar-on-a-Stick-bekannt;-die-Lernplattform-l\303\244uft-auf-jedem-PC-oder-Netbook-im-Klassenzimmer..md" "b/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-gibt-die-Ver\303\266ffentlichung-von-Sugar-on-a-Stick-bekannt;-die-Lernplattform-l\303\244uft-auf-jedem-PC-oder-Netbook-im-Klassenzimmer..md" deleted file mode 100644 index f800116d..00000000 --- "a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-gibt-die-Ver\303\266ffentlichung-von-Sugar-on-a-Stick-bekannt;-die-Lernplattform-l\303\244uft-auf-jedem-PC-oder-Netbook-im-Klassenzimmer..md" +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: "Sugar Labs gibt die Veröffentlichung von Sugar on a Stick bekannt; die Lernplattform läuft auf jedem PC oder Netbook im Klassenzimmer." -category: "PRESS RELEASE" -date: "2009-06-24" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -LinuxTag, Berlin, 24. Juni 2009: Sugar Labs™, gemeinnütziger Anbieter der Sugar-Lernplattform, die weltweit von über einer Million Kindern benutzt wird, gibt die Veröffentlichung von Sugar on a Stick v1 Strawberry bekannt. Frei zum Download auf [www.sugarlabs.org](www.sugarlabs.org) verfügbar, lässt sich Sugar on a Stick auf einen gewöhnlichen 1GB-USB-Stick laden, von dem aus ein PC oder Netbook direkt in die preisgekrönte Sugar-Umgebung gebootet werden kann. Es läuft auf neuen Macs mit einer Hilfs-CD und unter Windows mittels Virtualisierung. Sugar on a Stick ist für den Betrieb mit einem Schulserver ausgelegt, der die Verteilung von Materialien, das Einsammeln von Hausaufgaben, Datensicherung, Moodle-Anbindung und gefilterten Zugriff auf das Internet bieten kann. Die gegenwärtige Strawberry-Version ist zum Testen im Klassenzimmer gedacht. [Rückmeldungen](mailto:feedback@sugarlabs.org) werden in die nächste Version einfließen, die ende 2009 verfügbar sein wird. - -"Ein Jahr nach seiner Gründung arbeitet Sugar Labs an der Auslieferung seiner Bildungszusage an die zweite Million Lernender", so Walter Bender, Gründer und Geschäftsführer. "Sugar wird bevorzugt, weil es kleinen Kindern eine überragende Lernerfahrung bietet: faszinierend und doch erschwinglich. Sugar on a Stick stellt eine wunderbare Möglichkeit dar, Sugar auszuprobieren, ohne die Festplatte des Rechners zu verändern. Es eignet sich auch gut für langsamere, ältere Rechner oder schwachbrüstige Netbooks. Es gibt eine Version für den OLPC XO-1 und es wird auf den neueren XO-1.5-Laptops diesen Herbst zu finden sein." - -Sugar on a Stick bietet eine schlüssige und einheitliche Computererfahrung. Es mindert die Kosten durch hohe Flexibilität bei der Hardware-Auswahl, was es Schulen ermöglicht, bereits vorhandene Hardware weiterhin zu nutzen. Die Lernenden können von der zunehmenden Verbreitung von Rechnern in den Haushalten profitieren: Dadurch, dass sich Sugar on a Stick mit nach Hause nehmen lässt, steht jedem Schüler eine einheitliche, vergleichbare Computerumgebung zur Verfügung, die seine Eltern ebenso nutzen können. Auch ermöglicht es Offline-Zugang zu Anwendungen und Materialien, nachdem nicht jeder Lernende zu Hause über einen Internet-Zugang verfügt. - -Als Teil der andauernden Bemühungen, Sugar on a Stick für den Einsatz im Klassenzimmer bereit zu machen, wurde Sugar Labs ein 20.000$-Zuschuss der Gould Charitable Foundation zuerkannt, um Sugar an der Gardner Pilot Academy zu implementieren, einer öffentlichen Grundschule in einem der kulturell und sprachlich vielfältigsten Viertel Bostons in Massachusetts, USA. - -Lernaktivitäten bilden das Herzstück von Sugar. Sugar on a Stick umfasst 40 Aktivitäten, um das Interesse junger Lernender zu wecken, beispielsweise Lesen, Schreiben, Malen oder Etoys. Hunderte weiterer Aktivitäten stehen in der [Sugar-Aktivitätenbibliothek](http://activities.sugarlabs.org) zum freien Download bereit. Die meisten "ver-Sugar-ten" Aktivitäten ermöglichen die Zusammenarbeit von Schülern: Schüler und Lehrer arbeiten, spielen und lernen gemeinsam in denselben Aktivitäten. Die Sugar-Lernplattform ist offen, sodass durch Einsatz anderer Open-Source-Produkte vorhandene Software für Kinder integriert werden kann. So wurde etwa die gefeierte GCompris-Suite aus 100 Aktivitäten, die die letzten fünf Jahre über von Bruno Coudoin entwickelt wurde, erst kürzlich zu Sugar hinzugefügt, darunter Aktivitäten wie Schach, Geographie oder Sudoku. Lehrer und Eltern, die sich für Sugars Aktivitäten und sein modernes Interface für Kinder interessieren, finden im unlängst eröffneten [Sugar Labs Dailymotion-Kanal](http://www.dailymotion.com/sugarlabs) kurze Videos. - -Besucher des LinuxTages sind herzlich eingeladen, mit Beitragenden zu Sugar Labs am Stand 7.2a 110a zu sprechen. diff --git a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-kondigt-aan-dat-Sugar-on-a-Stick-nu-beschikbaar-is;-dit-leerplatform-draait-op-elke-pc-of-netbook..md b/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-kondigt-aan-dat-Sugar-on-a-Stick-nu-beschikbaar-is;-dit-leerplatform-draait-op-elke-pc-of-netbook..md deleted file mode 100644 index 8bb6346e..00000000 --- a/src/constants/MarkdownFiles/posts/2009-06-24-Sugar-Labs-kondigt-aan-dat-Sugar-on-a-Stick-nu-beschikbaar-is;-dit-leerplatform-draait-op-elke-pc-of-netbook..md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: "Sugar Labs kondigt aan dat Sugar on a Stick nu beschikbaar is; dit leerplatform draait op elke pc of netbook." -category: "PRESS RELEASE" -date: "2009-06-24" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -LinuxTag, Berlijn, 24 juni 2009: Sugar Labs™ is de non-profit organisatie die het Sugar Leerplatform levert aan meer dan één miljoen kinderen over de hele wereld. Zij kondigt aan dat nu Sugar on a Stick versie 1 beschikbaar is onder de naam **"Strawberry"**. Het is gratis op te halen bij [www.sugarlabs.org](http://www.sugarlabs.org) en te installeren op een 1 GB flash drive. Daarna kan Sugar direct worden opgestart op een PC of netbook. Het draait ook op recente Macs met een hulp-CD en in Windows met gebruik van virtualisatie. - -Sugar on a Stick is ontworpen in combinatie met een School Server, waarmee het volgende kan worden verzorgd: distributie van informatie/leerstof, huiswerk verzamelen, backups maken, integratie met Moodle en gefilterde toegang tot het internet. Deze "Strawberry"-versie is bedoeld om in de klas te testen; feedback zal in de volgende versie worden opgenomen en komt tegen het einde van 2009 beschikbaar. - -> "Eén jaar na oprichting maakt Sugar Labs haar beloften waar voor haar tweede miljoen studenten," zegt Walter Bender, oprichter en directeur. -> "Sugar heeft de voorkeur, want het is een superieure leeromgeving voor jonge kinderen: motiverend en betaalbaar. Sugar on a Stick is een geweldige manier om het uit te proberen zonder de harde schijf te veranderen. Het is ook geschikt voor oudere pc’s en langzamere netbooks. Er is een versie voor de OLPC XO-1 en het zal geleverd worden met de nieuwere XO-1.5 laptops in de herfst." - -Sugar on a Stick geeft een samenhangend en consistente werkomgeving. Het vermindert kosten doordat het op veel hardware kan worden geïnstalleerd, zodat scholen hun bestaande apparatuur kunnen blijven gebruiken. Het komt de leerlingen ten goede dat zij hun vertrouwde Sugar on a Stick-omgeving mee naar huis kunnen nemen en het ook kunnen delen met hun ouders. Het geeft ook offline toegang tot hun activiteiten en leerstof, daar niet iedere leerling thuis internet heeft. - -Als onderdeel van een voortdurende inspanning om Sugar on a Stick klaar te maken voor de klas, heeft Sugar Labs een donatie van **$20.000** ontvangen van de Gould Charitable Foundation om Sugar te installeren op de Gardner Pilot Academy, een openbare basisschool in een wijk van Boston, Massachusetts met één van de grootste verscheidenheid aan achtergronden qua cultuur en taal. - -Leeractiviteiten zijn het hart van Sugar. Sugar on a Stick bevat **veertig activiteiten** voor jonge leerlingen zoals lezen, schrijven, tekenen en eToys. Er zijn nog honderden andere activiteiten gratis op te halen bij de [Sugar Activiteiten Bibliotheek](http://activities.sugarlabs.org). De meeste van deze activiteiten hebben samenwerking ingebouwd: leerlingen en onderwijskrachten werken, spelen en leren samen. - -Het Sugar Leerplatform is open, dus andere bestaande open-sourceprojecten voor kinderen kunnen erin geïntegreerd worden. Zo is de bekende **GCompris-suite** van honderd activiteiten onlangs toegevoegd aan Sugar, met activiteiten als schaken, aardrijkskunde en sudoku. Dit project werd de afgelopen vijf jaar door **Bruno Coudoin** ontwikkeld. - -Leerkrachten en ouders die geïnteresseerd zijn in Sugar-activiteiten en de moderne interface voor kinderen kunnen korte video’s bekijken op het onlangs geopende [Sugar Labs Dailymotion-kanaal](http://www.dailymotion.com/sugarlabs). - -Bezoekers aan LinuxTag zijn welkom bij stand **7.2a 110a** om te komen praten met Sugar Labs-medewerkers. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2009-11-18-Sugar-Labs-and-Free-Software-Foundation-Celebrate-Software-Freedom-Day,-Announce-Joint-Efforts-to-Promote-the-Sugar-Learning-Platform-for-Children-Worldwide.md b/src/constants/MarkdownFiles/posts/2009-11-18-Sugar-Labs-and-Free-Software-Foundation-Celebrate-Software-Freedom-Day,-Announce-Joint-Efforts-to-Promote-the-Sugar-Learning-Platform-for-Children-Worldwide.md deleted file mode 100644 index bc4aa140..00000000 --- a/src/constants/MarkdownFiles/posts/2009-11-18-Sugar-Labs-and-Free-Software-Foundation-Celebrate-Software-Freedom-Day,-Announce-Joint-Efforts-to-Promote-the-Sugar-Learning-Platform-for-Children-Worldwide.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "Sugar Labs and Free Software Foundation Celebrate Software Freedom Day, Announce Joint Efforts to Promote the Sugar Learning Platform for Children Worldwide" -category: "PRESS RELEASE" -date: "2009-11-18" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -CAMBRIDGE, MA, September 18, 2009 — Sugar Labs, nonprofit provider of the Sugar Learning Platform for children, and the Free Software Foundation (FSF), which promotes computer users’ right to use, study, copy, modify, and redistribute computer programs, have announced joint efforts to collaborate and promote Sugar on the occasion of **Software Freedom Day**, September 19th. - -The FSF will host an event in Boston featuring Sugar Labs Executive Director **Walter Bender**, FSF president **Richard Stallman**, and other speakers. **Peter Brown**, FSF’s executive director, said: - -> “The Sugar Learning Platform is fast becoming an essential route to computer user freedom for children around the world. The international free software movement is getting behind Sugar, and we want to use Software Freedom Day as an opportunity to help draw community attention, developer resources, and external funders to the important work going on at Sugar Labs.” - -The FSF has upgraded its hosting services support of Sugar Labs to keep pace with its growth. As part of the ongoing relationship, **Bernardo Innocenti**, a member of the Sugar Labs Oversight Board, is working at the FSF offices. Mr. Innocenti stated: - -> “The FSF and Sugar Labs are pursuing distinct, but interdependent goals; Free (as in Freedom) Software is a fundamental part of globally accessible education, and good education enables critical thought, a pre-requisite for appreciating the value of Freedom.” - -Sugar is a global project. Translated into **25 languages**, it is used in classrooms in **40 countries** by over **1 million children** as part of the **One Laptop per Child (OLPC)** nonprofit program. Sugar’s simple interface, built-in collaboration, and automatic backup through each student’s Journal have been designed to interest young learners. - -The recently released **Sugar on a Stick (SoaS)** project brings Sugar to even more children, allowing young learners to keep a working copy of Sugar on a simple USB stick, ready to start up any PC or netbook with the child’s environment and data. Pilot projects in schools with Sugar on a Stick are underway in **Boston**, **Berlin**, and elsewhere. - -SoaS is **free software** available under the **General Public License (GPL)** and is available for download without charge at [sugarlabs.org](http://www.sugarlabs.org). - -According to Walter Bender: - -> “Sugar is running on over 99% of all of the OLPC-XO laptops around the world because governments prefer its quality, openness, built-in collaboration, and easy localization to indigenous languages. Teachers and students are exercising their freedom by modifying and improving Sugar and its Activities. With Sugar on a Stick, access to Sugar is even more widespread.” - -For example, **Uruguay** has distributed a Sugar-equipped OLPC laptop to every student in the country. [Alexandre Oliva of FSF’s sister organization Free Software Foundation Latin America](http://www.fsfla.org) said: - -> “I was amazed when I first saw Sugar in action in Peru two years ago; shortly thereafter, my daughter tasted Sugar and loved it. She’s going to elementary school next year, and I’m very happy she can now easily carry Sugar with her, and share it with her friends. Myself, I’m going to spread its freedom into as many schools as I can.” - -**Karsten Gerloff**, President of [Free Software Foundation Europe](http://fsfe.org), added: - -> “Education and Free Software are both all about sharing knowledge. Through projects like Sugar, young people around the world can discover the creativity that freedom makes possible. Together with the political backing that FSFE’s Edu-Team and others are building, Sugar puts Free Software in its rightful place in education.” - -Sugar Labs relies on the efforts of **software developers** who donate their skills to the project. Mr. Bender continued: - -> “We are looking for developers with experience in GNU/Linux, Python and/or Gtk+ for contributing to the Sugar shell and educational Activities for children. We also need testers, experienced packagers, and educators willing to contribute their ideas for Sugar in the classroom.” \ No newline at end of file diff --git "a/src/constants/MarkdownFiles/posts/2009-12-08-L\342\200\231association-\303\240-but-non-lucratif-Sugar-Labs-annonce-la-version-2-de-\342\200\234Sugar-on-a-Stick\342\200\235.md" "b/src/constants/MarkdownFiles/posts/2009-12-08-L\342\200\231association-\303\240-but-non-lucratif-Sugar-Labs-annonce-la-version-2-de-\342\200\234Sugar-on-a-Stick\342\200\235.md" deleted file mode 100644 index 7d6f7600..00000000 --- "a/src/constants/MarkdownFiles/posts/2009-12-08-L\342\200\231association-\303\240-but-non-lucratif-Sugar-Labs-annonce-la-version-2-de-\342\200\234Sugar-on-a-Stick\342\200\235.md" +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: "L’association à but non lucratif Sugar Labs annonce la version 2 de “Sugar on a Stick” qui améliore la lecture de livres électroniques et transforme n’importe quelle clé USB en une plate-forme éducative pour les enfants ; partenariat avec Nexcopy, Inc." -category: "PRESS RELEASE" -date: "2009-12-08" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> -PARIS, le 8 décembre 2009 - **Netbook World Summit** - Sugar Labs® la communauté de volontaires développant la plate-forme éducative Sugar déjà diffusée à plus d’un million d’enfants dans le monde, annonce la sortie de **Sugar on a Stick v2 “Blueberry” (Myrtille)**. - -Disponible en téléchargement sur [http://www.sugarlabs.org][0], Sugar on a Stick peut s’installer sur toute clé USB de 1Go ou plus et permet, sans modifier l’installation, de faire fonctionner n’importe quel PC, netbook ou un Mac récent, dans l’environnement pour enfant Sugar. Sugar est également disponible pour la plupart des distributions GNU/Linux, peut fonctionner de manière virtualisée sur Windows et Apple OS X et intègre nativement des fonctionnalités de collaboration et de sauvegarde dans le Journal des activités. - -La dernière version de Sugar propose : -- une navigation web simplifiée, -- une meilleure gestion des réseaux sans fil, -- un portail d’installation de nouvelles Activités pour enfants, -- une configuration clavier facilitée, -- et l’intégration de **Gnash** pour le support des contenus Adobe Flash. - -De nouvelles Activités comme **Physiques** et **OOo4Kids** complètent les applications favorites telles que **Naviguer** et **Lire**, adaptées à la lecture de livres électroniques. - -> “Sugar on a Stick est une merveilleuse manière d’expérimenter Sugar,” commente Walter Bender, le président exécutif du Sugar Labs. “En cette période de fêtes de fin d’année, nous souhaitons rappeler aux parents et aux enseignants que les livres électroniques ne sont pas réservés à des coûteux lecteur dédiés, mais font partie du mouvement libre d’accès à la connaissance pour aider les enfants partout dans le monde à développer un accès critique à la connaissance et combler le fossé numérique partout où il existe.” - -Sugar on a Stick intègre plusieurs activités de lecture de livres électroniques pour télécharger et visualiser des livres aux formats PDF, EPUB et DejaVu. De plus, l’Activité **Read Etexts** peut lire des livres électroniques à haute voix, permettant de convertir n’importe quel vieux PC ou un netbook à bas coût en un outil de lecture audio pour les personnes à vision réduite. Avec Sugar, les enfants peuvent même construire leurs propres livres électroniques. - -Des centaines de livres électroniques pour enfants sont disponibles sur : -- [Projet Gutenberg](https://www.gutenberg.org), -- [Internet Archive Children’s Library](https://archive.org/details/iacl), -- [epubBooks.com](https://www.epubbooks.com), -- [Feedbooks.com](https://www.feedbooks.com), -- [ManyBooks.net](https://manybooks.net), -- et d’autres comme [International Children’s Digital Library](http://en.childrenslibrary.org). - -Des projets pilotes sont en cours dans des écoles aux États-Unis et en Europe. Les responsables d’écoles intéressés par Sugar seront ravis de découvrir la mise à jour du **Serveur d’école XS**, qui permet : -- un accès protégé à Internet, -- la distribution de contenu, -- une intégration Moodle, -- et des sauvegardes centralisées. - -Pour soutenir ce déploiement, Sugar Labs a établi un partenariat avec **Nexcopy, Inc.**, basée à Rancho Santa Margarita, Californie. Nexcopy, spécialiste des solutions de duplication USB, a lancé le site [http://recycleusb.com](http://recycleusb.com). Ils récupèrent des clés USB, les chargent avec Sugar on a Stick, puis les renvoient au Sugar Labs pour distribution dans les écoles. Nexcopy a également offert une unité de réplication de 20 clés au projet. - -> Greg Morris, Président de Nexcopy, commente : -> “Nexcopy est fier d’être partenaire avec une organisation à but non lucratif comme le Sugar Labs. Nous sommes convaincus que la plate-forme éducative Sugar est un pas dans la bonne direction pour permettre aux enfants d’être efficaces avec les ordinateurs. Notre objectif est de donner au Sugar Labs le support et l’équipement nécessaire pour permettre le succès de cette opération philanthropique et permettre la production de masse d’un grand nombre de clés Sugar pour un déploiement global. Je suis très honoré que Nexcopy fasse partie de ce processus.” - -### À propos du Sugar Labs -Sugar Labs est une organisation non lucrative de volontaires, membre du projet **Software Freedom Conservancy**. À l’origine intégré au projet One Laptop Per Child, Sugar Labs coordonne les efforts mondiaux pour fournir des opportunités éducatives à travers la plate-forme Sugar. Soutenu par des dons, Sugar Labs cherche activement des fonds pour accélérer son développement. -🔗 [http://www.sugarlabs.org](http://www.sugarlabs.org ) - -### À propos de Nexcopy Incorporated -Nexcopy Incorporated est spécialisée dans le développement d’outils de duplication de mémoire flash de haute performance. Présente sur les marchés d’Amérique Centrale et du Sud, d’Europe, d’Inde, d’Asie, ainsi que sur le marché américain, la société est basée en Californie. - ---- - -Sugar Labs est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leurs auteurs. diff --git a/src/constants/MarkdownFiles/posts/2009-12-08-Sugar-Labs-Nonprofit-Announces-v2-of-Sugar-on-a-Stick-with-Improved-E-Book-Readers,-Recycles-Any-USB-Stick-Into-Learning-Environment-for-Children;-Partners-with-Nexcopy,-Inc..md b/src/constants/MarkdownFiles/posts/2009-12-08-Sugar-Labs-Nonprofit-Announces-v2-of-Sugar-on-a-Stick-with-Improved-E-Book-Readers,-Recycles-Any-USB-Stick-Into-Learning-Environment-for-Children;-Partners-with-Nexcopy,-Inc..md deleted file mode 100644 index ed2f390a..00000000 --- a/src/constants/MarkdownFiles/posts/2009-12-08-Sugar-Labs-Nonprofit-Announces-v2-of-Sugar-on-a-Stick-with-Improved-E-Book-Readers,-Recycles-Any-USB-Stick-Into-Learning-Environment-for-Children;-Partners-with-Nexcopy,-Inc..md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "Sugar Labs Nonprofit Announces v2 of Sugar on a Stick with Improved E-Book Readers, Recycles Any USB Stick Into Learning Environment for Children; Partners with Nexcopy, Inc." -category: "PRESS RELEASE" -date: "2009-12-08" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -PARIS, December 8, 2009 — Netbook World Summit — Sugar Labs® (R), volunteer-driven nonprofit provider of the Sugar Learning Platform for over one million children around the world, announces the release of Sugar on a Stick v2 “Blueberry.” Available for download at [http://www.sugarlabs.org](http://www.sugarlabs.org), Sugar on a Stick can be loaded onto any ordinary 1GB or greater flash drive to reboot any PC, netbook or recent Mac directly into the child-friendly Sugar environment without touching the existing installation. - -Sugar is also available for GNU/Linux distributions, runs under virtualization on Windows and Apple OS X, and features built-in classroom collaboration and automatic backup to a Journal. The latest version of Sugar offers simpler navigation, improved wireless networking, streamlined updating of Activities for children, easier keyboard configuration, better Gnash support for Adobe Flash content, and more. New Activities such as Physics and OOo4Kids join updated favorites such as Browse and Read, suitable for reading e-books. - -“Sugar on a Stick is a great way to experience Sugar,” commented Walter Bender, Sugar Labs executive director. “In this holiday season, we wish to remind parents and teachers that e-books are not only for costly reader units for the well-to-do, but freely available as part of the open-access to knowledge movement to help children everywhere develop critical learning skills and to bridge the digital divide wherever it exists.” - -Sugar on a Stick includes several e-book reader Activities to find and display e-books in PDF, EPUB, and DejaVu formats. The Read Etexts Activity can read e-books out loud, converting any old PC or inexpensive netbook into a text-to-speech aid for disabled readers. With Sugar, children can even make their own e-books. Thousands of e-books for children are available on websites such as Project Gutenberg, the Internet Archive Children’s Library, epubBooks.com, Feedbooks.com, and ManyBooks.net. Other sites offer online reading, such as the International Children’s Digital Library. - -Pilot Sugar projects are underway in American and European schools. School administrators wishing to deploy Sugar will be interested in OLPC’s recently updated XS school server software, which provides “safety net” and connectivity services at the school level: backup, content distribution, filtered access to the Internet, and Moodle integration. - -To assist schools interested in testing this technology, Sugar Labs has partnered with Nexcopy, Inc. of Rancho Santa Margarita, California, an industry leader in USB duplicator solutions, to open [http://recycleusb.com](http://recycleusb.com). Nexcopy will collect used USB sticks, reload them with Sugar on a Stick, and forward them to Sugar Labs for distribution to schools. Nexcopy has also donated a 20-stick USB duplication unit to Sugar Labs. - -Greg Morris, President of Nexcopy, commented, “Nexcopy is proud to partner with a nonprofit organization such as Sugar Labs. We believe the Sugar Learning Platform is clearly a step in the right direction for getting children involved with personal computers. Our objective is to give Sugar Labs the back-end equipment support needed to make this philanthropy successful and help with producing the large number of Sugar Sticks needed for global deployment. I am very honored Nexcopy is a part of this process.” - -**About Sugar Labs**: Sugar Labs, a volunteer-driven, nonprofit organization, is a member project of the Software Freedom Conservancy. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. Sugar Labs is supported by donations and is seeking funding to accelerate development. For more information, please visit [http://www.sugarlabs.org](http://www.sugarlabs.org). - -**About Nexcopy Incorporated**: Nexcopy Incorporated specializes in developing and manufacturing the finest and most feature-rich flash memory duplicators in the market. Pioneering the solid-state memory duplication market, Nexcopy supplies Central and South America, Europe, India, Asia, Pacific Rim and serves the U.S. market through its headquarters in California. - -Sugar Labs is a registered trademark of the Software Freedom Conservancy. Other names are trademarks of their respective owners. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2010-04-29-L'Office-de-secours-et-de-travaux-des-Nations-unies-choisi-les-ordinateurs-du-projet-One-Laptop-per-Child-et-la-plate-forme-Sugar-pour.md b/src/constants/MarkdownFiles/posts/2010-04-29-L'Office-de-secours-et-de-travaux-des-Nations-unies-choisi-les-ordinateurs-du-projet-One-Laptop-per-Child-et-la-plate-forme-Sugar-pour.md deleted file mode 100644 index bfffa955..00000000 --- a/src/constants/MarkdownFiles/posts/2010-04-29-L'Office-de-secours-et-de-travaux-des-Nations-unies-choisi-les-ordinateurs-du-projet-One-Laptop-per-Child-et-la-plate-forme-Sugar-pour.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: "L'Office de secours et de travaux des Nations unies choisi les ordinateurs du projet One Laptop per Child et la plate-forme Sugar pour un projet majeur d'éducation au proche orient" -category: "PRESS RELEASE" -date: "2010-04-29" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -CAMBRIDGE, Mass, 29 avril 2010 - L'Office de secours et travaux des Nations unies pour les réfugiés de Palestine au proche orient ([UNRWA](http://www.unrwa.org)) a annoncé un programme ambitieux de 3 ans pour fournir à un demi-million d'enfants réfugiés Palestinien, dans la bande de Gaza, au Liban, en Syrie et en Jordanie, un ordinateur équipé de la plateforme éducative Sugar, plusieurs fois primée. - -"Motiver la prochaine génération en lui donnant l'accès à la connaissance et à l'apprentissage est capital pour les projets éducatifs de l'UNRWA. Nous enseignons à 500 000 enfants au Proche Orient chaque jour et donner à chacun d'entre eux un ordinateur sera une énorme contribution pour combler le fossé technologique et d'accès au savoir dans l'une des régions les plus troublée du monde", a indiqué Chris Gunness, le porte-parole de l'UNWRA. - -Selon Walter Bender, fondateur et directeur exécutif du Sugar Labs: "Aujourd'hui, de la forêt vierge du Pérou aux steppes de Mongolie, des collines du Rwanda aux montages d'Afghanistan, un million et demi d'enfants apprennent chacun dans leur langue maternelle, sur les ordinateurs XO du projet OLPC grâce à Sugar et sa suite d'Activités d'apprentissage. Le projet de l'UNRWA ajoutera un demi-million d'apprenants supplémentaires en provenance de la vallée de Jordanie et du Moyen Orient, et d'autres projets vont voir le jour prochainement. C'est une génération entière qui apprend avec Sugar." - -Le cœur de Sugar, ce sont ses Activités pour les enfants ([http://activities.sugarlabs.org](http://activities.sugarlabs.org)). Amusant et motivant, ce sont des programmes qui permettent de lire des livres électroniques, d'écrire, de dessiner, de naviguer sur Internet, de programmer et plein d'autres choses. Sugar intègre de plus le travail collaboratif et l'enregistrement des activités réalisées dans le journal ce qui le rend particulièrement adapté à l'utilisation en classe mais aussi en dehors de l'école pour continuer les apprentissages. Complété par un serveur d'école XS, un logiciel libre et ouvert proposé par le projet One Laptop Per Child, il permet de fournir aux jeunes apprenants un environnement connecté sûr et sécurisé. - -Les contenus existant de l'UNRWA seront adaptés à Sugar et la formation des enseignants va démarrer prochainement. Le projet de l'UNRWA fait suite au déploiement l'année dernière de 1000 ordinateurs XO dans les écoles Palestinienne par le PEI (Palestine Education Initiative [http://www.pei.gov.ps](http://www.pei.gov.ps), [http://en.palexo.com](http://en.palexo.com)). Sugar Labs est à la recherche de développeurs et de volontaires pour faire de ce projet un vrai succès. - -A propos du Sugar Labs: Sugar Labs est un organisation non lucrative de volontaires, membre du projet Software Freedom Conservancy. A l’origine intégré au projet One Laptop Per Child, Sugar Labs coordonne les volontaires dans le monde qui sont passionés par l’idée de fournir des opportunités d’éducation à travers la plate-forme éducative Sugar. Sugar Labs est soutenu par des donations et cherche des fonds pour accélérer son développement. Pour plus d’information, voir [http://www.sugarlabs.org](http://www.sugarlabs.org) - -Sugar Labs est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leur auteurs. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2010-04-29-United-Nations-Relief-and-Works-Agency-Sceglie-i-Laptop-di-One-Laptop-per-Child-con--Sugar-per-un-Importante-Progetto-Educativo-in-Medio-Oriente.md b/src/constants/MarkdownFiles/posts/2010-04-29-United-Nations-Relief-and-Works-Agency-Sceglie-i-Laptop-di-One-Laptop-per-Child-con--Sugar-per-un-Importante-Progetto-Educativo-in-Medio-Oriente.md deleted file mode 100644 index fb43409a..00000000 --- a/src/constants/MarkdownFiles/posts/2010-04-29-United-Nations-Relief-and-Works-Agency-Sceglie-i-Laptop-di-One-Laptop-per-Child-con--Sugar-per-un-Importante-Progetto-Educativo-in-Medio-Oriente.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: "United Nations Relief and Works Agency Sceglie i Laptop di One Laptop per Child con Sugar per un Importante Progetto Educativo in Medio Oriente" -category: "PRESS RELEASE" -date: "2010-04-29" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -CAMBRIDGE, Mass., 29 Aprile, 2010 — L'Agenzia delle Nazioni Unite per i rifugiati della Palestina nel Medio Oriente ([UNRWA](http://www.unrwa.org)) ha annunciato un ambizioso programma triennale per fornire un computer portatile dotato del premiato ambiente software Sugar Learning Platform a mezzo milione di bambini palestinesi rifugiati nella Striscia di Gaza, Libano, Siria, e Giordania. - -“Rafforzare la prossima generazione grazie a conoscenza e capacità di apprendimento è l'aspetto centrale per progetti educativi dell'UNRWA. Ogni giorno forniamo istruzione a 500.000 bambini nel Medio Oriente e fornire ad ognuno di loro un laptop sarà un grande aiuto a chiudere il gap di conoscenza e tecnologie in una delle regioni del mondo con maggiori problemi,” dice Chris Gunness, portavoce dell'UNRWA. - -Walter Bender, fondatore e Direttore Esecutivo di Sugar Labs, dichiara: “Ad oggi, un milione e mezzo di bambini, dalle foreste equatoriali del Perù alle steppe della Mongolia, dalle colline del Rwanda alle montagne dell'Afganistan, stanno imparando, utilizzando la loro lingua madre grazie a Sugar e alla collezione di Attività didattiche con i laptop XO di OLPC. Il progetto di UNRWA accrescerà di un altro mezzo milione di studenti nella valle del Giordano e nel Medio Oriente, altri progetti sono in sviluppo. Una intera nuova generazione sta apprendendo con Sugar.” - -Al cuore di Sugar sono le Attività: [http://activities.sugarlabs.org](http://activities.sugarlabs.org) – programmi divertenti e appassionanti, nati per leggere libri elettronici, scrivere, disegnare, navigare la rete Internet, programmare, e molto altro ancora. Sugar integra capacità di collaborazione fra utenti e di memorizzazione dei dati in una struttura organizzata in base temporale (Diario), funzionalità estremamente adatte sia ad un utilizzo in classe che per continuare ad apprendere e studiare anche al di fuori della scuola. Il sistema XS School Server, basato su software libero, reso disponibile da One Laptop per Child, permette un accesso sicuro e filtrato alla rete Internet per i giovani studenti. - -I materiali didattici di UNRWA esistenti saranno adattati a Sugar e si sta già provvedendo anche alla formazione dei docenti. Il progetto di UNRWA segue le orme della distribuzione avvenuta lo scorso anno di 1000 laptops XO nelle scuole della Palestina a cura della Palestine Education Initiative ([http://www.pei.gov.ps](http://www.pei.gov.ps), [http://en.palexo.com](http://en.palexo.com)). Sugar Labs è lieta di accogliere sviluppatori e volontari che vogliano collaborare alla riuscita di questa iniziativa. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2010-04-29-United-Nations-Relief-and-Works-Agency-chooses-One-Laptop-per-Child-Laptops-with-Sugar-for-Major-Education-Project-in-Mideast.md b/src/constants/MarkdownFiles/posts/2010-04-29-United-Nations-Relief-and-Works-Agency-chooses-One-Laptop-per-Child-Laptops-with-Sugar-for-Major-Education-Project-in-Mideast.md deleted file mode 100644 index ef93f04b..00000000 --- a/src/constants/MarkdownFiles/posts/2010-04-29-United-Nations-Relief-and-Works-Agency-chooses-One-Laptop-per-Child-Laptops-with-Sugar-for-Major-Education-Project-in-Mideast.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: "United Nations Relief and Works Agency chooses One Laptop per Child Laptops with Sugar for Major Education Project in Mideast" -category: "PRESS RELEASE" -date: "2010-04-29" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -CAMBRIDGE, Mass, April 29, 2010 - The United Nations Relief and Works Agency for Palestine Refugees in the Near East (UNRWA, [http://www.unrwa.org](http://www.unrwa.org)) has announced an ambitious three-year program to provide a laptop loaded with the award-winning Sugar Learning Platform to one-half million Palestine refugee children in the West Bank and Gaza, Lebanon, Syria, and Jordan. - -“Empowering the next generation through knowledge and learning is central to UNRWA’s education projects. We are teaching 500,000 children in the Middle East every day and having all of them with a laptop will be a huge contribution to bridging the technology and knowledge gap in one of the most troubled regions of the world,” said Chris Gunness, UNWRA Spokesman. - -Walter Bender, founder and Executive Director of Sugar Labs, said: “Today, one-and-one-half-million children, from the rain forests of Peru to the steppes of Mongolia, from the hills of Rwanda to the mountains of Afghanistan, are learning in their native tongues with Sugar and its suite of learning Activities on OLPC’s XO laptops. The UNRWA project will add one-half million more learners in the Jordan valley and throughout the Middle East, and more projects are on the way. An entire generation is learning with Sugar.” - -The heart of Sugar is its Activities for children ([http://activities.sugarlabs.org](http://activities.sugarlabs.org)), fun and engaging programs for reading e-books, writing, drawing, browsing the Internet, programming, and so on. Sugar has collaboration and backup to a Journal built-in, making it particularly well-suited both for the classroom and outside school where learning continues. The free open source XS School Server, available from One Laptop per Child, provides a safely filtered online environment for young learners. - -Existing UNRWA learning content will be adapted to Sugar and teacher training is underway. The UNRWA project follows last year’s deployment of 1000 XO laptops in Palestinian schools by the Palestine Education Initiative ([http://www.pei.gov.ps](http://www.pei.gov.ps), [http://en.palexo.com](http://en.palexo.com)). Sugar Labs welcomes developers and volunteers to make this important endeavor successful. - -About Sugar Labs: Sugar Labs, a volunteer-driven, nonprofit organization, is a member project of the Software Freedom Conservancy. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. Sugar Labs is supported by donations and is seeking funding to accelerate development. For more information, please visit [http://www.sugarlabs.org](http://www.sugarlabs.org). \ No newline at end of file diff --git "a/src/constants/MarkdownFiles/posts/2010-06-04-La-Plataforma-de-Aprendizaje-Sugar-y-el-Escritorio-GNOME-se-distribuir\303\241n-hoy-en-la-One-Laptop-per-Child-modelo-XO-1.5;-tambi\303\251n-se-ejecutar\303\241-en-el-nuevo-XO-HS-High-School-Edition.md" "b/src/constants/MarkdownFiles/posts/2010-06-04-La-Plataforma-de-Aprendizaje-Sugar-y-el-Escritorio-GNOME-se-distribuir\303\241n-hoy-en-la-One-Laptop-per-Child-modelo-XO-1.5;-tambi\303\251n-se-ejecutar\303\241-en-el-nuevo-XO-HS-High-School-Edition.md" deleted file mode 100644 index a083476f..00000000 --- "a/src/constants/MarkdownFiles/posts/2010-06-04-La-Plataforma-de-Aprendizaje-Sugar-y-el-Escritorio-GNOME-se-distribuir\303\241n-hoy-en-la-One-Laptop-per-Child-modelo-XO-1.5;-tambi\303\251n-se-ejecutar\303\241-en-el-nuevo-XO-HS-High-School-Edition.md" +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "La Plataforma de Aprendizaje Sugar y el Escritorio GNOME se distribuirán hoy en la One Laptop per Child modelo XO-1.5; también se ejecutará en el nuevo XO-HS High School Edition" -category: "PRESS RELEASE" -date: "2010-06-04" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -ASUNCIÓN, 14 de junio de 2010 — Sugar Labs, el Proyecto de Escritorio Libre GNOME, y One Laptop per Child (OLPC) han anunciado una actualización del software que se ofrece en el OLPC XO-1.5. Los 1,5 millones de niños que ya usan Sugar en el XO-1 original también podrán beneficiarse de la actualización ya que Paraguay Educa ha portado el software. - -La plataforma de aprendizaje Sugar promueve el aprendizaje colaborativo a través de Actividades amigables para los niños que fomentan el pensamiento crítico. El escritorio libre GNOME es un componente distinguido de todas las principales distribuciones de GNU/Linux, adecuado para niños mayores y adultos. El cambio entre los dos entornos se realiza con un único click. Con GNOME en el portátil XO, se abre la puerta a miles de aplicaciones de formación y de productividad adicionales. - -El XO-1.5 tiene el mismo diseño industrial que el XO-1 original. Está basado en un procesador VIA, que proporciona el doble de velocidad que el XO-1, y tiene 4 veces más de memoria DRAM y memoria FLASH. OLPC ha anunciado la disponibilidad de una edición para secundaria del XO-1.5, el XO-HS High School Edition, con un diseño de teclado nuevo, más cómodo para los estudiantes mayores. El primer despliegue del XO-HS está programado para empezar en Uruguay en el marco del exitoso Plan Ceibal a partir de septiembre. - -Los niños familiarizados con el XO-1 evolucionarán naturalmente a las funcionalidades ampliadas del XO-1.5. "One Laptop per Child promueve software libre y de código abierto para que pueda evolucionar y adaptarse a las necesidades de los niños. La plataforma Sugar en el XO es clave para nuestra misión educativa porque proporciona a los estudiantes un entorno de software de aprendizaje único e intuitivo", dijo el director ejecutivo de la asociación OLPC Rodrigo Arboleda. - -Stormy Peters, Directora Ejecutiva de la GNOME Foundation, dice: “Estamos muy entusiasmados de estar trabajando con Sugar y OLPC para proveer software de escritorio para niños de todas las edades. La misión de GNOME es proporcionar un escritorio libre y accesible para todos. Los niños, desde Uruguay hasta Ghana, serán capaces de utilizar sus XO para aprender y mostrar a sus amigos y familias cómo usar Sugar y GNOME." - -Walter Bender, director ejecutivo de Sugar Labs, dijo que "la fluidez de cambio entre los dos escritorios ofrece al alumno la capacidad de transición de un entorno de aprendizaje —Sugar— a un entorno de producción —GNOME—. Así disponen de los medios para perfeccionar las habilidades creativas adquiridas en educación primaria, con las capacidades emprendedoras de la educación secundaria". - -“Sugar on a Stick” permite a los niños que no tienen un ordenador portátil XO beneficiarse de este nuevo software. Disponible para descarga desde Sugar Labs, en la nueva distribución v3 Mirabelle, puede ser cargada en un pendrive USB común y usarse para iniciar Sugar en una PC sin tocar el disco duro. Las laptops XO y Sugar on a Stick ejecutan Fedora GNU/Linux. - -**Acerca de Sugar Labs®:** Sugar Labs es una organización dirigida por voluntarios, sin ánimo de lucro y es un proyecto miembro de Software Freedom Conservancy. Originalmente parte del proyecto One Laptop Per Child, Sugar Labs coordina voluntarios en todo el mundo apasionados por la posibilidad de proveer oportunidades educacionales a niños a través de la Sugar Learning Platform. Sugar Labs es soportada por donaciones y está en busca de apoyo económico y voluntarios para acelerar el desarrollo. Para más información, por favor visita: [http://www.sugarlabs.org](http://www.sugarlabs.org). - -**Acerca de GNOME:** GNOME es un proyecto de software libre que desarrolla un estándar de escritorio completo, accesible y fácil de utilizar en todas las distribuciones principales de GNU/Linux y Unix. Popular en instalaciones corporativas grandes y entre millones de pequeñas y medianas empresas y usuarios domésticos a lo largo del mundo, incluye un entorno de desarrollo para crear nuevas aplicaciones. La Fundación GNOME se compone de cientos de desarrolladores voluntarios y compañías líderes de la industria. Se puede obtener mayor información en [http://www.gnome.org](http://www.gnome.org) y [http://foundation.gnome.org](http://foundation.gnome.org). - -**Acerca de One Laptop per Child:** ([http://www.laptop.org](http://www.laptop.org)) OLPC es una organización sin ánimo de lucro creada por Nicholas Negroponte y otros del Media Lab del MIT para diseñar, fabricar y distribuir portátiles lo suficientemente baratos como para proporcionar a cada niño en el mundo acceso al conocimiento y a las formas modernas de educación. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-Announces-New-Version-of-Sugar-on-a-Stick,-Educational-Software-for-Children.md b/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-Announces-New-Version-of-Sugar-on-a-Stick,-Educational-Software-for-Children.md deleted file mode 100644 index ecd0b142..00000000 --- a/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-Announces-New-Version-of-Sugar-on-a-Stick,-Educational-Software-for-Children.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: "Sugar Labs Announces New Version of Sugar on a Stick, Educational Software for Children" -category: "PRESS RELEASE" -date: "2010-06-10" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -BERLIN, June 10, 2010 — LinuxTag — Sugar Labs®, nonprofit provider of the Sugar Learning Platform to over one and a half million children worldwide, has released Mirabelle, the third version of Sugar on a Stick, a collaborative learning environment that can be loaded onto any ordinary USB thumbdrive and used with a PC, netbook or Mac without touching the hard disk. It is available free for download at [https://wiki.sugarlabs.org/go/Sugar_on_a_Stick](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick). Sugar runs natively on major GNU/Linux distributions and can also run in virtualization under Microsoft Windows and Apple OS X. - -One year after the premiere of v1 Strawberry at LinuxTag 2009 and following v2 Blueberry last December, v3 Mirabelle brings improved stability and simplified customization to curious teachers interested in testing Sugar on new netbooks or PCs already in the classroom. We suggest teachers reach out to university-level computer science and education schools to build local support structures, important with an ICT project. - -Sebastian Dziallas, Project Lead for Sugar on a Stick and a recent high school graduate based in Germany, said, "Teachers have told us how important reliability is in the classroom while engaging students, so we decided to create a release that has a stable core and can be customized to fit every deployment's needs. Mirabelle is a solid baseline which teachers can customize with Activities interesting to young learners. Part of our strategy is to achieve sustainable development while inviting new contributors. We achieved this by integrating Sugar on a Stick more closely with Fedora, the underlying GNU/Linux distribution; Mirabelle is now an official Fedora Spin." - -Sugar Labs is also making available a Sugar Creation Kit, a downloadable DVD which includes Mirabelle, documentation, and a library of Sugar Activities, fun and engaging programs for children taken from the [Sugar Activity Library](http://activities.sugarlabs.org). - -Thomas Gilliard, a Sugar Labs contributor, said, "The Sugar Creation Kit turns any PC into a Sugar on a Stick generating station. Tools and documentation are gathered on one disk; busy teachers don't have to hunt down anything. This makes it possible to work via 'sneaker net' and in a classroom behind a firewall." - -Visitors to LinuxTag are invited to meet Sugar Labs contributors at Hall 7.2a, Booth 115. - -**About Sugar Labs**: Sugar Labs, a volunteer-driven, nonprofit organization, is a member project of the Software Freedom Conservancy. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. Sugar Labs is supported by donations and is seeking funding to accelerate development. For more information, please visit [http://www.sugarlabs.org](http://www.sugarlabs.org). \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-Annuncia-una-Nuova-Versione-di-Sugar-on-a-Stick,-piattaforma-software-educativa-per-bambini.md b/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-Annuncia-una-Nuova-Versione-di-Sugar-on-a-Stick,-piattaforma-software-educativa-per-bambini.md deleted file mode 100644 index 9f55d8de..00000000 --- a/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-Annuncia-una-Nuova-Versione-di-Sugar-on-a-Stick,-piattaforma-software-educativa-per-bambini.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: "Sugar Labs Annuncia una Nuova Versione di Sugar on a Stick, piattaforma software educativa per bambini" -category: "PRESS RELEASE" -date: "2010-06-10" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -**BERLINO, 10 Giugno, 2010 — LinuxTag** — Sugar Labs®, il produttore nonprofit della Sugar Learning Platform utilizzata da più di un milione e mezzo di bambini nel mondo, ha rilasciato *Mirabelle*, la terza versione di Sugar on a Stick, una piattaforma collaborativa di apprendimento che può essere caricata su un normale disco rimovibile USB e utilizzata su un PC, netbook o Mac senza alcuna modifica al disco rigido del sistema ospite. È liberamente disponibile per il download all'indirizzo [https://wiki.sugarlabs.org/go/Sugar_on_a_Stick](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick). -Sugar funziona in modo nativo sulle principali distribuzioni GNU/Linux e attraverso la virtualizzazione su Microsoft Windows e Apple OS X. - -Esattamente un anno dopo la premiere della v1 Strawberry al LinuxTag 2009 e dopo la v2 Blueberry resa disponibile lo scorso dicembre, la v3 Mirabelle presenta maggior stabilità e una più facile personalizzazione per gli insegnanti interessati a sperimentare Sugar sui nuovi netbook o PC eventualmente già presenti in classe. Suggeriamo agli insegnanti di contattare facoltà universitarie di informatica ed educazione per costruire strutture di supporto locali, fondamentali per un progetto ICT. - -Sebastian Dziallas, Project Leader di Sugar on a Stick e neodiplomato residente in Germania, dichiara: -> “Gli insegnanti ci hanno detto quanto l'affidabilità sia fondamentale lavorando in classe con gli studenti, quindi abbiamo deciso di creare una versione caratterizzata da un core affidabile e che potesse poi essere personalizzata per soddisfare qualsiasi esigenza di rilascio. -> Mirabelle è una base solida che gli insegnanti possono personalizzare con le Attività maggiormente interessanti per i loro giovani studenti. -> La nostra strategia è mirata anche a sviluppare la piattaforma grazie alla collaborazione di nuovi contributori. Abbiamo ottenuto questo grazie anche alla integrazione più stretta di Sugar on a Stick con Fedora, la distribuzione GNU/Linux su cui è basato; Mirabelle ora è un Fedora Spin ufficiale.” - -Sugar Labs rende inoltre disponibile un **Sugar Creation Kit**, un DVD scaricabile che include Mirabelle, documentazione e una completa libreria di Attività Sugar, programmi divertenti ed interessanti estratti dalla Sugar Activity Library disponibile online ([http://activities.sugarlabs.org](http://activities.sugarlabs.org)). - -Thomas Gilliard, un contributore di Sugar Labs, commenta: -> “Il *Sugar Creation Kit* trasforma ogni PC in una stazione in grado di produrre istanze di Sugar on a Stick. Strumenti e documentazione sono tutti raccolti in un unico disco; gli insegnanti non perderanno tempo nella ricerca di quanto possa essere utile alla loro attività didattica. -> Questo strumento permette inoltre di lavorare via 'sneaker net' (non connessi a Internet) e in aule protette da firewall.” - -I visitatori del LinuxTag sono invitati ad incontrare gli sviluppatori di Sugar Labs presso il **Booth 115, Hall 7.2a**. \ No newline at end of file diff --git "a/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-annonce-la-nouvelle-version-de-\302\253Sugar-On-A-Stick\302\273,-son-syst\303\250me-\303\251ducatif-\303\240-destination-des-enfants.md" "b/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-annonce-la-nouvelle-version-de-\302\253Sugar-On-A-Stick\302\273,-son-syst\303\250me-\303\251ducatif-\303\240-destination-des-enfants.md" deleted file mode 100644 index d4230d03..00000000 --- "a/src/constants/MarkdownFiles/posts/2010-06-10-Sugar-Labs-annonce-la-nouvelle-version-de-\302\253Sugar-On-A-Stick\302\273,-son-syst\303\250me-\303\251ducatif-\303\240-destination-des-enfants.md" +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "Sugar Labs annonce la nouvelle version de «Sugar-On-A-Stick», son système éducatif à destination des enfants" -category: "PRESS RELEASE" -date: "2010-06-10" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - - -Berlin, le 10 juin 2010 - LinuxTag - Sugar Labs, organisation à but non lucratif à l’origine du développement de la plateforme éducative Sugar (déjà utilisée par plus de 1,5 millions d’enfants dans le monde), a dévoilé la troisième version de Sugar on a Stick, «Mirabelle», qui offre un environnement d’apprentissage collaboratif, utilisable depuis un PC, un netbook ou un Mac, sans aucune manipulation sur le système d’exploitation d’origine installé sur son disque, en utilisant une simple clé USB préchargée. Sugar on a Stick est téléchargeable à l’adresse suivante : [https://wiki.sugarlabs.org/go/Sugar_on_a_Stick](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick). Le programme Sugar fonctionne nativement avec la majorité des distributions GNU/Linux et peut être également utilisé depuis une machine virtuelle sur environnement Microsoft Windows ou Apple OS X. - -Un an après la première version de Sugar on a Stick («Strawberry») présentée lors de la conférence LinuxTag 2009 et suivi par «Blueberry» en décembre dernier, la nouvelle version «Mirabelle» apporte une meilleure stabilité et améliore les possibilités de personnalisation du système qui est offerte aux enseignants curieux et désireux d’utiliser Sugar sur les ordinateurs déjà présents en classe. D’ailleurs, nous recommandons vivement aux enseignants de développer autour de leur projet les différentes interactions et les échanges, en particulier avec le milieu universitaire autour de l’information ou des sciences de l’éducation. C’est un élément essentiel pour mener à bien un projet TICE. - -Sebastian Dziallas, chef de projet Sugar on a Stick, et étudiant allemand récemment diplômé rapporte que «les enseignants nous ont dit à quel point la fiabilité du programme est importante lorsqu’il est utilisé par les élèves en classe. C’est pour cela que nous avons décidé de rendre disponible une version avec un noyau stable et qui soit adaptable facilement à son environnement. Mirabelle est une version avec laquelle les enseignants pourront adapter les Activités en fonction des intérêts des enfants. De plus, une partie de notre stratégie consiste à faire naître un schéma de développement durable en invitant de nouvelles personnes à contribuer au projet. Nous avons aussi pu proposer les nouveautés de Mirabelle en optimisant la base de Sugar, la distribution GNU/Linux Fedora. Mirabelle est donc officiellement dérivée de Fedora, un Fedora Spin.» - -Sugar Labs a également rendu disponible le «Sugar Creation Kit», un DVD qui comprend Mirabelle, la documentation associée ainsi qu’un ensemble d’Activités pour Sugar, parmi les plus amusantes et attrayantes, aussi disponibles également en téléchargement sur le Sugar Activity Library ([http://activities.sugarlabs.org](http://activities.sugarlabs.org)). - -Thomas Gilliard, un des contributeurs à Sugar Labs explique que «Le Sugar Creation Kit permet de transformer n’importe quel PC en un poste capable de configurer des clés Sugar On A Stick. Les outils et la documentation nécessaire sont déjà présents sur le DVD si bien que les enseignants ne perdront pas de temps à rechercher une information, même derrière un pare-feu, sans avoir à se connecter au réseau». - -Sugar Labs sera présent pour toute la durée du salon LinuxTag 2010 au stand 115, Hall 7.2a. - -**À propos du Sugar Labs** : Sugar Labs est une organisation non lucrative de volontaires, membre du projet Software Freedom Conservancy. À l’origine intégré au projet One Laptop Per Child, Sugar Labs coordonne les volontaires dans le monde qui sont passionnés par l’idée de fournir des opportunités d’éducation à travers la plate-forme éducative Sugar. Sugar Labs est soutenu par des donations et cherche des fonds pour accélérer son développement. Pour plus d’informations, voir [http://www.sugarlabs.org](http://www.sugarlabs.org) - -Sugar Labs est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leurs auteurs. \ No newline at end of file diff --git "a/src/constants/MarkdownFiles/posts/2010-06-14-La-plateforme-\303\251ducative-Sugar-et-l'interface-bureautique-GNOME-d\303\251sormais-pr\303\251sents-sur-le-nouvel-XO-1.5-de-la-fondation-OLPC,-ainsi-que-le-nouveau-mod\303\250le-XO-HS-High-School-Edition.md" "b/src/constants/MarkdownFiles/posts/2010-06-14-La-plateforme-\303\251ducative-Sugar-et-l'interface-bureautique-GNOME-d\303\251sormais-pr\303\251sents-sur-le-nouvel-XO-1.5-de-la-fondation-OLPC,-ainsi-que-le-nouveau-mod\303\250le-XO-HS-High-School-Edition.md" deleted file mode 100644 index fef4b9f5..00000000 --- "a/src/constants/MarkdownFiles/posts/2010-06-14-La-plateforme-\303\251ducative-Sugar-et-l'interface-bureautique-GNOME-d\303\251sormais-pr\303\251sents-sur-le-nouvel-XO-1.5-de-la-fondation-OLPC,-ainsi-que-le-nouveau-mod\303\250le-XO-HS-High-School-Edition.md" +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "La plateforme éducative Sugar et l'interface bureautique GNOME désormais présents sur le nouvel XO 1.5 de la fondation OLPC, ainsi que le nouveau modèle XO-HS High School Edition" -category: "PRESS RELEASE" -date: "2010-01-14" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -ASUNCIÓN, le 14 juin 2010 – Sugar Labs, le projet d'interface bureautique libre GNOME, et la fondation One Laptop per Child (OLPC) ont annoncé conjointement une mise à jour du logiciel de l'ordinateur XO-1.5. Les 1,5 millions d'enfants qui utilisent déjà Sugar sur le XO-1 d'origine pourront également bénéficier de cette mise à jour, grâce au concours du Paraguay Educa qui a adapté cette mise à jour pour le XO-1. - -La plateforme éducative Sugar fait la promotion de l'apprentissage collaboratif à travers des Activités adaptées aux enfants, qui encouragent une pensée critique. L'interface bureautique GNOME, installé sur toutes les distributions majeures GNU/Linux, est destinée aux enfants plus âgés et aux adultes. Changer d'environnement se fait en un clic. Avec l'environnement GNOME présent sur l'ordinateur XO, la porte est ouverte à des millers d'applications éducatives et créatives supplémentaires. - -Le XO-1.5 est basé sur le même design que le premier XO. Equipé d'un processeur VIA, il est deux fois plus rapide que la première génération et dispose de quatre fois plus de mémoire RAM et d'espace de stockage. La fondation OLPC a annoncé la disponibilité d'une version destinée aux collégiens du dernier XO-1.5, nommé XO-HS (High School Edition), avec un clavier entièrement revu, plus confortable pour les élèves plus âgés. Le premier déploiement du XO-HS se déroulera en septembre en Uruguay dans le cadre du très réussi Plan Ceibal. - -Les enfants habitués au XO-1 pourront évoluer vers un XO-1.5 avec ses fonctionnalités supérieures. "Le projet One Laptop per Child promeut le logiciel libre si bien que l'enfant pourra grandir et adapter son XO à ses besoins. La plateforme Sugar sur le XO est l'élément clé de notre mission éducative car il offre à l'élève un environnement d'apprentissage unique et intuitif", explique Rodrigo Arboleda, président de l'association OLPC. - -Stormy Peters, Directeur Exécutif de la fondation GNOME, indique que "Nous sommes vraiment enthousiasmés de travailler avec Sugar et le projet OLPC pour fournir une interface bureautique aux enfants de tous les âges. La mission de GNOME est de fournir une interface bureautique libre et accessible à tous. De l'Uruguay au Ghana, les enfants pourront utiliser leurs nouveaux XO pour apprendre et pour montrer à leurs amis et famille comment utiliser Sugar et GNOME." - -Walter Bender, Directeur Exécutif du Sugar Labs, précise que "La fluidité du passage d'un bureau à l'autre offre aux élèves la capacité de passer d'un environnement d'apprentissage - Sugar - à un environnement de production et de productivité - GNOME. Ils ont ainsi les moyens de transformer les compétences créatives qu'ils ont acquis à l'école primaire en des compétences entrepreneuriales dans le cadre de l'enseignement secondaire." - -De plus, Sugar on a Stick permet aux enfants qui n'ont pas l'ordinateur XO de bénéficier de ce nouveau logiciel. Il est téléchargeable sur le site web du Sugar Labs dans sa nouvelle version, v3 "Mirabelle". Il peut être chargé sur n'importe quelle clé USB et utilisé pour démarrer un PC sous Sugar, sans modifier le contenu du disque dur. L'ordinateur XO et Sugar on a Stick fonctionnent avec Fedora GNU/Linux. - -**À propos du Sugar Labs :** -Sugar Labs est une organisation non lucrative de volontaires, membre du projet Software Freedom Conservancy. À l’origine intégré au projet One Laptop Per Child, Sugar Labs coordonne les volontaires dans le monde qui sont passionnés par l’idée de fournir des opportunités d’éducation à travers la plate-forme éducative Sugar. Sugar Labs est soutenu par des donations et cherche des fonds pour accélérer son développement. Pour plus d’information, voir <http://www.sugarlabs.org> - -**À propos de GNOME :** -GNOME est un projet de logiciel libre qui développe, pour toutes les distributions majeures de GNU/Linux et d'Unix, une interface bureautique complète, accessible et facile d'utilisation. Fort d'un succès mondial, grâce à de larges déploiements dans les grandes entreprises et avec des millions d'utilisateurs dans les PME et chez les particuliers, GNOME intègre un environnement de développement permettant de créer de nouvelles applications. La fondation à but non lucratif GNOME est constituée de centaines de volontaires développeurs et entreprises leader sur leur marché. Plus d'informations sont disponibles sur [http://www.gnome.org](http://www.gnome.org) et [http://foundation.gnome.org](http://foundation.gnome.org). - -**À propos de One Laptop per Child** -([http://www.laptop.org](http://www.laptop.org)) : OLPC est une organisation à but non-lucratif créée par Nicholas Negroponte et d'autres membres du Media Lab du MIT afin de concevoir, produire et distribuer des ordinateurs portables suffisamment abordables pour permettre à chaque enfant du monde d'avoir un accès au savoir et aux formes modernes d'éducation. - -*Sugar Labs est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leurs auteurs.* \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2010-06-14-Sugar-Learning-Platform-and-GNOME-Desktop-Now-Shipping-on-the-One-Laptop-per-Child-XO-1.5;-Will-Run-On-New-XO-HS.md b/src/constants/MarkdownFiles/posts/2010-06-14-Sugar-Learning-Platform-and-GNOME-Desktop-Now-Shipping-on-the-One-Laptop-per-Child-XO-1.5;-Will-Run-On-New-XO-HS.md deleted file mode 100644 index 26a5e70f..00000000 --- a/src/constants/MarkdownFiles/posts/2010-06-14-Sugar-Learning-Platform-and-GNOME-Desktop-Now-Shipping-on-the-One-Laptop-per-Child-XO-1.5;-Will-Run-On-New-XO-HS.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: "Sugar Learning Platform and GNOME Desktop Now Shipping on the One Laptop per Child XO-1.5; Will Run On New XO-HS" -category: "PRESS RELEASE" -date: "2010-06-14" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -ASUNCIÓN, June 14, 2010 – Sugar Labs, the GNOME Free Desktop Project, and One Laptop per Child (OLPC) have announced an update to the software offered on the OLPC XO-1.5. The 1.5 million children already using Sugar on the original XO-1 can also benefit from the update, since Paraguay Educa has backported the software. - -The Sugar Learning Platform promotes collaborative learning through child-friendly Activities that encourage critical thinking. The GNOME free desktop is a hallmark of all major GNU/Linux distributions, suitable for older children and grownups. Switching between the two environments takes only a single click. With GNOME on the XO laptop, the door is opened to thousands of additional educational and productivity applications. - -The XO-1.5 has the same industrial design as the original XO-1. Based on a VIA processor, it provides 2× the speed of the XO-1, 4× DRAM memory, and 4× FLASH memory. OLPC has announced the availability of a high-school edition of the XO-1.5, the XO-HS, with a newly designed keyboard, more comfortable for older students. The first deployment of the XO-HS is set to begin in Uruguay under the highly successful Plan Ceibal in September. - -Children familiar with the XO-1 will naturally grow into the XO-1.5 with its expanded functionality. “One Laptop per Child promotes open-source software so that it can grow and adapt to the needs of the child. The Sugar platform on the XO is key to our educational mission because it gives students a unique and intuitive learning software environment,” said OLPC Association CEO Rodrigo Arboleda. - -Stormy Peters, Executive Director of the GNOME Foundation, said, “We're really excited to be working with Sugar and OLPC to provide desktop software to children of all ages. GNOME's mission is to provide a free desktop accessible to everyone. Children from Uruguay to Ghana will be able to use their XOs to learn and to show their friends and families how to use Sugar and GNOME.” - -Walter Bender, Executive Director of Sugar Labs, said “the fluidity of movement between the two desktops gives learners the ability to transition from a learning environment – Sugar – to a production and productivity environment – GNOME. They have the means of honing the creative skills acquired in an elementary education setting into entrepreneurial skills in a secondary education setting.” - -“Sugar on a Stick” allows children who don't have an XO laptop to benefit from this new software. Available for download from Sugar Labs in the new, v3 Mirabelle flavor, it can be loaded onto an ordinary USB thumbdrive and used to start a PC in Sugar without touching the hard disk. The XO laptops and Sugar on a Stick run Fedora GNU/Linux. - -### About Sugar Labs - -Sugar Labs, a volunteer-driven, nonprofit organization, is a member project of the Software Freedom Conservancy. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. Sugar Labs is supported by donations and is seeking funding to accelerate development. For more information, please visit [http://www.sugarlabs.org](http://www.sugarlabs.org). - -### About GNOME - -GNOME is a free-software project which develops a complete, accessible and easy-to-use desktop standard on all leading GNU/Linux and Unix distributions. Popular with large corporate deployments and millions of small-business and home users worldwide, it includes a development environment to create new applications. The nonprofit GNOME Foundation is composed of hundreds of volunteer developers and industry-leading companies. More information can be found at [http://www.gnome.org](http://www.gnome.org) and [http://foundation.gnome.org](http://foundation.gnome.org). - -### About One Laptop per Child - -[http://www.laptop.org](http://www.laptop.org): OLPC is a non-profit organization created by Nicholas Negroponte and others from the MIT Media Lab to design, manufacture and distribute laptop computers that are inexpensive enough to provide every child in the world access to knowledge and modern forms of education. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2010-06-14-Sugar-Learning-Platform-e-GNOME-Desktop-sono-disponibili-per-gli-XO-1.5-di-One-Laptop-per-Child;-Compatibili-anche-per-i-nuovi-XO-HS-High-School-Edition.md b/src/constants/MarkdownFiles/posts/2010-06-14-Sugar-Learning-Platform-e-GNOME-Desktop-sono-disponibili-per-gli-XO-1.5-di-One-Laptop-per-Child;-Compatibili-anche-per-i-nuovi-XO-HS-High-School-Edition.md deleted file mode 100644 index f5f49666..00000000 --- a/src/constants/MarkdownFiles/posts/2010-06-14-Sugar-Learning-Platform-e-GNOME-Desktop-sono-disponibili-per-gli-XO-1.5-di-One-Laptop-per-Child;-Compatibili-anche-per-i-nuovi-XO-HS-High-School-Edition.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "Sugar Learning Platform e GNOME Desktop sono disponibili per gli XO-1.5 di One Laptop per Child; Compatibili anche per i nuovi XO-HS High School Edition" -category: "PRESS RELEASE" -date: "2010-06-14" -author: "Sugar Labs" - ---- -<!-- markdownlint-disable --> - -ASUNCIÓN, 14 Giugno, 2010 – Sugar Labs, GNOME Free Desktop Project, e One Laptop per Child (OLPC) annunciano un aggiornamento al software fornito insieme sui OLPC XO-1.5. Anche il milione e mezzo di bambini che già utilizzano Sugar con gli XO-1 originali potranno beneficiare dell'aggiornamento grazie al backporting realizzato da Paraguay Educa. - -Sugar Learning Platform promuove l'apprendimento collaborativo attraverso molteplici Attività orientate all'infanzia, studiate anche per stimolare il pensiero critico. Lo GNOME free desktop è il marchio di fabbrica di tutte le principali distribuzioni GNU/Linux ed è ottimo per i bimbi più grandi e gli adolescenti. Per alternare i due ambienti operativi è sufficiente un singolo click. Con GNOME sui laptop XO si apre la porta a migliaia di altri applicativi per la didattica e per la produttività. - -Il laptop XO-1.5 ha design identico all'XO-1 originale. Essendo basato su processore VIA, ha il doppio della velocità, il quadruplo della memoria RAM ed il quadruplo della memoria FLASH rispetto a un XO-1. OLPC ha annunciato la disponibilità di una versione specifica per le scuole superiori dell'XO-1.5, che sarà chiamata XO-HS, dotata di una tastiera riprogettata per essere più funzionale per gli studenti più grandi. La prima consegna di XO-HS è prevista in settembre in Uruguay nel contesto del progetto di successo Plan Ceibal. - -I bambini che hanno già familiarità con XO-1 potranno crescere con le maggiori funzionalità di XO-1.5. “One Laptop per Child" promuove il software libero così che possa crescere, migliorare ed adattarsi alle esigenze dei bambini. La Piattaforma Sugar su XO è un componente chiave per la nostra missione educativa, in quanto offre agli studenti un ambiente software di lavoro uniforme e intuitivo", dichiara Rodrigo Arboleda, CEO della OLPC Association. - -Stormy Peters, Direttore Esecutivo della GNOME Foundation, dichiara, “Siamo entusiasti di avere l'opportunità per lavorare con Sugar e OLPC per fornire un software di desktop ai giovani di tutte le età. La missione di GNOME è quella di realizzare un desktop libero utilizzabile da tutti. Bambini dall'Uruguay al Ghana potranno utilizzare i loro laptop XO per apprendere e insegnare ai loro amici e genitori come utilizzare insieme Sugar e GNOME.” - -Walter Bender, Direttore Esecutivo di Sugar Labs, dichiara “la fluidità di movimento fra i due ambienti desktop offre agli studenti la possibilità di passare da una piattaforma di apprendimento – Sugar – ad un ambiente di produttività e lavoro – GNOME. Avranno quindi gli strumenti per utilizzare le conoscenze creative acquisite nella loro educazione di base per sviluppare capacità imprenditoriali nella educazione secondaria.” - -“Sugar on a Stick” permette ai bambini che non possiedono un laptop XO di beneficiare di questo nuovo software. Disponibile per il download dal sito internet di Sugar Labs nella nuova versione, v3 Mirabelle, può essere caricato su una normale chiavetta USB di memoria ed utilizzata per avviare un PC con Sugar senza modificare in alcun modo il computer ospite. I laptop XO e Sugar on a Stick utilizzano Fedora GNU/Linux. - -**In merito a Sugar Labs**: Sugar Labs, a volunteer-driven, nonprofit organization, è un progetto membro della Software Freedom Conservancy. Originariamente parte del progetto One Laptop Per Child, Sugar Labs coordina volontari di tutto il mondo motivati ad offrire opportunità ai bambini di apprendere attraverso la Sugar Learning Platform. Sugar Labs è sorretta solo da donazioni e sta cercando aiuto e collaborazione da volontari per accelerare lo sviluppo. Per maggiori informazioni visitate: [http://www.sugarlabs.org](http://www.sugarlabs.org). - -**In merito a GNOME**: GNOME è un progetto di free-software che sviluppa un desktop standard completo, accessibile e di facile utilizzo, per tutte le principali distribuzioni GNU/Linux e Unix. Ampiamente conosciuto e utilizzato nelle grandi imprese e in milioni di piccole aziende e utenti privati nel mondo, include anche un ambiente completo di sviluppo per creare nuovi programmi. La nonprofit GNOME Foundation è costituita da centinaia di sviluppatori volontari e da industrie-leader. Ulteriori informazioni possono essere reperite presso: [http://www.gnome.org](http://www.gnome.org) e [http://foundation.gnome.org](http://foundation.gnome.org). - -**In merito a One Laptop per Child** ([http://www.laptop.org](http://www.laptop.org)): OLPC è una organizzazione non-profit creata da Nicholas Negroponte ed altri del MIT Media Lab per progettare, produrre e distribuire laptop computers che siano così economici da poter fornire ad ogni bambino del mondo accesso alla conoscenza e alle più moderne forme di apprendimento. \ No newline at end of file diff --git "a/src/constants/MarkdownFiles/posts/2011-04-15-La-organizaci\303\263n-sin-fines-de-lucro-Sugar-Labs-patrocina-el-equipo-de-ciclistas-Team-Chipotle-para-dar-a-conocer-su-misi\303\263n-educativa..md" "b/src/constants/MarkdownFiles/posts/2011-04-15-La-organizaci\303\263n-sin-fines-de-lucro-Sugar-Labs-patrocina-el-equipo-de-ciclistas-Team-Chipotle-para-dar-a-conocer-su-misi\303\263n-educativa..md" deleted file mode 100644 index 4656c198..00000000 --- "a/src/constants/MarkdownFiles/posts/2011-04-15-La-organizaci\303\263n-sin-fines-de-lucro-Sugar-Labs-patrocina-el-equipo-de-ciclistas-Team-Chipotle-para-dar-a-conocer-su-misi\303\263n-educativa..md" +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "La organización sin fines de lucro Sugar Labs patrocina el equipo de ciclistas Team Chipotle para dar a conocer su misión educativa." -excerpt: "Sugar Labs se asocia con el equipo de ciclismo Team Chipotle en un acuerdo innovador de patrocinio para recaudar fondos y dar a conocer su misión educativa, involucrando a niños en Uruguay para documentar la carrera usando sus laptops XO." -category: "PRESS RELEASE" -date: "2011-04-15" -slug: "sugar-labs-patrocina-team-chipotle-mision-educativa" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "ciclismo,educacion,olpc,uruguay,team-chipotle,stem,plan-ceibal,laptops-xo" ---- -<!-- markdownlint-disable --> - -MONTEVIDEO, Uruguay, Abril 15, 2011 — Sugar Labs (R), el fabricante de software para el proyecto One Laptop Per Child (OLPC), va a patrocinar a Team Chipotle, el equipo de ciclistas de Slipstream Sports LLC en un acuerdo sin precedentes que permitirá recabar fondos para la organización sin fines de lucro. La participación del equipo Chipotle permitirá que se conozca la labor de Sugar Labs a lo largo de todo el mundo: la camiseta del equipo Chipotle Development llevará el logo de Sugar Labs. - -"El joven equipo de ciclistas Slipstream Sports ha surgido del objetivo fundacional de la compañía de apoyar los jóvenes talentos y desarrollar la próxima generación de campeones de ciclismo. A los niños les encantan las carreras de bicicletas, y los jóvenes ciclistas son excelentes referentes para los ellos", dijo Jonathan Vaughters, CEO de Slipstream Sports. "Queremos generar un cambio en las vidas de los jóvenes estudiantes y atletas y nuestro innovador acuerdo de patrocinio con Sugar Labas es parte de ello." - -El equipo participará durante los próximos 10 días en la 68a. Vuelta Ciclista del Uruguay 2011. Los escolares uruguayos se incorporarán al evento tomando fotos y escribiendo artículos con sus laptops verdes XO cuando la carrera llegue a sus ciudades. Enviarán su trabajo a [concurso@rapceibal.info](mailto:concurso@rapceibal.info) para que se publique en el blog [http://www.sugarlabs.org/vueltaciclista](http://www.sugarlabs.org/vueltaciclista). Los mejores artículos recibirán premios que serán entregados en el próximo evento de desarrolladores de software eduJAM! que tendrá lugar en Montevideo del 5 al 7 de mayo ([http://ceibaljam.org](http://ceibaljam.org)). - -"Los deportes y STEM (por ciencia, tecnología, ingeniería y matemáticas en inglés) tienen una gran sinergia. Estamos entusiasmados con las oportunidad de despertar el interés de los niños en matemáticas y ciencia a través de su interés por la carrera", dijo Walter Bender, fundador y director ejecutivo de Sugar Labs. - -Uruguay es el primer país en el mundo de equipar al 100% de estudiantes y maestros de escuela primaria, más de medio millón de personas, con una laptop OLPC XO ejecuando Sugar a través del Plan Ceibal ([http://ceibaljam.org](http://ceibaljam.org)). - -Según Gabriel Eirea del CeibalJAM!, "Esta carrera, luego del fútbol, es el evento deportivo más popular en nuestro país y es una parte integral de la cultura local. Cada año durante Semana Santa esta carrera recorre muchas localidades remotas del país y es seguida por cientos de miles de entusiastas espectadores. La comunidad de voluntarios que apoya la implementación del Plan Ceibal, representada por RAP Ceibal y ceibalJAM!, desea promover el uso de las laptops XO en las escuelas, en las comunidades y promueve la apropiación de la tecnología. Con la plataforma Sugar y la laptop XO, nuestros niños no solamente consumen contenido, sino que lo generan. Durante la carrera, niños de todo el país bloguearán sobre el equipo. En el evento eduJAM!, desarrolladores de la plataforma Sugar se encontrarán con niños que se beneficiarán de su trabajo y son el centro de su misión." - -Image:  - -**Sobre Sugar Labs®**: Sugar Labs, una organización sin fines de lucro, conducida por voluntarios, es un proyecto miembro de Software Freedom Conservancy. Originalmente parte del proyecto One Laptop Per Child, Sugar Labs coordina voluntarios en todo el mundo que tienen pasión por dar a los niños oportunidades de educarse a través de la Plataforma de Aprendizaje Sugar. Sugar Labs se mantiene en base a donaciones y está buscando financiación y voluntarios para acelerar su desarrollo. Por más información, visite por favor [http://www.sugarlabs.org](http://www.sugarlabs.org). - -**Sobre Slipstream Sports LLC**: fundada en 2005, Slipstream Sports, LLC es una empresa de avanzada en el rubro de gestión deportiva dedicada a promover el crecimiento ético del ciclismo y desarrollar la próxima generación de campeones de ciclismo. Por más información, por favor visite [http://www.slipstreamsports.com](http://www.slipstreamsports.com). - -*Sugar Labs es una marca registrada de Software Freedom Conservancy. Otros nombres son marcas registradas de sus respectivos dueños.* - -**NOTA:** El equipo Chipotle Development desafortunadamente no va a participar de la 68a. Vuelta Ciclista del Uruguay este año. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2011-04-15-Sugar-Labs-Nonprofit-Sponsoring-Team-Chipotle-to-Raise-Awareness-of-Educational-Mission.md b/src/constants/MarkdownFiles/posts/2011-04-15-Sugar-Labs-Nonprofit-Sponsoring-Team-Chipotle-to-Raise-Awareness-of-Educational-Mission.md deleted file mode 100644 index ad119638..00000000 --- a/src/constants/MarkdownFiles/posts/2011-04-15-Sugar-Labs-Nonprofit-Sponsoring-Team-Chipotle-to-Raise-Awareness-of-Educational-Mission.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Sugar Labs Nonprofit Sponsoring Team Chipotle to Raise Awareness of Educational Mission" -excerpt: "Sugar Labs partners with Team Chipotle cycling team in an innovative sponsorship arrangement to raise awareness and funds for its educational mission while engaging children in Uruguay to document the race using their XO laptops." -category: "PRESS RELEASE" -date: "2011-04-15" -slug: "sugar-labs-sponsoring-team-chipotle-awareness-educational-mission" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "cycling,education,olpc,uruguay,team-chipotle,stem,plan-ceibal,xo-laptops" ---- -<!-- markdownlint-disable --> - - -MONTEVIDEO, Uruguay, April 15, 2011 — Sugar Labs®, software provider to the -One Laptop Per Child (OLPC) project, will sponsor Team Chipotle, the -Continental cycling team owned and operated by Slipstream Sports LLC, in a -groundbreaking arrangement which will raise funds to support the nonprofit's -educational mission. Team Chipotle will raise awareness for Sugar Labs at -races around the world with team jerseys carrying the Sugar Labs logo. - -"Team Chipotle has grown out of our founding goal of developing the next -generation of cycling champions. Every kid loves a bike race and young -cyclists provide great role models for children," said Jonathan Vaughters, CEO -of Slipstream Sports. "We want to make a difference in the lives of young -athletes and children and our innovative sponsorship arrangement with Sugar -Labs is part of that." - -The team will race over the next ten days in the 68th Vuelta Ciclista del -Uruguay 2011 and pupils there will participate, taking photos and writing -articles with their green XO laptops as the race passes through their towns, -and e-mailing them to -[concurso@rapceibal.info](mailto:concurso@rapceibal.info) for posting to a -blog ([http://www.sugarlabs.org/vueltaciclista](http://www.sugarlabs.org/vueltaciclista)). The best articles will win -prizes to be awarded at the eduJAM! Developers Summit which will take place in -Montevideo May 5–7 ([http://ceibaljam.org](http://ceibaljam.org)). - -"Sports and STEM (Science, Technology, Engineering, and Mathematics) have a -great synergy. We are excited by the prospect of engaging children in learning -math and science through their excitement about the race", said Walter Bender, -founder and Executive Director of Sugar Labs. - -Uruguay is the first country in the world to provide 100% of its elementary -school pupils and teachers - over half a million - with an OLPC XO laptop -running Sugar through its Plan Ceibal ([http://ceibaljam.org](http://ceibaljam.org)). - -According to Gabriel Eirea of CeibalJAM!, "This race is, after football, the -most popular sports event in the country and is an integral part of our local -culture. Every year during Holy Week this race passes through the remotest -towns of the country and is followed by hundreds of thousands of enthusiastic -viewers. The volunteer community supporting Plan Ceibal, represented by RAP -Ceibal and ceibalJAM!, wants to promote the use of XO laptops beyond the -schools, inside the communities, advocating technology appropriation. With -Sugar and the XO, our children don't just consume content, they create it. -During the race, children throughout the country will be blogging about the -team. At eduJAM!, Sugar Labs developers will meet children who are at the -center of their mission and benefit from their work." - -Image:  - -About Sugar Labs: Sugar Labs, a volunteer-driven, nonprofit organization, is a -member project of the Software Freedom Conservancy. Originally part of the One -Laptop Per Child project, Sugar Labs coordinates volunteers around the world -who are passionate about providing educational opportunities to children -through the Sugar Learning Platform. Sugar Labs is supported by donations and -is seeking funding to accelerate development. For more information, please -visit [http://www.sugarlabs.org](http://www.sugarlabs.org). - -About Slipstream Sports LLC: Founded in 2005, Slipstream Sports, LLC is a -highly progressive sports management company dedicated solely to promoting the -ethical growth of cycling and developing the next generation of cycling -champions. For more information, please visit -[http://www.slipstreamsports.com](http://www.slipstreamsports.com). - -Sugar Labs is a registered trademark of the Software Freedom Conservancy. -Other names are trademarks of their respective owners. - -NOTE: The Chipotle Development Team will unfortunately not race in the Vuelta -Ciclista del Uruguay this year. \ No newline at end of file diff --git "a/src/constants/MarkdownFiles/posts/2013-02-05-La-organizaci\303\263n-educacional-sin-fines-de-lucro-Sugar-Labs(R)-celebra-el-D\303\255a-del-Aprendizaje-Digital-con-dos-ganadores-del-premio-Google-Code-In.md" "b/src/constants/MarkdownFiles/posts/2013-02-05-La-organizaci\303\263n-educacional-sin-fines-de-lucro-Sugar-Labs(R)-celebra-el-D\303\255a-del-Aprendizaje-Digital-con-dos-ganadores-del-premio-Google-Code-In.md" deleted file mode 100644 index 5d7512ea..00000000 --- "a/src/constants/MarkdownFiles/posts/2013-02-05-La-organizaci\303\263n-educacional-sin-fines-de-lucro-Sugar-Labs(R)-celebra-el-D\303\255a-del-Aprendizaje-Digital-con-dos-ganadores-del-premio-Google-Code-In.md" +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "La organización educacional sin fines de lucro Sugar Labs(R) celebra el Día del Aprendizaje Digital con dos ganadores del premio Google Code-In" -excerpt: "Sugar Labs anuncia que dos estudiantes, Agustín Zubiaga Sánchez y Aneesh Dogra, han sido ganadores del premio principal de Google Code-In por sus significativas contribuciones a la plataforma de aprendizaje Sugar." -category: "PRESS RELEASE" -date: "2013-02-05" -slug: "sugar-labs-celebra-dia-aprendizaje-digital-ganadores-code-in" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "google-code-in,dia-aprendizaje-digital,educacion,programacion,estudiantes,codigo-abierto,python" ---- -<!-- markdownlint-disable --> - -[PDF](/assets/post-assets/press/SugarLabsPR-es.20130205.pdf) - -CAMBRIDGE, Mass, 5 de Febrero del 2013 – Sugar Labs(R), una organización educativa sin fines de lucro, proveedora de software libre para el aprendizaje para niños, se enorgullece de celebrar el 6 de febrero como el Día del Aprendizaje Digital. -**Enlace:** [Digital Learning Day](http://www.digitallearningday.org) - -...con dos ganadores del principal premio del Google Code-In, Agustin Zubiaga Sanchez y Aneesh Dogra, quienes tuvieron una brillante participación en el programa anual de Google, para estudiantes de entre 13 y 17 años de edad. Más de 50 participantes de 14 países participaron para mejorar Sugar, guiados por 22 voluntarios de Sugar Labs(R). Los ganadores visitarán las instalaciones de Google en Mountain View, CA, esta primavera. -**Más info:** [Google Code-In 2012](http://developers.google.com/open-source/gci/2012) - -Agustin (Aguz para sus amigos) tiene 15 años, vive en un pueblo de Uruguay y es un reciente graduado de la escuela técnica Rafael Perazza dependiente de la Universidad del Trabajo del Uruguay. Luego de usar Sugar por varios años, su maestro del club de computadoras lo animó a aprender el lenguaje de programación Python usado en Sugar. Uno de sus proyectos involucra código para agregar una imagen de fondo a la Vista de Hogar de Sugar. Él dice: "Comencé a programar gracias a Sugar y ahora estoy muy contento de ser uno de sus desarrolladores." - -Aneesh, quien ya ganó el Google Code-In del año anterior, tiene 17 años y vive en Punjab, India. Él trabajó actualizando un gran número de Actividades Sugar para niños y contribuyó con el libro electrónico "Cómo hacer una Actividad Sugar". -**Libro (EN):** [Make Your Own Sugar Activities](http://www.flossmanuals.net/make-your-own-su%20gar-activities) -**Libro (ES):** [Cómo Hacer una Actividad Sugar](http://en.flossmanuals.net/como-hacer-una-actividad-sugar) - -Habiendo ganado premios previamente, incluyendo el Concurso Raspberry Pi Summer Coding del último año, está interesado en aplicaciones audiovisuales y seguridad informática. -**Premio anterior:** [Raspberry Pi Summer Coding](http://www.raspberrypi.org/archives/2544) -**Blog personal de Aneesh:** [anee.me](http://anee.me) - -"Fue muy difícil elegir los ganadores," comentó Chris Leonard, enlace por Sugar Labs(R) para el Google Code-In. "Un tercio de nuestros participantes completó múltiples tareas. Aneesh fue muy prolífico, completando más de 40 tareas y Aguz hizo mejoras fundamentales en la plataforma Sugar. Todos nuestros participantes aprendieron cosas en estos tres meses. Notablemente, un participante, Daniel Francis, de Uruguay, tuvo que retirarse del concurso porque fue elegido para la Comisión de Supervisión de Sugar Labs, durante el concurso, a la madura edad de 14 años." - -"Seis años después de que Sugar apareció en las aulas, su primera generación de estudiantes está convirtiéndose en los ingenieros, escritores y maestros del mañana," dice Walter Bender, fundador de Sugar Labs. "Aguz y Daniel crecieron con Sugar en Uruguay donde es usado en cada escuela, y Google Code-In tuvo su primer participante desde Perú, donde Sugar es parte de un programa nacional también. Sugar fue diseñado para tener un piso bajo, sin techo, y su Diario, Actividades, colaboración integrada y Visualización de código lo hacen ideal para el aula." - -Aunque Sugar es usado principalmente en países en desarrollo mundialmente a través del programa One Laptop Per Child, apela a que todos los niños descubran la era digital del siglo 21. -**Conoce más:** [One Laptop Per Child](http://laptop.org) - -El Dr. Gerald Ardito, un miembro del comité para Sugar Labs(R), maestro de escuela media y profesor de Ciencias de la Computación en Westchester, NY, ha usado las Laptops XO y Sugar en una variedad de contextos educacionales. "Lo que ha sido tan poderoso es ver a los estudiantes ser capaces de tomar posesión real de su aprendizaje cuando usan Sugar", él dice. "Los he visto una y otra vez, pasar de ser consumidores a ser productores de medios digitales." - -Sugar Labs(R) desea agradecer a Google y a Bradley Kuhn de la organización Software Freedom Conservancy, madre de Sugar Labs y otros proyectos de software libre/código abierto. - -**Imagen del anuncio:** - - ---- - -**Sobre Sugar Labs(R):** -Sugar Labs, una organización sin fines de lucro, conducida por voluntarios, es un proyecto miembro de Software Freedom Conservancy. Originalmente parte del proyecto One Laptop Per Child, Sugar Labs coordina voluntarios en todo el mundo que tienen pasión por dar a los niños oportunidades de educarse a través de la Plataforma de Aprendizaje Sugar. -Sugar Labs se mantiene en base a donaciones y está buscando financiación y voluntarios para acelerar su desarrollo. -**Sitio oficial:** [www.sugarlabs.org](http://www.sugarlabs.org) - -*Sugar Labs es una marca registrada de la Software Freedom Conservancy. Otros nombres y marcas corresponden a sus respectivos dueños.* \ No newline at end of file diff --git "a/src/constants/MarkdownFiles/posts/2013-02-05-Le-Sugar-Labs(R),-organisme-non-lucratif-\303\240-but-\303\251ducatif.md" "b/src/constants/MarkdownFiles/posts/2013-02-05-Le-Sugar-Labs(R),-organisme-non-lucratif-\303\240-but-\303\251ducatif.md" deleted file mode 100644 index 5f20b865..00000000 --- "a/src/constants/MarkdownFiles/posts/2013-02-05-Le-Sugar-Labs(R),-organisme-non-lucratif-\303\240-but-\303\251ducatif.md" +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Le Sugar Labs(R), organisme non lucratif à but éducatif, célèbre le 'Digital Learning Day' avec deux lauréats au grand prix du 'Google Code-In'" -excerpt: "Sugar Labs annonce deux étudiants, Agustin Zubiaga Sanchez et Aneesh Dogra, comme lauréats du grand prix Google Code-In qui ont apporté des contributions significatives à la plateforme d'apprentissage Sugar." -category: "PRESS RELEASE" -date: "2013-02-05" -slug: "sugar-labs-celebre-digital-learning-day-lauréats-google-code-in" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "google-code-in,digital-learning-day,education,programming,students,open-source,python" ---- -<!-- markdownlint-disable --> - -[PDF](/assets/post-assets/press/SugarLabsPR-fr.20130205.pdf) - -Cambridge (Massachusetts), 5 février 2013 — Le Sugar Labs(R), l'éditeur éducatif à but non lucratif de logiciels libres et ouverts à destination des enfants, a le plaisir de célébrer la Journée d'Apprentissage Numérique (Digital Learning Day) du 6 février. -**Lien :** [Digital Learning Day](http://www.digitallearningday.org) - -Avec les lauréats au grand prix Google Code-In : -**Lien :** [Google Code-In 2012](http://developers.google.com/open-source/gci/2012) -Agustin Zubiaga Sanchez et Aneesh Dogra, deux participants brillants au programme annuel de Google destiné aux élèves de l'enseignement secondaire, âgés de 13 à 17 ans. Plus de 50 participants représentant 14 pays, accompagnés par 22 tuteurs volontaires pour le Sugar Labs, ont contribué à améliorer Sugar. Les lauréats visiteront le siège de Google à Mountain View, en Californie, au cours du printemps prochain. Google Code-In et son programme associé destiné aux étudiants de niveau universitaire, le Google Summer of Code, invitent les organismes open source à encadrer des étudiants travaillant sur des tâches de programmation et de documentation réelles. - -Agustin (Aguz pour ses amis) est âgé de 15 ans. Il vit dans un village en Uruguay et vient d'obtenir son diplôme universitaire du centre Rafael Perazza de l'Universidad del Trabajo del Uruguay (UTU). Utilisateur de Sugar depuis plusieurs années, son enseignant du club informatique l'a encouragé à apprendre le langage de programmation Python utilisé par Sugar. L'un de ses projets consistait à ajouter des images d'arrière-plan à la page d'accueil de Sugar. Il déclare : "C'est grâce à Sugar que j'ai commencé à programmer. Aujourd'hui, je suis très heureux d'être l'un de ses développeurs." - -Aneesh, lui aussi lauréat du Google Code-In de l'an passé, a 17 ans et vit au Punjab, en Inde. Il a participé à la mise à jour de plusieurs "apps" Sugar destinées aux enfants et a contribué à la rédaction du livre électronique : -**Lien :** [Réalisez votre propre activité Sugar](http://www.flossmanuals.net/make-your-own-sugar-activities) - -Après avoir gagné différents prix, parmi lesquels : -**Lien :** [Raspberry Pi Summer Coding Contest](http://www.raspberrypi.org/archives/2544), -il s'intéresse aux applications audiovisuelles et à la sécurité informatique. Aneesh publie son blog : -**Lien :** [anee.me](http://anee.me) - -"Choisir les lauréats n'était pas une tâche facile", explique Chris Leonard, le correspondant du Sugar Labs auprès du Google Code-In. "Un bon tiers de nos participants ont réalisé différentes tâches. Aneesh a eu une activité prolifique, avec plus de 40 tâches à son actif, et Aguz a apporté des améliorations capitales à la plateforme Sugar. Tous nos participants ont beaucoup appris au cours de ces trois derniers mois. Fait remarquable, l'un des participants, Daniel Francis, d'Uruguay, a dû se retirer du concours après avoir été désigné au Sugar Labs Oversight Board pendant le déroulement du concours. Détail important : il vient tout juste d'avoir 14 ans." - -"Six ans après la première utilisation de Sugar dans des salles de classe, cette première génération d'étudiants préfigure les ingénieurs, les auteurs et les enseignants de demain," a déclaré Walter Bender, le fondateur du Sugar Labs. "Aguz et Daniel ont grandi avec Sugar, en Uruguay, alors que Sugar est utilisé dans toutes les écoles et que le Google Code-In compte son tout premier participant originaire du Pérou, pays dans lequel Sugar intègre également le cursus scolaire national. Sugar a été conçu pour sa facilité d'accès et son potentiel illimité. Le 'Journal', les 'Activités', les fonctions de collaboration et de visualisation du code source, qui intègrent la plateforme Sugar, en font un instrument idéal pour la classe." - -Sugar est utilisé dans de nombreux pays émergents dans le monde entier, participant au programme : -**Lien :** [One Laptop Per Child](http://laptop.org) -Il s'adresse, plus largement, à tous les enfants qui découvrent le 21ème siècle numérique. - -Gerald Ardito, membre du bureau du Sugar Labs, enseignant de collège et professeur d'informatique à Westchester (New-York), utilise Sugar dans différents contextes éducatifs. De son propre aveu, "Observer les étudiants prendre littéralement en mains leur propre apprentissage grâce à Sugar est une expérience unique". "J'ai observé à de nombreuses reprises, au cours de ces dernières années, comment ils passaient du stade de consommateurs de médias numériques à celui de producteurs." - -Le Sugar Labs tient à exprimer sa gratitude à Google et tout particulièrement à Bradley Kuhn, le directeur exécutif du Software Freedom Conservancy, organisme fédérant le Sugar Labs et 27 autres projets de logiciels libres et ouverts. - -**Image :** - - ---- - -**À propos de Sugar Labs(R)** -Sugar Labs(R) est une organisation non lucrative de volontaires, membre du projet Software Freedom Conservancy. À l’origine intégré au projet One Laptop Per Child, Sugar Labs coordonne les volontaires dans le monde qui sont passionnés par l’idée de fournir des opportunités d’éducation à travers la plate-forme éducative Sugar. Sugar Labs(R) est soutenu par des donations et cherche des fonds pour accélérer son développement. Pour plus d’information, voir [www.sugarlabs.org/press](http://www.sugarlabs.org/press) ou contacter **pr@sugarlabs.org**. - -*Sugar Labs(R) est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leur auteurs.* \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2013-02-05-Sugar-Labs(R)-Educational-Nonprofit-Celebrates-Digital-Learning-Day-With-Two-Google-Code-In-Grand-Prize-Winners.md b/src/constants/MarkdownFiles/posts/2013-02-05-Sugar-Labs(R)-Educational-Nonprofit-Celebrates-Digital-Learning-Day-With-Two-Google-Code-In-Grand-Prize-Winners.md deleted file mode 100644 index 3a045f3a..00000000 --- a/src/constants/MarkdownFiles/posts/2013-02-05-Sugar-Labs(R)-Educational-Nonprofit-Celebrates-Digital-Learning-Day-With-Two-Google-Code-In-Grand-Prize-Winners.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: "Sugar Labs(R) Educational Nonprofit Celebrates Digital Learning Day With Two Google Code-In Grand Prize Winners" -excerpt: "Sugar Labs announces two students, Agustin Zubiaga Sanchez and Aneesh Dogra, as Google Code-In grand prize winners who made significant contributions to the Sugar Learning Platform." -category: "PRESS RELEASE" -date: "2013-02-05" -slug: "sugar-labs-celebrates-digital-learning-day-code-in-winners" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "google-code-in,digital-learning-day,education,programming,students,open-source,python" ---- -<!-- markdownlint-disable --> - -[PDF](/assets/post-assets/press/SugarLabsPR-en.20130205.pdf) - -CAMBRIDGE, Mass, February 5, 2013 — Sugar Labs(R), educational nonprofit provider of free and open-source learning software for children, is proud to celebrate **[Digital Learning Day](http://www.digitallearningday.org)** on February 6th with **[Google Code-In](http://developers.google.com/open-source/gci/2012)** grand prize winners Agustin Zubiaga Sanchez and Aneesh Dogra, who participated brilliantly in Google's annual program for middle and high school students aged 13 to 17. Over 50 participants from 14 countries, mentored by 22 Sugar Labs volunteers, helped to improve Sugar. The winners will visit Google headquarters in Mountain View, CA this spring. Google Code-In and its sister program for university students, Google Summer of Code, invite open source organizations to mentor students who work on real programming and documentation tasks. - -Agustin (Aguz to his friends) is 15, lives in a village in Uruguay and is a recent graduate of Rafael Perazza Technical High School at Universidad del Trabajo del Uruguay. After using Sugar for several years, his computer club teacher encouraged him to learn the Python programming language used in Sugar. One of his projects involved code to add background images to Sugar's Home View. He says, "I started programming thanks to Sugar and now I am very happy to be one of its developers." - -Aneesh, also a winner at last year's Google Code-In, is 17 and lives in Punjab, India. He worked on updating a large number of Sugar "Apps" for children and contributed to the "**[Make Your Own Sugar Activities!](http://www.flossmanuals.net/make-your-own-sugar-activities)**" ebook. Having won previous honors, including runner-up in last year's **[Raspberry Pi Summer Coding Contest](http://www.raspberrypi.org/archives/2544)**, he is interested in audiovisual applications and computer security. More information about Aneesh is available on his **[blog](http://anee.me)**. - -"We had a hard time choosing our winners," commented Chris Leonard, Sugar Labs liaison for Google Code-In. "Fully a third of our participants completed multiple tasks. Aneesh was prolific, completing over 40 tasks, and Aguz made fundamental improvements to the Sugar platform itself. All of our participants learned over these past three months. Notably, one participant, Daniel Francis of Uruguay, had to take his name out the running because he was elected to the Sugar Labs Oversight Board during the contest at the ripe old age of 14." - -"Six years after Sugar first appeared in classrooms, its first generation of learners are becoming tomorrow's engineers, writers, and teachers," said Walter Bender, founder of Sugar Labs. "Aguz and Daniel grew up with Sugar in Uruguay where Sugar is used in every school and Google Code-In had its first ever participant from Peru, where Sugar is part of the nationwide curriculum as well. Sugar was designed to be low floor, no ceiling and its Journal, Activities, built-in collaboration and View Source features make Sugar ideal for the classroom." - -Sugar is used in developing countries worldwide through the **[One Laptop Per Child program](http://laptop.org)**, but it also appeals to all children discovering the digital 21st century. Dr. Gerald Ardito, a Sugar Labs board member, as well as a middle school teacher and professor of Computer Science in Westchester, NY, has used Sugar in a variety of educational settings. "It is so powerful to watch students be able to take real ownership of their learning when they are using Sugar", he said. "I have seen them time and time again move from being consumers of computer centered media to producers." - -Sugar Labs wishes to thank Google and in particular Bradley Kuhn, executive director of the Software Freedom Conservancy, parent organization of Sugar Labs and 27 other free/libre software projects. - -**Image:** - - ---- - -**About Sugar Labs(R):** -Sugar Labs(R), a volunteer-driven, educational nonprofit organization, is a member project of the Software Freedom Conservancy. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. Sugar Labs(R) is supported by donations and is seeking funding to accelerate development. For more information, please visit [sugarlabs.org/press](http://www.sugarlabs.org/press) or contact pr@sugarlabs.org. - -Sugar Labs(R) is a registered trademark of the Software Freedom Conservancy. Other names are trademarks of their respective owners. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2013-10-12-Children-Programmers-Abound-at-First-International-TurtleArt-Day.md b/src/constants/MarkdownFiles/posts/2013-10-12-Children-Programmers-Abound-at-First-International-TurtleArt-Day.md deleted file mode 100644 index 8120ef12..00000000 --- a/src/constants/MarkdownFiles/posts/2013-10-12-Children-Programmers-Abound-at-First-International-TurtleArt-Day.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Children Programmers Abound at First International TurtleArt Day" -excerpt: "Sugar Labs celebrates the first TurtleArt Day in Caacupé, Paraguay, with 275 students and 77 teachers exploring creative programming through the TurtleArt environment." -category: "PRESS RELEASE" -date: "2013-10-12" -slug: "children-programmers-first-international-turtleart-day" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "turtleart,programming,education,art,logo,children,paraguay,international-day" ---- -<!-- markdownlint-disable --> - -[PDF](/assets/post-assets/press/SugarLabsPR-en.20131015.pdf) - -CAACUPÉ, Paraguay, October 12, 2013 — Sugar Labs®, educational nonprofit provider of free and open-source learning software for children, is proud to celebrate **TurtleArt Day** -- **Event Info:** [TurtleArt Day](http://turtleartday.org) -in Caacupé, Paraguay, with 275 students, their parents, and 77 teachers. They were joined by educators and Sugar developers from 8 countries throughout the Americas and as far away as Australia. Additional TurtleArt Days are planned for Peru, Costa Rica, Argentina, and Malaysia; the next will be October 15th in Montevideo, Uruguay. - -Caacupé has been the focus of a one-to-one learning program run by -- **Organization:** [Paraguay Educa](http://www.paraguayeduca.org) -since 2008. The foundation is active in 35 schools, working with 365 teachers and 9,700 children. The children of Caacupé live in areas with high poverty levels: 60% of them are street workers and most have at least one parent living abroad. Much of the coordination was done by "Evolution" children, youth leaders in Caacupé who attend school in the morning, teach in the afternoon, and on weekends supply technical support to school programs. - -TurtleArt is a programming environment with a graphical "turtle" that draws colorful art based on snap-together elements. Its "low floor" provides an easy entry point for beginners. It also has "high ceiling" programming features that challenge the more adventurous student. TurtleArt's roots are in Logo, the first programming language for children, created by Seymour Papert, Wally Feurzeig, Daniel Bobrow, and Cynthia Solomon in 1967. Logo's friendly turtle, which relies on instructions from children to move, has inspired adaptations from Logo for the Apple® II to Lego® Mindstorms®, TurtleArt, and Scratch. - -An international group of TurtleArtists travelled to Caacupé with the generous support of BBVA Bank to launch the first TurtleArt Day. Also participating was -- **EduJam Group:** [EduJam!](http://ceibaljam.org) -attendants, a group of developers who work on open-source educational software. Caacupé's participants enjoyed workshops to create TurtleArt projects; interactive programming that involved robots and sensors; and discussions where educators and children shared their experiences. - -> "Logo was designed to be 'mathland'; TurtleArt is 'artland'," says Artemis Papert, co-creator of TurtleArt. -> "It allows us to bring together art and programming. While you do art, you also do programming, math, and geometry — the tools you need while focusing on doing art. We have observed that artists become more comfortable with programming and programmers become more comfortable with art when they use TurtleArt." - -Cecilia Rodríguez Alcalá, Executive Director of Paraguay Educa, said, -> "The aspects of TurtleArt Day highlighted by the Evolution team included cultural exchange between the children and the international community, and children teaching each other, pursuing their personal interests, including projects involving physical-world interaction." - -Claudia Urrea, an educator and member of the Sugar Labs Oversight Board, said, -> "With TurtleArt, the children enjoyed programming the robots and using sensors, creating artistic images, engaging in the concrete use of mathematical concepts such as variables and random numbers, realizing how quickly the pace of their learning evolved, and discovering the multiple applicabilities of computation." - -Andres Aguirre of the Butia project, a robot programmed with TurtleArt, said, -> "Even though the children had limited time to use the robots, they were able to experiment with some high-level programming concepts such as conditionals and control structures." - -**Images:** --  --  - ---- - -### About Sugar Labs® -Sugar Labs, a volunteer-driven, nonprofit organization, is a member project of the Software Freedom Conservancy. Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities through the Sugar Learning Platform. Sugar is installed on more than three million computers. Sugar Labs is supported by donations and is seeking funding to accelerate development. - -For more information, please visit [sugarlabs.org/press](http://www.sugarlabs.org/press) or contact **pr@sugarlabs.org**. - -*Sugar Labs® is a registered trademark of the Software Freedom Conservancy. Other names are trademarks of their respective owners.* \ No newline at end of file diff --git "a/src/constants/MarkdownFiles/posts/2013-10-12-Programadores-ni\303\261os-abundan-en-el-primer-D\303\255a-Internacional-de-TurtleArt.md" "b/src/constants/MarkdownFiles/posts/2013-10-12-Programadores-ni\303\261os-abundan-en-el-primer-D\303\255a-Internacional-de-TurtleArt.md" deleted file mode 100644 index 2f55d736..00000000 --- "a/src/constants/MarkdownFiles/posts/2013-10-12-Programadores-ni\303\261os-abundan-en-el-primer-D\303\255a-Internacional-de-TurtleArt.md" +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: "Programadores niños abundan en el primer Día Internacional de TurtleArt" -excerpt: "Sugar Labs celebra el primer Día de Tortugarte en Caacupé, Paraguay, con 275 estudiantes y 77 profesores explorando programación creativa a través del entorno TurtleArt." -category: "PRESS RELEASE" -date: "2013-10-12" -slug: "primer-dia-internacional-turtleart" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "tortugarte,programming,education,art,logo,children,paraguay,international-day" ---- -<!-- markdownlint-disable --> - - -[PDF](/assets/post-assets/press/SugarLabsPR-es.20131015.pdf) - -Caacupé, Paraguay, 12 de octubre de 2013 — Sugar Labs®, el proveedor educativo de aprendizaje sin fines de lucro de software libre y de código abierto para los niños, se enorgullece de celebrar el Día de Tortugarte en Caacupé, Paraguay, con 275 estudiantes, sus padres y 77 profesores. A ellos se sumaron educadores y desarrolladores de Sugar procedentes de 8 países de América y de otros lugares lejanos como Australia. Están previstos Días de Tortugarte adicionales para Perú, Costa Rica, Argentina y Malasia; el próximo será el 15 de octubre en Montevideo, Uruguay. - -Caacupé ha sido objeto del programa Una Computadora Por Niño —modelo de aprendizaje uno a uno— a cargo de Paraguay Educa desde 2008. La fundación opera en 35 escuelas, en colaboración con 365 profesores y 9.700 niños. Los niños y niñas de Caacupé viven en áreas con altos niveles de pobreza: el 60 % de ellos trabaja en la calle y la mayoría tiene al menos un padre que vive en el extranjero. Gran parte de la coordinación fue hecha por los chicos "Evolution", líderes juveniles de Caacupé que asisten a la escuela por la mañana, enseñan por la tarde y los fines de semana ofrecen asistencia técnica a los programas escolares. - -Tortugarte es un entorno de programación con una "tortuga" gráfica que dibuja arte colorido a base de elementos de cierre conjunto. Su "piso bajo" proporciona un punto de entrada fácil para los principiantes. También cuenta con funciones de programación de "alto techo" que retan al estudiante más aventurero. Las raíces de Tortugarte están en Logo, el primer lenguaje de programación para niños, creado por Seymour Papert, Wally Feurzeig, Daniel Bobrow y Cynthia Salomón en 1967. La tortuga amistosa del logotipo, que se basa en las instrucciones de los niños para moverse, ha inspirado adaptaciones de Logo para Apple® II, Lego® Mindstorms®, Tortugarte y Scratch. - -Un grupo internacional de Tortu-artistas viajó a Caacupé con el generoso apoyo del banco BBVA para lanzar el primer Día de Tortugarte. También participaron del eduJAM!, un evento de desarrolladores que trabajan en software educativo de código abierto. Los participantes disfrutaron de talleres para crear proyectos de Tortugarte en Caacupé, programación interactiva con robots y sensores, y discusiones donde educadores y niños compartieron sus experiencias. - -"El logotipo fue diseñado para ser 'La Tierra de las Matemáticas'; Tortugarte es 'La Tierra del Arte'", dice Artemis Papert, co-creadora de Tortugarte. "Nos permite reunir el arte y la programación. Mientras uno hace arte, también hace programación, matemáticas y geometría —las herramientas que se necesitan mientras se centra en hacer arte. Hemos observado que los artistas se sienten más cómodos con la programación y los programadores se sienten más cómodos con el arte cuando utilizan Tortugarte." - -Brian Silverman, co-creador de Tortugarte, observó: "Me quedé sorprendido por la pasión de los niños que vinieron al Día de Tortugarte: fueron salvajemente entusiastas y mantuvieron su atención durante seis horas. Llegaron al evento con solo una experiencia rudimentaria en Tortugarte y se fueron con más conocimiento acerca de su potencial artístico". - -Cecilia Rodríguez Alcalá, directora ejecutiva de Paraguay Educa, dijo: "Entre los aspectos destacados del Día de Tortugarte sobresale el desempeño en equipo de los jóvenes Evolution, ya que incluye el intercambio cultural entre los niños y la comunidad internacional, así como la enseñanza entre pares y proyectos de interacción física en el mundo". - -Claudia Urrea, educadora y miembro de la Junta de Supervisión de Sugar Labs, dijo: "Con Tortugarte, los niños disfrutaron de la programación de robots y el uso de sensores, la creación de imágenes artísticas, y la participación concreta en el uso de conceptos matemáticos como variables y números aleatorios. Fue notable la rapidez con que evolucionó su aprendizaje y el descubrimiento de las múltiples aplicaciones de la informática". - -Andrés Aguirre, del proyecto Butiá —un robot programado con Tortugarte—, dijo: "A pesar de que había tiempo limitado para usar los robots, los niños fueron capaces de experimentar con algunos conceptos de programación de alto nivel, tales como condicionales y estructuras de control". - -**Más información:** -- [Día de Tortugarte](http://turtleartday.org) -- [Paraguay Educa](http://www.paraguayeduca.org) -- [Ceibal Jam](http://ceibaljam.org) - -**Imágenes del evento:** --  --  - -**Sobre Sugar Labs®:** -Es una organización sin fines de lucro dirigida por voluntarios, miembro de la Software Freedom Conservancy. Sugar Labs coordina alrededor del mundo a voluntarios apasionados por proveer oportunidades educativas a través de la plataforma de aprendizaje Sugar. Sugar se encuentra instalada en más de tres millones de computadoras. Sugar Labs se mantiene a base de donaciones y busca fondos para acelerar su desarrollo. Para más información visita [sugarlabs.org/press](http://www.sugarlabs.org/press) o escribe a [pr@sugarlabs.org](mailto:pr@sugarlabs.org). - -Sugar Labs es una marca registrada de la Software Freedom Conservancy. Otros nombres y marcas mencionados corresponden a sus respectivos dueños. \ No newline at end of file diff --git "a/src/constants/MarkdownFiles/posts/2013-10-12-Une-foule-d'enfants-programmeurs-participe-\303\240-la-1\303\250re-Journ\303\251e-Internationale-TurtleArt.md" "b/src/constants/MarkdownFiles/posts/2013-10-12-Une-foule-d'enfants-programmeurs-participe-\303\240-la-1\303\250re-Journ\303\251e-Internationale-TurtleArt.md" deleted file mode 100644 index a3464439..00000000 --- "a/src/constants/MarkdownFiles/posts/2013-10-12-Une-foule-d'enfants-programmeurs-participe-\303\240-la-1\303\250re-Journ\303\251e-Internationale-TurtleArt.md" +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: "Une foule d'enfants programmeurs participe à la 1ère Journée Internationale TurtleArt" -excerpt: "Sugar Labs célèbre la première Journée TurtleArt à Caacupé, Paraguay, avec 275 élèves, 77 professeurs et des participants internationaux explorant la programmation créative à travers l'environnement TurtleArt." -category: "PRESS RELEASE" -date: "2013-10-12" -slug: "premiere-journee-internationale-turtleart" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "turtleart,programming,education,art,logo,children,paraguay,international-day" ---- -<!-- markdownlint-disable --> - -[PDF](/assets/post-assets/press/SugarLabsPR-fr.20131015.pdf) - -CAACUPÉ, Paraguay, le 12 Octobre 2013. Sugar Labs(R), fournisseur à but non lucratif de programmes éducatifs gratuits et sous licence libre, célèbre avec une grande fierté la journée TurtleArt à Caacupé, au Paraguay. 275 élèves y participent avec leurs parents ainsi que 77 professeurs. Des éducateurs et des développeurs Sugar se sont joints à eux, venant de 8 pays des Amériques mais aussi d'aussi loin que l'Australie. De nouvelles journées TurtleArt sont prévues au Pérou, au Costa Rica, en Argentine et en Malaysie; la prochaine aura lieu le 15 octobre à Montevideo, Uruguay. - -Caacupé héberge depuis 2008 un programme d'"apprentissage un-à-un" mené par [Paraguay Educa](http://www.paraguayeduca.org). Cette fondation est présente dans 35 écoles, collabore avec 365 professeurs et 9.700 enfants. Les enfants de Caacupé vivent dans des zones de grande pauvreté: 60% d'entre eux sont des travailleurs des rues et la plupart ont au moins un de leur parents qui vit à l'étranger. Une bonne part de la coordination a été assurée par des jeunes de Caacupé, engagés dans le programme "Evolution". Ils suivent les cours à l'école le matin, enseignent l'après-midi et fournissent une assistance technique aux programmes de l'école le week-end. - -TurtleArt est un environnement de programmation au sein duquel une "tortue" graphique trace des dessins colorés à partir d'éléments de base pouvant s'emboîter. Son caractère accessible fait d'elle l'activité idéale pour une initiation à la programmation. TurtleArt trouve ses origines dans le langage Logo, le premier langage de programmation pour enfants créé par Seymour Papert, Wally Feurzeig, Daniel Bobrow et Cynthia Solomon en 1967. La sympathique tortue de Logo, qui se déplace suivant les instructions données par les enfants, a inspiré des adaptations allant de l'Apple(R) II à Lego(R) Mindstorms(R), TurtleArt et Scratch. - -Un groupe international d'artistes TurtleArt a fait le voyage jusqu'à Caacupé pour ce lancement de la première journée TurtleArt, grâce au généreux soutien financier de la banque BBVA. Parmi les participants à cette première journée on trouve aussi des développeurs de [EduJam!](http://ceibaljam.org), groupe qui développe des logiciels éducatifs en licence libre. - -Les participants de Caacupé ont pris part avec enthousiasme à des ateliers autour de projets TurtleArt; de la programmation interactive utilisant des robots et des capteurs et enfin de discussions où éducateurs et enfants ont pu partager leurs expériences. - -"Le langage Logo a été conçu comme le 'royaume des maths'; TurtleArt est plutôt le 'royaume du dessin d'art'" nous confie Artemis Papert, co-créateur de TurtleArt. "Il nous offre la possibilité de réunir dessin et programmation. Quand vous pratiquez le dessin, vous faites aussi de la programmation, des maths et de la géométrie – vous vous en servez comme outil pour dessiner. Nous avons remarqué que les artistes se sentent ensuite plus à l'aise en programmation et les programmeurs plus à l'aise dans les activités artistiques quand ils utilisent TurtleArt." - -Brian Silverman, co-créateur de TurtleArt fait la remarque suivante: "J'ai été fasciné par la passion éveillée chez les enfants venant participer à la journée TurtleArt. Ils étaient enthousiastes en diable et sont restés concentrés pendant six heures. Ils sont venus ici avec une expérience de TurtleArt vraiment rudimentaire et sont repartis avec une meilleure compréhension de son potentiel artistique." - -Cecilia Rodríguez Alcalá, directrice de Paraguay Educa, déclare: "Ce que l'équipe Evolution a mis en lumière lors de cette journée TurtleArt, ce sont les aspects d'échange culturel entre les enfants et la communauté internationale et le fait que les enfants enseignent les uns aux autres, tout en suivant leurs goûts personnels, notamment sur des projets qui comportent une interaction avec le monde physique." - -Claudia Urrea, éducatrice et membre du bureau de supervision de Sugar Labs s'entousiasme : "Avec TurtleArt, les enfants adorent programmer les robots et utiliser les capteurs pour créer des images artistiques, s'adonner à des activités concrètes utilisant des concepts mathématiques tels que les variables et les nombres aléatoires. Ils se rendent compte de la vitesse à laquelle ils apprennent et découvrent les applications multiples de l'informatique." - -Andres Aguirre du projet Butia, un robot programmé avec TurtleArt, déclare: "Bien que les enfants aient disposé d'un temps limité pour utiliser les robots, ils ont pu faire l'expérience de concepts de programmation haut-niveau tels que les tests conditionnels et structures de contrôle." - -- **Lien:** [Día de Tortugarte](http://turtleartday.org) -- **Lien:** [Paraguay Educa](http://www.paraguayeduca.org) -- **Lien:** [CeibalJam!](http://ceibaljam.org) - -Image:  -Image:  - ---- - -**À propos de Sugar Labs(R)** -Sugar Labs(R) est une organisation non lucrative de volontaires, membre du projet Software Freedom Conservancy. Sugar Labs coordonne les volontaires dans le monde qui sont passionnés par l'idée de fournir des opportunités d'éducation à travers la plate-forme éducative Sugar; installée sur plus de 3 millions d'ordinateurs. Sugar Labs(R) est soutenu par des donations et cherche des fonds pour accélérer son développement. Pour plus d'information, voir [http://www.sugarlabs.org/press](http://www.sugarlabs.org/press) ou contacter **pr@sugarlabs.org**. - -Sugar Labs(R) est une marque déposée de la Software Freedom Conservancy. Les autres marques déposées sont la propriété respective de leurs auteurs. \ No newline at end of file diff --git "a/src/constants/MarkdownFiles/posts/2014-01-22-Sugar-Labs(R),-organizaci\303\263n-sin-fines-de-lucro-para-la-Educaci\303\263n-celebra-dos-Ganadores-del-Gran-Premio-de-Google-Code-In.md" "b/src/constants/MarkdownFiles/posts/2014-01-22-Sugar-Labs(R),-organizaci\303\263n-sin-fines-de-lucro-para-la-Educaci\303\263n-celebra-dos-Ganadores-del-Gran-Premio-de-Google-Code-In.md" deleted file mode 100644 index c819ee6e..00000000 --- "a/src/constants/MarkdownFiles/posts/2014-01-22-Sugar-Labs(R),-organizaci\303\263n-sin-fines-de-lucro-para-la-Educaci\303\263n-celebra-dos-Ganadores-del-Gran-Premio-de-Google-Code-In.md" +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Sugar Labs(R), organización sin fines de lucro para la Educación celebra dos Ganadores del Gran Premio de Google Code-In" -excerpt: "Sugar Labs reconoce a los estudiantes Ignacio Rodríguez y Jorge Alberto Gómez López como ganadores del gran premio de Google Code-In, quienes contribuyeron significativamente a mejorar la plataforma de aprendizaje Sugar." -category: "PRESS RELEASE" -date: "2014-01-22" -slug: "sugar-labs-celebra-ganadores-google-code-in" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "google-code-in,open-source,education,students,programming,development,uruguay,el-salvador" ---- -<!-- markdownlint-disable --> - -[PDF](/assets/post-assets/press/SugarLabsPR-es.20140122.pdf) - -CAMBRIDGE, Mass, Enero 22, 2014 — Sugar Labs(R), organización educativa sin fines de lucro que provee software de aprendizaje libre y de código abierto para niños, se enorgullece en reconocer a los ganadores del gran premio de Google Code-In (GCI) Ignacio Rodríguez y Jorge Alberto Gómez López, quienes participaron de forma brillante en el programa anual de Google para estudiantes de secundaria y bachillerato entre 13 a 17 años de edad. - -A través de GCI, Google invita a las organizaciones de código abierto a asesorar estudiantes que trabajan en tareas reales de programación y documentación. Poco más de 30 participantes de más de una docena de países —desde Australia a Zimbabwe—, asesorados por voluntarios de Sugar Labs, ayudaron a mejorar la plataforma de aprendizaje Sugar que utilizan más de tres millones de niños en todo el mundo. Los ganadores visitarán la sede de Google en Mountain View, California esta primavera. - -Ignácio, quien tiene 14 años y vive en Canelones, Uruguay, creció con Sugar y comenzó a participar en el desarrollo de Sugar desde hace tres años. "¡La competencia fue un lugar para socializar y hacer amigos!", dice él. "Aunque sentí presión, la comunidad estaba allí para ayudar." - -Jorge, de 17 años, vive en Santa Tecla, El Salvador. "Nunca en mi vida soñé empezar a trabajar en un proyecto de código abierto; fue muy divertido explorar un mundo totalmente nuevo, aprender nuevas herramientas, y lo más importante, hacer nuevos amigos de diferentes partes del mundo —personas que comparten el mismo objetivo y trabajan como una comunidad. Siento que soy parte de Sugar Labs, que formó parte de un gran proyecto, con los amigos y mentores". - -Completan la lista de finalistas de Sugar Labs: Sai Vineet de Jamshedpur, India; Emil Dudev desde Sofía, Bulgaria; y Sam Parkinson desde Canberra, Australia (la plataforma Sugar se utiliza ampliamente en las escuelas australianas). Sam comentó: "Contribuir a Sugar, además de darme experiencia en programación, me ha mostrado cómo la programación colaborativa puede ser divertida. ¡Y también ha sido divertido trabajar hacia una meta significativa común!" - -"GCI ha hecho evidente que los usuarios de Sugar se están convirtiendo en los desarrolladores de Sugar: Sugar no sólo les da la licencia, sino también los medios para desarrollar sus propias herramientas de aprendizaje. Al tomar posesión, se convierten en responsables," dijo Walter Bender, fundador de Sugar Labs. "Ha sido difícil elegir a los ganadores. Muchos participantes completaron múltiples tareas. Ignacio fue prolífico, completando más de 60 tareas, pero nuestros cinco finalistas realizaron mejoras fundamentales a la plataforma misma de Sugar." - -José Miguel García, un pedagogo del Departamento de Tecnología Educativa de CODICEN-ANEP en Montevideo, observó: "Por segundo año consecutivo, un joven de Uruguay ha ganado la competencia. La implementación del Plan Ceibal, que entrega en propiedad una computadora portátil por niño y adolescente en Uruguay permite alcanzar niveles de equidad en cuanto al acceso a las tecnologías. Estas computadoras portátiles, además de ser utilizadas en la educación formal, permiten a los jóvenes investigar y desarrollarse en diversas actividades, ya sean lúdicas, artísticas, comunicativas, de programación, etc. Estos jóvenes, orientados e incentivados por su familia, profesores y/o por la propia comunidad de Sugar, alcanzan niveles importantes en el desarrollo del conocimiento, habilidad fundamental para la sociedad del siglo XXI." - -Sugar Labs desea agradecer a Google y, en particular, a Bradley Kuhn, director ejecutivo de la Software Freedom Conservancy. - ---- - -**Sobre Google Code-In** -**Sitio Oficial:** [developers.google.com/open-source/gci](http://developers.google.com/open-source/gci) -**Blog Oficial:** [google-opensource.blogspot.fr](http://google-opensource.blogspot.fr/2014/01/google-code-in-2013-drumroll-please.html) - ---- - -**Imágenes** - - - ---- - -**Sobre Sugar Labs(R)** -Sugar Labs, una organización sin fines de lucro conducida por voluntarios, es un proyecto miembro de Software Freedom Conservancy. Originalmente parte del proyecto One Laptop Per Child, Sugar Labs coordina voluntarios en todo el mundo que tienen pasión por dar a los niños oportunidades de educarse a través de la Plataforma de Aprendizaje Sugar. - -Sugar Labs se mantiene en base a donaciones y está buscando financiación y voluntarios para acelerar su desarrollo. Por más información, por favor visite [sugarlabs.org](http://www.sugarlabs.org) o contacte a [pr@sugarlabs.org](mailto:pr@sugarlabs.org). - -Sugar Labs es una marca registrada de la Software Freedom Conservancy. Otros nombres y marcas corresponden a sus respectivos dueños. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2014-01-22-Sugar-Labs(R)-Educational-Nonprofit-Celebrates-Two-Google-Code-In-Grand-Prize-Winners.md b/src/constants/MarkdownFiles/posts/2014-01-22-Sugar-Labs(R)-Educational-Nonprofit-Celebrates-Two-Google-Code-In-Grand-Prize-Winners.md deleted file mode 100644 index 3015e0c8..00000000 --- a/src/constants/MarkdownFiles/posts/2014-01-22-Sugar-Labs(R)-Educational-Nonprofit-Celebrates-Two-Google-Code-In-Grand-Prize-Winners.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: "Sugar Labs(R) Educational Nonprofit Celebrates Two Google Code-In Grand Prize Winners" -excerpt: "Sugar Labs recognizes students Ignacio Rodríguez and Jorge Alberto Gómez López as winners of the Google Code-In Contest, who contributed significantly to improving the Sugar Learning Platform used by over three million children worldwide." -category: "PRESS RELEASE" -date: "2014-01-22" -slug: "sugar-labs-celebrates-google-code-in-winners" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "google-code-in,education,open-source,students,programming,development,uruguay,el-salvador" ---- -<!-- markdownlint-disable --> - -[PDF](/assets/post-assets/press/SugarLabsPR-en.20140122.pdf) - -CAMBRIDGE, Mass, January 22, 2014 — Sugar Labs®️, educational nonprofit provider of free and open-source learning software for children, is proud to recognize the **Google Code-In Contest**. - -**Watch Live:** [Google Code-In Overview](http://developers.google.com/open-source/gci/) -**Platform:** [Google Open Source Blog](http://google-opensource.blogspot.fr/2014/01/google-code-in-2013-drumroll-please.html) - -Grand-prize winners **Ignacio Rodríguez** and **Jorge Alberto Gómez López**, who participated brilliantly in Google's annual program for middle- and high-school students aged 13 to 17. Through GCI, Google invites open source organizations to mentor students who work on real programming and documentation tasks. Over 30 participants from more than a dozen countries — from Australia to Zimbabwe — mentored by Sugar Labs volunteers, helped to improve the Sugar Learning Platform used by over three million children worldwide. The winners will visit Google headquarters in Mountain View, California this spring. - -Ignacio, who is 14 and lives in Canelones, Uruguay, grew up with Sugar and began participating in Sugar development three years ago. "The competition was a place to socialize and make friends!", he says. "While I felt pressure, the community was there to help." - -Jorge, age 17, lives in Santa Tecla, El Salvador. "I never dreamed I would be working on an open source project; it was really fun to explore a whole new world, learn new tools, and most importantly, make new friends from different parts of the world — people that share the same objective and work as a community. I feel that I'm part of Sugar Labs, part of a big project, with friends and mentors." - -Rounding out the Sugar Labs list of finalists are **Sai Vineet** from Jamshedpur, India, **Emil Dudev** from Sofia, Bulgaria, and **Sam Parkinson** from Canberra, Australia (Sugar is widely deployed in Australian schools). Sam remarked, "Contributing to Sugar has, besides giving me experience in programming, shown me how fun programming collaboratively can be! And it's also been fun working towards a common, meaningful goal." - -> "GCI has made it evident that Sugar users are becoming the Sugar developers: Sugar not only gives them the license but also the means for developing their own tools for learning. In taking ownership, they become responsible," -> — *Walter Bender, founder of Sugar Labs* - -"We had a difficult time choosing our winners. Many participants completed multiple tasks. Ignacio was prolific, completing over 60 tasks, but all five of our finalists made fundamental improvements to the Sugar platform itself." - -**José Miguel García**, an education researcher from the Department of Educational Technology at Uruguay's CODICEN-ANEP in Montevideo, observed: - -> "For the second consecutive year a youth from Uruguay has won the competition. The nationwide Plan Ceibal, which delivers a laptop running Sugar to every child, achieves levels of equity in access to technology. These laptops, besides being used in formal education, enable young people to explore and develop activities, whether recreational, artistic, communication, programming, etc. These young people, guided and encouraged by their families, teachers, and the Sugar community are reaching significant levels in the development of 21st century skills." - -Sugar Labs wishes to thank Google and in particular **Bradley Kuhn**, executive director of the Software Freedom Conservancy. - -<img src="/assets/post-assets/press/SugarLabs_GCI_2013_Winner_Ignacio.jpg" alt="SugarLabs_GCI_2013_Winner_Ignacio.jpg" style="width:100%"> - -<img src="/assets/post-assets/press/SugarLabs_GCI_2013_Winner_Jorge.jpg" alt="SugarLabs_GCI_2013_Winner_Jorge.jpg" style="width:100%"> - ---- - -### About Sugar Labs®️ - -Sugar Labs®️ is a volunteer-driven member project of [Software Freedom Conservancy](https://sfconservancy.org/), a nonprofit corporation. Originally part of the One Laptop Per Child project, Sugar Labs coordinates volunteers around the world who are passionate about providing educational opportunities to children through the Sugar Learning Platform. - -Sugar Labs®️ is supported by donations and is seeking funding to accelerate development. For more information, please visit [www.sugarlabs.org/press](http://www.sugarlabs.org/press) or contact `pr@sugarlabs.org`. - -Sugar Labs®️ is a registered trademark of the Software Freedom Conservancy. Other names are trademarks of their respective owners. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2016-05-15-The-connection-between-Sugar---Students---Teachers.md b/src/constants/MarkdownFiles/posts/2016-05-15-The-connection-between-Sugar---Students---Teachers.md deleted file mode 100644 index 104b44e6..00000000 --- a/src/constants/MarkdownFiles/posts/2016-05-15-The-connection-between-Sugar---Students---Teachers.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: "The connection between Sugar - Students - Teachers" -excerpt: "This Sugar Story explores how the Sugar learning platform connects students and teachers, highlighting user contributions, educational impact, and how the platform's open design encourages innovation from its community." -category: "SUGAR STORIES" -date: "2016-05-15" -slug: "connection-between-sugar-students-teachers" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "education,open-source,teachers,students,uruguay,programming,contribution,learning" ---- -<!-- markdownlint-disable --> - -Story1: The connection between Sugar - Students - Teachers ---------------------------------------------------------- -* * * - -One of the first formal studies of Sugar took place in Uruguay in 2009–10. Uruguay was the first country to provide every child a free internet-connected laptop computer. They began distributing OLPC XO laptops running Sugar in 2007. Even though Uruguay is a relatively small country, with less than 500,000 children, it took several years before they could achieve full coverage. The last region to receive laptops was Montevideo. Montevideo was last because there was less need there than in the more rural regions, since many urban children already had access to computers. The delay in deploying in Montevideo presented an opportunity to study the impact of Sugar. Children were asked in 2009—before they has Sugar—what they did with their computers. It should come as no surprise that they used their computers to play games (See Figure). The same children were asked in 2010—after almost one year of using Sugar—what they did with their computers. Again they responded that they used their computers to play games. They were still children after all. But they also used their computers to write, chat, paint, make and watch videos, search for information, etc. In other words, with Sugar, they used the computer as a tool. Children play games. But given the opportunity and the correct affordances, they can leverage computation to do much much more. - -<img src="/assets/post-assets/data.png" alt="Image of data from a DSPE-ANEP survey" class="img-fluid" width="100%"/> - -**Figure: Data from a DSPE-ANEP survey of students in Montevideo before and after the deployment of Sugar** - -Sugar was designed so that new uses emerging from the community could easily be incorporated, thus Sugar could be augmented and amplified by its community and the end users. We encouraged our end users to make contributions to the software itself. This was in part out of necessity: we were a small team with limited resources and we had no direct access to local curricula, needs, or problems. But our ulterior motive was to engage our users in development as a vehicle for their own learning. - -One of the first examples of end-user contributions took place in Abuja, Nigeria, site of the first OLPC pilot project. While teachers and students took to Sugar quickly, they did confront some problems. The most notable of these was that the word-processor application, Write, did not have a spelling dictionary in Igbo, the dialect used in this particular classroom (and one of the more than three-hundred languages currently spoken in Nigeria). From a conventional software-development standpoint, solving this problem (300 times) would be prohibitively expensive. But for children in Abuja, equipped with Sugar, the solution was simple: confronted with the problem of lacking a dictionary, they made their own Igbo dictionary. The did not look for others to do the work for them. The took on the responsibility themselves. The Free/Libre Software ethic built into Sugar enabled local control and innovation. - -John Gilmore heard the about our aspiration to reach out to our end users—children—at the 2008 Libreplanet conference. He asked, "how many patches have you received from kids?" At the time, the answer to his question was zero. But over the past nine years, the situation has changed dramatically. By 2015, 50% of the patches in our new releases were coming from children (See Table); our release manager in 2015–16 (Sugar v0.108) was Sam Parkinson, a fifteen-year-old from Australia; our current release manager (Sugar v0.110) is Ignacio Rodríguez, an eighteen-year-old from Uruguay who began hanging out on our IRC channel at age ten and contributing code at age twelve. - -| Release number (date) | Total Commits | Youth Commits | Release note URL | -|-------------------------|---------------|---------------|------------------------------------------------------------------------| -| 0.102 (July 2014) | 424 | 108 | [View Notes](https://wiki.sugarlabs.org/go/0.102/Notes) | -| 0.104 (February 2015) | 249 | 127 | [View Notes](https://wiki.sugarlabs.org/go/0.104/Notes) | - -**Table 1: Sugar commits by youth contributors** - -When the now former president of Uruguay, José Mujica, learned that a twelve-year-old from a small town east of Montevideo had programmed six entirely new Sugar activities for the XO, he smiled and said triumphantly: "Now we have hackers." In his eyes, this one child's ability to contribute to the global Sugar development community was a leading indicator of change and development in his country. - -None of this happened on its own. End-user contributions are not simply an artifact of Sugar been Free/Libre Software. Open-source Software gives you access to the code and that Free/Libre Software gives you a license to make changes. But without some level of support, very few people will have the means to exercise the rights granted to them under the license. For this reason, we built scaffolding into Sugar to directly support making changes and extensions to Sugar applications and Sugar itself. - -Sugar has no black boxes: the learner sees what the software does and how it does it. Sugar is written in Python and comes with all of the tools necessary to modify Sugar applications and Sugar itself. We chose Python as our development language because of its transparency and clarity. It is a very approachable language for inexperienced programmers. With just one keystroke or mouse click, the Sugar "view source" feature allows the user to look at any program they are running. A second mouse click results in a copy of the application being saved to the Sugar Applications directory, where it is immediately available for modification. (We use a "copy on write" scheme in order to reduce the risk of breaking critical tools. If there is no penalty for breaking code, there is better risk-reward ratio for exploring and modifying code.) The premise is that taking something apart and reassembling it in different ways is a key to understanding it. - -Not every creative use of Sugar involves programming. Rosamel Norma Ramírez Méndez is a teacher from a school in Durazno, a farming region about two-hours drive north from Montevideo, Uruguay. Ramírez had her lessons for the week prepared when, first thing Monday morning, one of her students walked into her classroom holding a loofa. The child asked Ramírez, "teacher, what is this?" Rather than answering the question, Ramírez seized the opportunity to engage her class in an authentic learning experience. She discarded her lesson plans for the week. Instead, on Monday the children figured out what they had found; on Tuesday they determined that they could grow it in their community; on Wednesday they investigated whether or not they should grow it in their community; on Thursday they prepared a presentation to give to their farmer parents on Friday about why they should grow this potential cash crop. Not every teacher has the insight into learning demonstrated by Ramírez. And not every teacher has the courage to discard their lesson plans in order to capture a learning opportunity, But given an extraordinary teacher, she was able to mentor her students as they used Sugar as a tool for problem-solving. Ramírez encouraged her students to become active in their learning, which means that they engaged in doing, making, problem-solving, and reflection. - -_**"Teachers can learn (and contribute) too." – Walter Bender**_ - -Sometimes teachers have been directly involved in Sugar software development. Sugar has an abacus application to help children explore whole-number arithmetic and the concept base (the activity allows the user to switch between various base representations of whole numbers). It also lets children design their own abacus. Teachers in Caacupé, Paraguay, were searching for a way to help their students with the concept of fractions. After playing with the Sugar abacus activity, they conceived and created—with the help of the Sugar developer community—a new abacus that lets children add and subtract fractions (See Figure). Sugar didn't just enable the teachers to invent, it encouraged them to invent. - -<img src="/assets/post-assets/abacus.png" alt="Image of the Caacupé Abacus" width="100%" class="img-fluid" /> - -**Figure: The Caacupé Abacus. The white beads represent whole numbers. The black beads represent fractions.** - -Guzmán Trinidad, a high-school physics teacher from Montevideo, Uruguay and Tony Forster, a retired mechanical engineer from Melbourne, Australia collaborated on a collection of physics experiments that could be conducted with a pair of alligator clips and a small collection of Sugar applications. In the process of developing their experiments, they maintained regular communication with the developers, submitting bug reports, documentation, feature requests, and the occasional patch. Other examples of teacher and community-based contributions include Proyecto Butiá, a robotics and sensor platform build on top of Sugar (and GNOME) at Facultad de Ingeniería, Universidad de la República, Uruguay. Butiá inspired numerous other robotics platforms, e.g., RoDI (Robot Didáctico Inalámbrico) developed in Paraguay, as well as a wealth of projects aligned with the pedagogy of Constructionism. In the spirit of Sugar, these hardware projects were all designed to be "open": schematics and firmware were made available under Free/Libre licenses. - -In 2012, we were part of a team running a week-long Sugar workshop for more than 60 teachers who had traveled to Chachapoyas, the regional capital of the Amazonas region of Peru. During the day we spend time reviewing the various Sugar activities and discussing strategies for using Sugar in the classroom. In the evenings, we gave a series of optional workshops on specialized topics. One evening, mid-week, the topic was fixing bugs in Sugar. It was not expected that many teachers would attend—in part because we were competing with an annual festival and in part because their background in programming was minimal. But almost everyone showed up. In the workshop, we walked through the process of fixing a bug in the Sugar Mind Map activity and used git to push a patch upstream. Teachers, especially rural teachers, have a hunger for knowledge about the tools that they use. This is in part due to intellectual curiosity and in part due to necessity: no one is going to make a service call to Amazonas. As purveyors of educational technology we have both a pedagogical and moral obligation to provide the means by which our users can maintain (and modify) our products. Enabling those closest to the learners is in the interest of everyone invested in educational technology as it both ensures viability of the product and it is a valuable source of new ideas and initiatives. - -References ----------- - -**Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=vLiCumKjofc) -- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) - -- Ceibal Jam (2009). Convenio marco entre la Asociación Civil Ceibal Jam y la Universidad de la República. -- DSPE-ANEP (2011). Informe de evaluación del Plan Ceibal 2010. Administración Nacional de Educación Pública Dirección Sectorial de Planificación Educativa Área de Evaluación del Plan Ceibal. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2024-05-01-Sugar-Labs-receives-eleven-contributor-projects-for-GSoC-2024.md b/src/constants/MarkdownFiles/posts/2024-05-01-Sugar-Labs-receives-eleven-contributor-projects-for-GSoC-2024.md deleted file mode 100644 index 6b576932..00000000 --- a/src/constants/MarkdownFiles/posts/2024-05-01-Sugar-Labs-receives-eleven-contributor-projects-for-GSoC-2024.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Sugar Labs receives eleven contributor projects for GSoC 2024" -excerpt: "Sugar Labs announces acceptance of eleven programming projects for Google Summer of Code 2024, including work on Music Blocks, Sugarizer, AI tools, and more." -category: "PRESS RELEASE" -date: "2024-05-01" -slug: "sugar-labs-gsoc-2024-projects" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "gsoc,google-summer-of-code,programming,education,ai,music-blocks,sugarizer,open-source,mentorship" ---- - -<!-- markdownlint-disable --> - -**CAMBRIDGE, MA, USA -- May 1, 2024 -- Sugar Labs today announced it received eleven projects for participation in this year's Google Summer of Code (GSoC).** - -## Sugar Labs receives eleven projects for GSoC - -Sugar Labs will receive eleven projects for this year's Google Summer of Code (GSoC), a [12+ week programming project under the guidance of mentors](https://summerofcode.withgoogle.com/). This marks the fourteenth year that Sugar Labs has participated in GSoC since 2009. - -## Sugar Labs projects for GSoC 2024 - -As part of GSoC 2024, Sugar Labs will be working on Music Blocks, Sugarizer, Flatpak, Raspberry Pi, and Sugar Activities. Plus, this summer, we will be working on several AI projects to create new tools for teaching and learning. These include an addition to the Chat and Pippy Activities in Sugar, as well as several Music Blocks projects. - -Here is a detailed list of all eleven projects: - -| Project Title | Contributor | Assigned Mentor(s) | -|--------------------------------------------------------|--------------------------|--------------------------| -| Musical ideation through Generative AI | AbhijeetGSOC | Devin Ulibarri | -| Sugar on Raspberry Pi | Anurag Singh (Oval-Elephant) | Walter Bender | -| Music Blocks v4 Project Builder Integration | Karan Palan | Anindya Kundu | -| Make your own Lesson Plan for Music Blocks | khadar | Devin Ulibarri | -| Add an AI-assistant to the Pippy Activity | Kshitij_Shah | Walter Bender | -| Develop 8 new mathematical activities | Marsian | Chihurumnaya Ibiam | -| Musical creation and transcription assistance via generative AI | Mubashir Shariq | Devin Ulibarri | -| Add an AI chatbot to the Chat Activity | Qixiang | Walter Bender | -| Sugarizer 3D Volume Activity | Samarth Bagga | Lionel Laské | -| Maintain and Port 12 Sugar Activities to Flatpak | SudoSu-bham | tchx84 | -| Sugarizer VueJS App | UtkarshSiddhpura | Lionel Laské | - -## Where to find more information about Sugar Labs and GSoC - -**Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=vLiCumKjofc) -**Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) - -GSoC publishes full details about each organization and their projects. You can find information about Sugar Labs's projects this year at [Google Summer of Code - Sugar Labs](https://summerofcode.withgoogle.com/programs/2024/organizations/sugar-labs). - -Since 2019, Sugar Labs has published projects it is considering for Google Summer of Code in a [public repository published on GitHub](https://github.com/sugarlabs/GSoC). People interested in participating as contributors are encouraged to follow this repository. - -## About Sugar Labs - -Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology to youth around the world. Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating the need for source code to be published publicly for study, licensed under a Free/Libre license for explicit permission to share and remix, and openly worked upon within a community where students are invited to make contributions, under guidance of experienced mentors. - -Donations to support the work of Sugar Labs can be made at [https://wiki.sugarlabs.org/go/Sugar_Labs/Donate](https://wiki.sugarlabs.org/go/Sugar_Labs/Donate). \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2024-05-03-Sugar-Labs-Past-Present-Future.md b/src/constants/MarkdownFiles/posts/2024-05-03-Sugar-Labs-Past-Present-Future.md deleted file mode 100644 index 26d676de..00000000 --- a/src/constants/MarkdownFiles/posts/2024-05-03-Sugar-Labs-Past-Present-Future.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: "Sugar Labs: Past, present, and future" -excerpt: "Join Sugar Labs for the kickoff of our new event series exploring our history, current projects, and vision for the future of educational technology for youth around the world." -category: "EVENTS" -date: "2024-05-03" -slug: "sugar-labs-past-present-future" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "events, education, open source, community, sugar labs" ---- - -<!-- markdownlint-disable --> - -**Sugar Labs kicks off a series of events with a live online event titled _"Sugar Labs: Past, present, and future"_ on Friday, May 3, 2024 at 15:00 ET (19:00 UTC).** We invite you to join us as we reflect on our story, explore our vision, and share how you can contribute. - -**Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=jZs-QJNfglc) -- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) - ---- - -## Event Information - -- **Event:** Sugar Labs: Past, present, and future -- **Date:** May 3, 2024 -- **Time:** 15:00 ET (19:00 UTC) -- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=jZs-QJNfglc) -- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) - ---- - -## About Sugar Labs - -Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology for youth around the world. - -Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating: - -- Public access to source code for study -- Free/Libre licensing for sharing and remixing -- Open collaboration within a welcoming community -- Contributions from students under experienced guidance - -Support our work: [Donate here](https://www.sugarlabs.org/donate/) - ---- diff --git a/src/constants/MarkdownFiles/posts/2024-05-08-Sugar-Labs-announces-nonprofit-status-new-executive-director.md b/src/constants/MarkdownFiles/posts/2024-05-08-Sugar-Labs-announces-nonprofit-status-new-executive-director.md deleted file mode 100644 index 24cf6629..00000000 --- a/src/constants/MarkdownFiles/posts/2024-05-08-Sugar-Labs-announces-nonprofit-status-new-executive-director.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "Sugar Labs announces nonprofit status, new executive director" -excerpt: "Sugar Labs officially announces its 501(c)(3) nonprofit status and the appointment of long-time contributor Devin Ulibarri as its first full-time executive director." -category: "PRESS RELEASE" -date: "2024-05-08" -slug: "sugar-labs-announces-nonprofit-status-new-executive-director" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "nonprofit,501c3,leadership,executive-director,free-software,education,announcement,organization" ---- -<!-- markdownlint-disable --> - -**CAMBRIDGE, MA, USA -- May 8, 2024 -- Sugar Labs today announced its 501(c)(3) nonprofit status as well as its pick for executive director, long-time contributor Devin Ulibarri.** - -## Sugar Labs is a 501(c)(3) nonprofit - -In 2019, the Sugar Labs oversight board voted to incorporate as its own entity and apply for nonprofit status. After that vote, the members of the board began efforts to leave the Software Freedom Conservancy, incorporate as Sugar Labs Inc., and applied for 501(c)(3) nonprofit status. In the spring of 2021, Sugar Labs Inc. was granted nonprofit status from the IRS. - -**More Info:** -- [Meeting Minutes – May 3, 2019](https://wiki.sugarlabs.org/go/Oversight_Board/Meeting_Minutes-2019-05-03) -- [Software Freedom Conservancy](https://sfconservancy.org/) - -## Devin Ulibarri hired as executive director - -In January 2024, the board agreed to hire long-time Sugar Labs contributor Devin Ulibarri as their first full-time executive director. Prior to stepping into this role, he worked as the outreach & communications coordinator for the [Free Software Foundation](https://fsf.org). - -**More Info:** -- [Free Software Foundation](https://fsf.org) -- [Music Blocks](https://www.sugarlabs.org/music-blocks) - -Ulibarri has been a part of the Sugar Labs community for ten years, primarily working together with Walter Bender on [Music Blocks](https://www.sugarlabs.org/music-blocks) development. Devin has been an advocate of the work and philosophy of Sugar Labs, giving talks and leading workshops internationally. As a former board member, he also played a major role in helping the organization achieve its current nonprofit status. - -Of the hiring, Sugar Labs board member and founder Walter Bender said, "Devin is a dedicated colleague, with deep roots in both Free/Libre Software and the pedagogy of Constructionism. We're thrilled to have Devin in this new role." Ulibarri responded: "I'm excited to serve within this capacity, to help Sugar Labs grow to bring all of its good work to more teachers, parents, and students across the US and, ultimately, around the globe." - -## Current leadership - -The officers of Sugar Labs Inc. are currently: Devin Ulibarri, executive director; Claudia Urrea, treasurer; and Walter Bender, secretary. The current board is Samson Goddy, Lionel Laské, Claudia Urrea, Walter Bender, and Alex Perez. - -**More Info:** -- [Sugar Labs Oversight Board](https://wiki.sugarlabs.org/go/Oversight_Board) \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2024-05-10-Musical-Squares-From-Turtle-Blocks-to-Music-Blocks-and-beyond.md b/src/constants/MarkdownFiles/posts/2024-05-10-Musical-Squares-From-Turtle-Blocks-to-Music-Blocks-and-beyond.md deleted file mode 100644 index dcc0b4fb..00000000 --- a/src/constants/MarkdownFiles/posts/2024-05-10-Musical-Squares-From-Turtle-Blocks-to-Music-Blocks-and-beyond.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: "Musical Squares: From Turtle Blocks to Music Blocks and Beyond" -excerpt: "Learn about Music Blocks, a visual programming language that combines music and coding, with a hands-on demonstration during this educational Sugar Labs livestream event." -category: "EVENTS" -date: "2024-05-10" -slug: "musical-squares-turtle-blocks-music-blocks-beyond" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "music,programming,education,turtle-blocks,visual-programming,livestream,coding,music-education" ---- -<!-- markdownlint-disable --> - -**Sugar Labs is hosting an event _"Learn about Music Blocks, visual programming language with a hands-on activity"_ on Friday, May 10, 2024 at 15:00 ET (19:00 UTC).** Join us for a fun and educational introduction to Music Blocks. - -## Event Information - -- **Title:** Musical Squares: From Turtle Blocks to Music Blocks and Beyond -- **Date:** May 10, 2024 -- **Time:** 15:00 ET (19:00 UTC) -- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=jZs-QJNfglc) -- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) - ---- - -## About Sugar Labs - -Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2024-05-17-Learn-to-make-games-with-Gameeky.md b/src/constants/MarkdownFiles/posts/2024-05-17-Learn-to-make-games-with-Gameeky.md deleted file mode 100644 index 3dd8d842..00000000 --- a/src/constants/MarkdownFiles/posts/2024-05-17-Learn-to-make-games-with-Gameeky.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "Learn to make games with Gameeky!" -excerpt: "Join developer Martin Abente Lahaye for a hands-on tutorial on creating games with Gameeky, a platform that empowers young learners and educators to build cooperative games and learning experiences." -category: "EVENTS" -date: "2024-05-17" -slug: "learn-make-games-with-gameeky" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "game-development,education,tutorial,livestream,programming,youth,coding,gameeky" ---- -<!-- markdownlint-disable --> - -**"Learn to make games with Gameeky" will be presented live by developer Martin Abente Lahaye. Get a hands-on tutorial for how to make games with Gameeky. Play, create, and learn: Gameeky lets young learners and educators create and explore cooperative games and learning experiences. Watch live on Friday, May 17, 2024 at 15:00 ET (19:00 UTC).** - -## Event Information - -- **Title:** Learn to make games with Gameeky -- **Date:** May 17, 2024 -- **Time:** 15:00 ET (19:00 UTC) -- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=vLiCumKjofc) -- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) - ---- - -## About Sugar Labs - -Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology for youth around the world. - -Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating: - -- Public access to source code for study -- Free/Libre licensing for sharing and remixing -- Open collaboration within a welcoming community -- Contributions from students under experienced guidance - -Support our work: [Donate here](https://www.sugarlabs.org/donate/) diff --git a/src/constants/MarkdownFiles/posts/2024-05-24-An-OLPC-update-with-Lylian-Peraza.md b/src/constants/MarkdownFiles/posts/2024-05-24-An-OLPC-update-with-Lylian-Peraza.md deleted file mode 100644 index 766735e1..00000000 --- a/src/constants/MarkdownFiles/posts/2024-05-24-An-OLPC-update-with-Lylian-Peraza.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "An OLPC update with Lylian Peraza" -excerpt: "Sugar Labs hosts Lylian Peraza, Vice President of Project Development at OLPC, for a livestream discussion about the latest developments and projects from One Laptop Per Child." -category: "EVENTS" -date: "2024-05-24" -slug: "olpc-update-lylian-peraza" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "olpc,education,technology,livestream,interview,nonprofit,laptops,global-education" ---- -<!-- markdownlint-disable --> - -**Join Sugar Labs for a discussion with Lylian Peraza, Vice President of Project Development at OLPC. Watch live on Friday, May 24, 2024 at 15:00 ET (19:00 UTC).** - -## Event Information - -- **Title:** An OLPC update with Lylian Peraza -- **Date:** May 24, 2024 -- **Time:** 15:00 ET (19:00 UTC) -- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=SuOta9MLLnw) -- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) - ---- - -## About Sugar Labs - -Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology for youth around the world. - -Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating: - -- Public access to source code for study -- Free/Libre licensing for sharing and remixing -- Open collaboration within a welcoming community -- Contributions from students under experienced guidance - -Support our work: [Donate here](https://www.sugarlabs.org/donate/) diff --git a/src/constants/MarkdownFiles/posts/2024-05-31-Learn-How-to-git-involved-with-Sugar-Labs-this-summer.md b/src/constants/MarkdownFiles/posts/2024-05-31-Learn-How-to-git-involved-with-Sugar-Labs-this-summer.md deleted file mode 100644 index 95073282..00000000 --- a/src/constants/MarkdownFiles/posts/2024-05-31-Learn-How-to-git-involved-with-Sugar-Labs-this-summer.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: "Learn: How to git involved with Sugar Labs this summer" -excerpt: "Join Sugar Labs Executive Director Devin Ulibarri for a live session on how to get involved with Sugar Labs this summer while learning valuable programming skills and contributing to educational software." -category: "EVENTS" -date: "2024-05-31" -slug: "how-to-git-involved-sugar-labs-summer" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "volunteer,git,programming,education,summer-programs,open-source,mentorship,coding" ---- -<!-- markdownlint-disable --> - -**Sugar Labs executive director Devin Ulibarri gives a short intro on ways to "git" involved with Sugar Labs this summer, while learning valuable skills. Watch live on Friday, May 31, 2024 at 15:00 ET (19:00 UTC).** - -## Event information - -- **Title:** Learn: How to git involved with Sugar Labs this summer -- **Date:** May 31, 2024 -- **Time:** 15:00 ET (19:00 UTC) -- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=W5ZLFBZkE34) -- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) - -## About Sugar Labs - -Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology to youth around the world. Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating the need for source code to be published publicly for study, licensed under a free/libre license for explicit permission to share and remix, and openly worked upon within a community where students are invited to make contributions, under guidance of experienced mentors. - -Support our work: [Donate here](https://www.sugarlabs.org/donate/) diff --git a/src/constants/MarkdownFiles/posts/2024-06-07-GSoC+DMP-contributors-initial-check-in-1-of-2-Music-Blocks-projects.md b/src/constants/MarkdownFiles/posts/2024-06-07-GSoC+DMP-contributors-initial-check-in-1-of-2-Music-Blocks-projects.md deleted file mode 100644 index 1bb0f431..00000000 --- a/src/constants/MarkdownFiles/posts/2024-06-07-GSoC+DMP-contributors-initial-check-in-1-of-2-Music-Blocks-projects.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: "GSoC+DMP contributors initial check-in 1 of 2: Music Blocks projects" -excerpt: "Join Sugar Labs for an introduction to Google Summer of Code (GSoC) and DMP projects this summer, presented by GSoC and DMP interns andfacilitated by their mentors, Devin Ulibarri, Walter Bender, and Anindya Kundu. Watch live on Friday, June 7, 2024 at 13:00 ET (17:00UTC)." -category: "EVENTS" -date: "2024-06-07" -slug: "gsoc-dmp-contributors" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "volunteer,git,programming,education,summer-programs,open-source,mentorship,coding" ---- -<!-- markdownlint-disable --> - -**Join Sugar Labs for an introduction to Google Summer of Code (GSoC) and DMP projects this summer, presented by GSoC and DMP interns andfacilitated by their mentors, Devin Ulibarri, Walter Bender, and Anindya Kundu. Watch live on Friday, June 7, 2024 at 13:00 ET (17:00UTC).** - -## Event information - -- **Title:** GSoC+DMP contributors initial check-in 1 of 2: Music Blocks projects -- **Date:** June 7, 2024 -- **Time:** 13:00 ET (17:00 UTC) -- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=PeIS3gXPFj0) -- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) ---- - -## About Sugar Labs - -Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology for youth around the world. - -Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating the need for source code to be published publicly for study, licensed under a free/libre license for explicit permission to share and remix, and openly worked upon within a community where students are invited to make contributions, under guidance of experienced mentors. - -Support our work: [Donate here](https://www.sugarlabs.org/donate/) diff --git a/src/constants/MarkdownFiles/posts/2024-09-13-Writing-new-Activities-and-sharing-sugar-with-youth.md b/src/constants/MarkdownFiles/posts/2024-09-13-Writing-new-Activities-and-sharing-sugar-with-youth.md deleted file mode 100644 index a3cefae8..00000000 --- a/src/constants/MarkdownFiles/posts/2024-09-13-Writing-new-Activities-and-sharing-sugar-with-youth.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "Writing new Activities and sharing sugar with Youth" -excerpt: "James Simmons shares his journey of contributing to Sugar Labs since 2007, including developing Activities for reading e-texts and creating resources to help others build their own Sugar Activities." -category: "SUGAR STORIES" -date: "2024-9-13" -slug: "writing-new-activities-sharing-sugar-with-youth" -author: "James Simmons" -description: "Sugar Labs Contributor" -tags: "community,activities,development,python,education,programming,ebooks,manuals" ---- -<!-- markdownlint-disable --> - -_Editorial note: This article was given to us by Sugar Labs community member James Simmons as part of a series called Sugar Stories, which aims to highlight stories from members our community. If you would like to share your Sugar Story with us as an article for possible publication, please send a draft to_ [_info@sugarlabs.org_](mailto:info@sugarlabs.org)_. Please be aware that there is an editorial process that will require some additional effort and collaboration, even after submission._ - -I started working with OLPC with the Give One Get One program back in 2007. Honestly speaking, at the time, I was more interested in getting an XO laptop for myself than in working for the project. I thought I could use the laptop to read plain textbooks from [Project Gutenberg](https://www.gutenberg.org/). Kindles were very expensive back then, and this looked like a good alternative. And it was. But, at the time, the Read Activity only worked with PDFs. In an effort to expand this functionality, I taught myself to program in Python, studied the code for the [Read Activity](https://activities.sugarlabs.org/en-US/sugar/addon/4028), and created the [Read Etexts Activity](https://activities.sugarlabs.org/en-US/sugar/addon/4035), which supported reading plain text files. Next, I decided that I wanted to have an Activity for reading comic books in CBZ format and created two of them: [View Slides](https://activities.sugarlabs.org/en-US/sugar/addon/4039) and [Read SD Comics](https://activities.sugarlabs.org/en-US/sugar/addon/4340). - - - -Photo of James Simmons with a copy of "Make your own Sugar Activities". Simmons has been contributing to Sugar since 2007. - -At the time, the best, and maybe only, way to learn how to create Activities was to study the code of existing ones. I'm a systems analyst, so that wasn't too difficult for me, since I already had some of the important skills needed to do this. But this situation wasn't great for teachers and their students who may want to create Activities but didn't yet have the skills needed. In 2009 or so, I convinced myself to write a proper manual, which we called [_Make Your Own Sugar Activities!_](https://archive.org/details/MakeYourOwnSugarActivities) I did this using the Floss Manuals website. I was fortunate enough to have a very nice cover illustration done for me by [Oceana Rain Fields](https://archive.flossmanuals.net/make-your-own-sugar-activities/about-the-authors.html), a student participating in the Rural Design Collective's summer mentorship program. The printed book was given out as a door prize at one of the first OLPC conferences. The book was later translated into Spanish by a team of Sugar Labs volunteers as [_Como Hacer Una Actividad Sugar_](https://archive.org/details/ComoHacerUnaActividadSugar). - -My personal involvement in Sugar Labs did not require any direct work with children, but, recently, I had the opportunity to introduce a young boy to Sugar. I had an old computer that I was going to give to a family friend, who was studying computer programming in college. His nine-year-old brother found out about it and wanted it for himself, so I installed the latest [Sugar Learning Platform](https://wiki.sugarlabs.org/go/What_is_Sugar#About_the_Sugar_Learning_Platform) and updated my old Activities to run on Python 3. He is pleased to have [the same operating system (OS) used by astronauts on the International Space Station (ISS)](https://www.fsf.org/blogs/community/gnu-linux-chosen-as-operating-system-of-the-international-space-station) and enjoys playing [Tux Kart](https://supertuxkart.net/Main_Page). I look forward to introducing him to even more that Sugar has to offer in the coming months. - -It's nice to have the [Sugar environment](https://wiki.sugarlabs.org/go/What_is_Sugar) as an option for kids, as well as ways for the community to participate in the creation of new Activities. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2024-09-20-sweet-spot.md b/src/constants/MarkdownFiles/posts/2024-09-20-sweet-spot.md deleted file mode 100644 index e46004c9..00000000 --- a/src/constants/MarkdownFiles/posts/2024-09-20-sweet-spot.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: "The Sweet Spot – Issue 001" -excerpt: "The inaugural issue of Sugar Labs' newsletter covering recent updates, GSoC projects, ways to get involved, and community news." -category: "COMMUNITY NEWS" -date: "2024-09-20" -slug: "the-sweet-spot-issue-001" -author: "Sugar Labs" -description: "Community Newsletter" -tags: "newsletter,community,gsoc,dmp,updates,volunteer,outreach,education" ---- -<!-- markdownlint-disable --> -# Recent news for September 20, 2024 - -Welcome to the very first issue of the **"Sweet Spot"**, a newsletter for Sugar Labs-related news in development, student and teacher work, events, how to get involved, and other news and information. This newsletter will be published semi-regularly for now, but the plan is to publish it on a bi-monthly, perhaps even monthly, basis in the future. Our aim with this newsletter is to help keep the growing body of Sugar Labs contributors on the same page, all while documenting our growth for our own and others' reference. - -This first issue is meant to set a precedent of communication and documentation, as well as to help inform the community of our current status, recent progress, and future plans. Its predecessor is the ["Sugar Digest"](https://lists.sugarlabs.org/archive/community-news/), which still serves as an important catalog of our activities. Like Sugar Digest, this newsletter is intended to keep community members in the loop about everything going on within Sugar Labs. It will highlight any recent publications from us. It will occasionally include links to third-party news and updates that our community finds relevant. - -This first issue has links and "news" from a few months back. Future installments will focus on a more acute timeframe than this inaugural issue, which aims to cover our news since the beginning of this year. - -We hope that you enjoy this first issue. And, if you have something you'd like to share, please feel free to email [info@sugarlabs.org](mailto:info@sugarlabs.org). And for those who would like to volunteer in other ways, this edition has a list of volunteer help that we need with Sugar Labs overall. - -## Updates - -### GSoC and DMP students complete their projects - -This year's GSoC and DMP students have completed their work for Sugar Labs. Students were asked to document their progress through blogs and participate in online events showcasing their work at regular intervals throughout the summer. You can find links to their blog posts on our bi-weekly summary posts on Medium and watch videos of their presentations on YouTube. - -#### Bi-weekly GSoC and DMP summaries: - -- [Please help us welcome this summer's Google Summer of Code team for Music Blocks development](https://medium.com/@sugarlabs/please-help-us-welcome-this-summers-google-summer-of-code-team-for-music-blocks-development-6c2524244605) -- [GSoC 2024 Students Weekly Report 1](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-report-1-1af7c29ede0a) -- [GSoC 2024 Students Weekly Reports 2 and 3](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-reports-2-and-3-af03ec159b49) -- [GSoC 2024 Students Weekly Reports 4 and 5](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-reports-4-and-5-987825617340) -- [GSoC 2024 Students Weekly Reports 6 and 7](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-reports-6-and-7-9eacb78e4093) -- [GSoC 2024 Students Weekly Reports 8 and 9](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-reports-8-and-9-fb7d86cfabb1) -- [GSoC 2024 Students Weekly Reports 10 and 11](https://medium.com/@sugarlabs/gsoc-2024-students-weekly-reports-10-and-11-670e9f3bb6b0) - -#### YouTube updates: - -- [GSoC+DMP contributors initial check-in 1 of 2: Music Blocks projects](https://www.youtube.com/watch?v=PeIS3gXPFj0) -- [GSoC+DMP contributors initial check-in 2 of 2: Sugarizer, Raspberry Pi, Math games, and more](https://www.youtube.com/watch?v=k7eY-tkl2zw) -- [Summer Interlude by GSoC+DMP Interns, Presentation 1 of 2: Music Blocks and Sugarizer](https://www.youtube.com/watch?v=qWLWCdp4_D4) -- [Summer Interlude by GSoC+DMP Interns, Presentation 2 of 2: RPi, AI Assists, Math games, and more](https://www.youtube.com/watch?v=TARoJDitQVg) -- [Summer Finale by GSoC Interns, Presentation 1 of 3: Music Blocks and Sugarizer](https://www.youtube.com/watch?v=dVYpK5fTHsQ) -- [Summer Finale by GSoC Interns, Presentation 2 of 3: RPi, AI Assists, Math games, and more](https://www.youtube.com/watch?v=d0nTfKmOWl8) -- [Summer Finale by DMP Interns, Presentation 3 of 3: Music Blocks, Raspberry Pi and Math games](https://www.youtube.com/watch?v=0yMqz3GW3rY) - -### Ways to get involved - -Sugar Labs is seeking volunteer assistance in the following ways. Sustained, committed help in any of the following areas will help us grow as an organization. If you are passionate or curious to learn more about any of these roles, and are able to commit the time necessary, then we encourage you to apply. Send a notification of your interest to [info@sugarlabs.org](mailto:info@sugarlabs.org), including some information about yourself, what interests you about the volunteer role, and what experience/qualities make you a good candidate for the position. - -- [Help Wanted](https://wiki.sugarlabs.org/go/Help_Wanted) -- [Introduction Video](https://www.youtube.com/watch?v=W5ZLFBZkE34) - -## Social Links - -- **Wiki** – [https://wiki.sugarlabs.org](https://wiki.sugarlabs.org) -- **Mastodon** – [https://mastodon.social/@sugar_labs](https://mastodon.social/@sugar_labs) diff --git a/src/constants/MarkdownFiles/posts/2024-11-08-fall-board-elections-how-to-participate.md b/src/constants/MarkdownFiles/posts/2024-11-08-fall-board-elections-how-to-participate.md deleted file mode 100644 index 099dd2f9..00000000 --- a/src/constants/MarkdownFiles/posts/2024-11-08-fall-board-elections-how-to-participate.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "Board election results announcement: Three new members for the 2025-26 cycle" -excerpt: "The election results for the Sugar Labs Board of Directors have been announced. Devin Ulibarri, Sumit Srivastava, and Sebastian Silva will serve on the board for the 2025-26 cycle." -category: "COMMUNITY NEWS" -date: "2024-11-08" -slug: "board-election-results-2025-26" -author: "Devin Ulibarri" -description: "Executive Director" -tags: "markdown,parser,test,education,post,aigenerated" ---- -<!-- markdownlint-disable --> - -# The results for the 2025-26 Sugar Labs board cycle have been determined. - -The votes have been counted, and the [results](https://bettervoting.com/dp3xc7/) for the [2025-26 Sugar Labs board cycle](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) have been determined. - -The winners are **Devin Ulibarri, Sumit Srivastava, and Sebastian Silva**. They have all been notified and have agreed to serve on the Board of Directors for the 2025-26 cycle. For this election, we used [bettervoting.com](https://bettervoting.com) after doing research on various voting systems. Please read our [original election announcement](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) for more information on how we decided upon this voting system. - -The new members of the board will be filling the seats of two outgoing board members, **Lionel Laské and Alex Perez**, and one vacant seat. - -The next election for three seats to the **2026-27 cycle** is planned for **August of next year**. All Sugar Labs members may vote, and members can: -- Run for election to the Board of Directors -- Vote in the elections for the Board of Directors -- Suggest referenda - -As indicated in the [Sugar Labs Inc. bylaws](https://wiki.sugarlabs.org/go/Sugar_Labs/Governance), anyone with "significant and sustained" contributions to Sugar Labs is eligible for membership. If you believe you qualify for membership based on this criteria and are interested in [becoming an official member of Sugar Labs](https://wiki.sugarlabs.org/go/Sugar_Labs/Members), you are encouraged to send an email to <members@sugarlabs.org>. - -If you were a member in the past but [did not vote in this election](https://www.sugarlabs.org/community/2024/11/22/elections-extension/), you will need to reapply for membership in order for your membership status to be reinstated. *(If you voted in this election, no further action is required.)* Registering for membership early will help ensure that you will be ready for the next election. - -If you are interested in volunteering to assist with the next election in 2025, please contact <volunteering@sugarlabs.org> with your interest. - -On behalf of the [Sugar Labs Board of Directors](https://www.sugarlabs.org/leadership/), we offer a big **Thank you!** to all who participated in this year's election. diff --git a/src/constants/MarkdownFiles/posts/2024-11-22-elections-extension.md b/src/constants/MarkdownFiles/posts/2024-11-22-elections-extension.md deleted file mode 100644 index 02239d70..00000000 --- a/src/constants/MarkdownFiles/posts/2024-11-22-elections-extension.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: "Deadline extended to November 24 to apply for a ballot and apply for candidacy" -excerpt: "Sugar Labs has extended the deadline for board of directors election participation to November 24, including both ballot applications and candidacy submissions for the upcoming election cycle." -category: "COMMUNITY NEWS" -date: "2024-11-22" -slug: "elections-extension-november-2024" -author: "Devin Ulibarri" -description: "Executive Director" -tags: "elections,governance,board,voting,deadline,community,membership" ---- -<!-- markdownlint-disable --> - -**Sugar Labs is running an election this fall for three seats to its board of directors. The deadline to apply for a ballot, as well as submit candidacy for the board, is November 24. Sugar Labs community members are encouraged to participate. By submitting an application for a ballot you will also be considered for membership. Current members who do not apply for a ballot will have their membership rescinded.** - -The deadline to apply for a ballot and apply for candidacy is fast approaching. Extended to Sunday, the deadline to [apply for a ballot](https://forms.gle/48F6h5wdV6BpSro66) is now November 24, 2024, End of Day (EoD), Anywhere on Earth (AoE). It is also the deadline to [submit for candidacy](https://wiki.sugarlabs.org/go/Oversight_Board/2025-2026-candidates#Candidates) for the [board of directors](https://www.sugarlabs.org/leadership/). - -### Eligibility to vote - -Since we made [our initial announcement](https://www.sugarlabs.org/community/2024/11/08/fall-board-elections-how-to-participate/), one of the most frequently asked questions has been *what determines eligibility for participating in the election?* Participation in the election is open to any member of Sugar Labs, and the eligibility requirements for membership are published on [Sugar Labs Members page](https://wiki.sugarlabs.org/go/Sugar_Labs/Members). - -The main gist, however, is that you've made a contribution to Sugar Labs. According to our definition, such a contribution "may be code, documentation, translations, maintenance of project-wide resources, *running a Sugar deployment*, or other non-trivial activities which benefit Sugar Labs." - -If you've made such a contribution to Sugar Labs, you are eligible as a member, and, as a member, you may vote. ***Also, if you're not a member or unsure about your status, we still encourage you to submit an application for a ballot.*** We will automatically begin to determine your membership eligibility based on your publicly visible contributions, so no other steps are necessary on your part. - -### Current members must vote in this election in order to maintain their membership status - -Our most recent membership list may be found [here](https://wiki.sugarlabs.org/go/Sugar_Labs/Members/List). If you are currently a member but you do not apply for a ballot to vote in this election, then we will consider your membership to be rescinded and your membership will be made inactive. Because [our bylaws require a majority vote from members to pass certain amendments](https://wiki.sugarlabs.org/go/Sugar_Labs/Governance#ARTICLE_XI), we need to ensure that our current membership list is up-to-date with active members. - -If you've made a contribution to Sugar Labs in the past, ***we strongly encourage you to vote in this election to maintain your membership status.*** We thank you for your contribution, and we encourage you to continue to participate in Sugar Labs, which is now investing in its growth and expansion like never before. - -If it's been a while since you've made a contribution, we encourage you to join us on our main [Matrix channel](https://matrix.to/#/#sugar:matrix.org) and follow us on [GitHub](https://github.com/sugarlabs/). These two channels are currently the most active for coordinating contributions. - -### Receive your ballot - -We encourage you to vote. The application to receive your ballot, due by the End of Day (EoD), Anywhere on Earth (AoE), November 24, 2024, is [here](https://forms.gle/48F6h5wdV6BpSro66). - -### Running for a board position - -For those of you who would like to run for a board position, you will need to add your name and statement to the list on the [candidate page](https://wiki.sugarlabs.org/go/Oversight_Board/2025-2026-candidates). If you need any technical assistance with the wiki, please contact <elections@sugarlabs.org>. - -Candidates should read and understand the terms of the [Sugar Labs Inc.'s Bylaws](https://wiki.sugarlabs.org/go/Sugar_Labs/Governance), as well as any domestic and international laws governing participation in a US-based 501(c)(3) nonprofit board. - -### Election timeline - -The updated timeline of the election is planned as follows, with a deadline to receive ballot applications for the End of Day (EoD), Anywhere on Earth (AoE), November 24, 2024, and a deadline to vote for the end of day on December 13, 2024. - -| Stage | Date | Event | -|------------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Stage I | November 8 | Announcement of election date and first call for candidates. | -| Stage II | ~~Nov 22~~ Nov 24 | Deadline to receive [candidacy applications](https://wiki.sugarlabs.org/go/Oversight_Board/2025-2026-candidates#Candidates) and [ballot applications](https://forms.gle/48F6h5wdV6BpSro66). | -| Stage III | November 27 | Ballots to be sent by email. If you do not receive your ballot by the following day, please email <elections@sugarlabs.org>. | -| Stage IV | December 13 | Deadline to vote. | -| Stage V | December 19 | Election results announced. | - -### Election method - -After doing research on various [election software recommended by the FLOSS community](https://github.com/sugarlabs/elections-research), we have decided to use [bettervoting.com](http://bettervoting.com). The software is licensed under the AGPLv3, and the system supports automatic runoff vote tallying. Our internal research on the system can be found in [this document](https://docs.google.com/document/d/1kuXXL-tVgB1Ptu50cTonWtRnAuKmWn1jyKd1qPgqFJY/edit?tab=t.0). - -Again, we encourage you to take the first step and apply for a ballot via our [application form](https://forms.gle/48F6h5wdV6BpSro66), and we look forward to your involvement. diff --git a/src/constants/MarkdownFiles/posts/2024-12-03-help-SL-continue-to-transform-education.md b/src/constants/MarkdownFiles/posts/2024-12-03-help-SL-continue-to-transform-education.md deleted file mode 100644 index bc9bb57d..00000000 --- a/src/constants/MarkdownFiles/posts/2024-12-03-help-SL-continue-to-transform-education.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: "Today, help Sugar Labs continue to transform education" -excerpt: "Sugar Labs Executive Director Devin Ulibarri shares the organization's vision and growth plans, highlighting achievements and requesting community support through donations to expand their educational initiatives." -category: "COMMUNITY NEWS" -date: "2024-12-03" -slug: "help-sugar-labs-continue-transform-education" -author: "Devin Ulibarri" -description: "Executive Director" -tags: "fundraising,donations,education,nonprofit,growth,community,technology,open-source" ---- -<!-- markdownlint-disable --> - -**Shared recently on our [mailing list](https://buttondown.com/sugarlabs), Sugar Labs executive director Devin Ulibarri shares his dreams for the organization and how you can help us at this critical moment in our growth.** - -Hello, - -Sugar Labs is at a critical inflection point. We need your support to leverage some important opportunities to grow. - -Consider [donating to Sugar Labs](https://www.paypal.com/donate?campaign_id=NEAV3YL4H6B5S) as we move into our next phase. - - -*The Sugar Labs community is a global network of students, teachers, and developers.* - -I stepped into the executive director position in January of this year. I did so because I believe in Sugar Labs's mission to create educational software and experiences for children. - -I also believe in its approach—giving kids the *license* to learn, through free/libre/open (FLO) source software, as well as the *means* to learn through its community of learners and teachers working together to create a fun, safe, and welcoming *learn-by-doing* environment. - -Based on my own experience as an educator for more than twenty years, I truly believe this organization has the potential to be a positive, disruptive force in education. - -Sugar Labs has a history that dates back almost two decades, with methods (e.g. LOGO, constructionism, project-based learning) that date back more than half a century. - -Yet, as an independent nonprofit, the organization itself is basically a startup. Having left our former umbrella organization Software Freedom Conservancy in 2020, we must now take on the challenges inherent to growing our own organization. - -This independence brings challenges, such as finding stability and resilience. It also means, however, that we have an opportunity to build the kind of organization that truly serves our mission. I want to invite you to join us at this pivotal moment. - -At the time of its founding more than sixteen years ago, Sugar Labs ran exclusively on one platform, created for One Laptop Per Child (OLPC), which was put into the hands of over three million children in over thirty-five countries. - -Since that time, Sugar Labs has strategically expanded its scope and renewed its relevance. One way that we've accomplished this is by making the platform available on more devices through Sugar on a Stick (SoaS), maintained as a Fedora "Spin," and Raspberry Pi (RPi)—the latter for which [we made notable improvements over the summer](https://youtu.be/EW0b5OkxXVs). - -We also created web-based applications such as Turtle Blocks, Music Blocks, and Sugarizer, which can run on any computer, regardless of operating system. - -Music Blocks, in particular, has received recognition as an innovative tool for exploring music and programming. - -Perhaps most notably, the Japanese government provided two years of funding to create a version of Music Blocks specifically to help Japan's elementary school students learn programming. - -Additionally, Music Blocks was also part of a large-scale deployment of seven-hundred thousand tablets by the Peruvian Ministry of Education. - -This year I've spent time ensuring that our finances are stronger and more transparent than ever before. I did this so that charitable donations can be made with confidence, ultimately helping every financial contribution we receive go further. - -I won't go into all the details here, but one thing I did is to update and publish our 990s to our website. - -All of our tax filings are now up to date and published on [sugarlabs.org/donate](https://www.sugarlabs.org/donate/) under "Our 990 tax filings." - -I also helped Sugar Labs secure in-kind services that help our daily operations at no cost to us. - -This year, we received Open Source Credits from Amazon Web Services (AWS) that are helping us test and develop new educational software; we received over one-hundred terabytes of data storage through Google Workspace for nonprofits; and we received other in-kind services that are helping us run our organization more efficiently. - -I also started a series of live events online where past and current contributors and students have a platform to tell their stories, as well as to invite guests from other organizations to discuss the future of technology-in-education. - -I did this because, although Sugar Labs's impact is somewhat obvious to the many who are active in the community, I've found that there are still many untold stories from community members whose lives are impacted positively. - -As I've continued to speak to members of the community and published their stories, I've found that these previously untold stories continue to affirm the important role Sugar Labs plays in education. - -For example, in [one of my interviews with Ibiam Chihurumnaya](https://youtu.be/JLsUiVzZ5Z0), Ibiam shares how the Sugar Learning Platform and the Sugar community introduced him and his classmates to programming from a young age and has given him skills he continues to use to this very day. - -As for our work this summer, Sugar Labs participated in our fourteenth Google Summer of Code (GSoC) to assist students to work on eleven projects. - -This, combined with our first-ever participation in Code4GovTech's Dedicated Mentorship Program (DMP), advanced our software development, mentoring a total of fourteen students who worked an estimated five-thousand hours on projects spanning the gamut from *Maintaining and Porting Twelve Activities to Flatpak,* to creating new math games, to creating promising new generative-AI services for both teachers and learners. - -To get a better sense of all that we accomplished this summer, you are encouraged to watch the *Finale* series of students' presentations on our [YouTube channel](https://www.youtube.com/@SugarlabsOrg-EN). - -We're proud of the work we've done so far this year. Yet, we know that we can do even more. - -For example, in order to publicly deploy the five generative-AI services we created this summer, we'll need additional computational resources. - -We understand that using resources on "AI" may seem like a luxury at this point in time, but we're persuaded that gen-AI will remain as a mainstay technology, and we owe it to our students to assist them in understanding and navigating this technology in a way that empowers them. - -Plus, we've already created prototypes, such as an assistant for lesson plan creation and a bot to assist with learning the basics of programming in Python, that we have found to be helpful for our students to learn and cultivate important skills and new ways of looking at the world. - -Just as we did when we created web-based software to run on any system or computer, we understand that we'll need to offer learning opportunities in gen-AI in order to stay current and relevant in an ever-evolving landscape. - -That said, we haven't compromised on our fundamental values. - -All of the services we created over the summer are licensed under a FLO license, allowing for freedom and full transparency so that learners can explore these systems at whatever level satisfies their curiosity. - -And, of course, we design our software so that students are empowered to create with these tools and build a portfolio of their work. - -All of these projects are exciting for us, and we hope that you're excited about them, too. - -However, in order to successfully implement all these projects—plus the myriad grants that I've written, and continue to write—*we must expand our capacity as an organization*. And, in order to increase our capacity, we need to raise funds to hire more staff. - -I dream of the day that we have a team of at least ten staff dedicated to assisting schools with their deployments and curricula, conducting ongoing research on how our tools are being used, helping with ongoing software maintenance, and running daily operations. - -Having these sorts of resources would help us achieve learning outcomes for students and their teachers. - -And it would also free up our volunteer community to focus on what they love about Sugar Labs: working on innovative projects under knowledgeable mentors to build and learn new skills. - -We have set an initial goal for this fall of $25k to grow in our second year of operations. - -Can you help us in this goal by contributing $3 or more? Your tax-deductible contribution will help us increase our capacity to continue to create innovative tools for learning, together with teachers and learners. - -**[Donate to Sugar Labs today](https://www.paypal.com/donate?campaign_id=NEAV3YL4H6B5S)** - -Donate today: [https://www.paypal.com/donate?campaign_id=NEAV3YL4H6B5S](https://www.paypal.com/donate?campaign_id=NEAV3YL4H6B5S) - -We are hopeful for the future in large part because we've accomplished so much in the past. - -We couldn't have gotten to where we are today without the contributions of hundreds of supporters over the years, both financial and volunteer efforts. - -We continue to be a unique, positive community and a wonderful place where **youth can solve authentic tasks and learn by doing**. - -Looking toward the next three to five years, we want to amplify all the great things in our community—mentorship, learning software, emphasis on problem solving is welcome and encouraged. - -Your contribution can help us expand our reach, and it can help us do so much more. - -From the bottom of my heart, thank you for reading this message and thank you for your time and consideration. - -Sincerely, -Devin Ulibarri -Executive Director, Sugar Labs Inc. - -P.S. Visit [https://www.sugarlabs.org/donate/](https://www.sugarlabs.org/donate/) to donate to, and support, our mission today! \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2024-12-19-election-results.md b/src/constants/MarkdownFiles/posts/2024-12-19-election-results.md deleted file mode 100644 index 0c5dc659..00000000 --- a/src/constants/MarkdownFiles/posts/2024-12-19-election-results.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "Board election results announcement: Three new members for the 2025-26 cycle" -excerpt: "The election results for the Sugar Labs Board of Directors have been announced. Devin Ulibarri, Sumit Srivastava, and Sebastian Silva will serve on the board for the 2025-26 cycle." -category: "COMMUNITY NEWS" -date: "2024-12-19" -slug: "board-election-results-2025-26" -author: "Devin Ulibarri" -description: "Executive Director" -tags: "elections,governance,board,community,leadership,voting" ---- -<!-- markdownlint-disable --> - -# The results for the 2025-26 Sugar Labs board cycle have been determined. - -The votes have been counted, and the [results](https://bettervoting.com/dp3xc7/) for the [2025-26 Sugar Labs board cycle](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) have been determined. - -The winners are **Devin Ulibarri, Sumit Srivastava, and Sebastian Silva**. They have all been notified and have agreed to serve on the Board of Directors for the 2025-26 cycle. For this election, we used [bettervoting.com](https://bettervoting.com) after doing research on various voting systems. Please read our [original election announcement](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) for more information on how we decided upon this voting system. - -The new members of the board will be filling the seats of two outgoing board members, **Lionel Laské and Alex Perez**, and one vacant seat. - -The next election for three seats to the **2026-27 cycle** is planned for **August of next year**. All Sugar Labs members may vote, and members can: -- Run for election to the Board of Directors -- Vote in the elections for the Board of Directors -- Suggest referenda - -As indicated in the [Sugar Labs Inc. bylaws](https://wiki.sugarlabs.org/go/Sugar_Labs/Governance), anyone with "significant and sustained" contributions to Sugar Labs is eligible for membership. If you believe you qualify for membership based on this criteria and are interested in [becoming an official member of Sugar Labs](https://wiki.sugarlabs.org/go/Sugar_Labs/Members), you are encouraged to send an email to <members@sugarlabs.org>. - -If you were a member in the past but [did not vote in this election](https://www.sugarlabs.org/community/2024/11/22/elections-extension/), you will need to reapply for membership in order for your membership status to be reinstated. *(If you voted in this election, no further action is required.)* Registering for membership early will help ensure that you will be ready for the next election. - -If you are interested in volunteering to assist with the next election in 2025, please contact <volunteering@sugarlabs.org> with your interest. - -On behalf of the [Sugar Labs Board of Directors](https://www.sugarlabs.org/leadership/), we offer a big **Thank you!** to all who participated in this year's election. diff --git a/src/constants/MarkdownFiles/posts/2024-12-25-Reflections-as-Parents-and-Teachers-Sugar-at-home-and-in-their-classroom.md b/src/constants/MarkdownFiles/posts/2024-12-25-Reflections-as-Parents-and-Teachers-Sugar-at-home-and-in-their-classroom.md deleted file mode 100644 index 8df3a592..00000000 --- a/src/constants/MarkdownFiles/posts/2024-12-25-Reflections-as-Parents-and-Teachers-Sugar-at-home-and-in-their-classroom.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: "Reflections as Parents and Teachers Sugar at home and in their classroom" -excerpt: "Sugar Labs Executive Director Devin Ulibarri shares personal experiences using the Sugar Learning Platform both as a parent with his son and as an educator in various classroom settings." -category: "SUGAR STORIES" -date: "2024-12-25" -slug: "reflections-as-parents-and-teachers-sugar-at-home-and-in-classroom" -author: "Devin Ulibarri" -description: "Executive Director" -tags: "education,parenting,classroom,sugar-activities,learning,teaching,literacy,programming" ---- -<!-- markdownlint-disable --> - -**Reflections as a parent and teacher: Sugar at home and in the classroom** -As the year comes to a close, I wanted to take some time to reflect upon how I've used Sugar both in the classroom and at home. I have a few hopes in mind as I share my experience engaging with Sugar both as a teacher and a parent. One hope is that it will show a window into some of the more grounded work Sugar Labs has done this year. - -Much of the most recent testimony that we've shared from the [Sugar Labs community](/@sugarlabs) has been centered around software development. While the success of students creating software is certainly important, the purpose of such progress is grounded in helping teachers teach and to help learners learn. Another hope is that the following vignettes will dispel doubts around the efficacy of the Sugar Learning Platform as an effective tool for education, which I've heard from a few folks during conversations throughout [my first year as Sugar Labs's executive director](https://www.sugarlabs.org/press/2024/05/08/Sugar-Labs-announces-nonprofit-status-new-executive-director/). This article will address those doubts directly. My third hope is that my experiences will inspire others, whether parents or teachers (or both), to try Sugar themselves. - -## The first few years as a parent - -My son Kai was born in 2017, but it was about three years before his birth that I became involved in Sugar Labs. It's a story that I've told in more depth before, but I became interested in Sugar Labs because of their unique approach to education. At the time, I was doing research on the _implications of software-freedom-in-education_, which led me to conclude that the freedoms granted to users in free/libre/open (FLO) source software have [profound positive implications for education](https://wiki.sugarlabs.org/go/File:Education-needs-free-software.pdf). I attended a talk given by Sugar Labs founder Walter Bender, and we soon began working together to integrate music into [Turtle Blocks](http://activities.sugarlabs.org/en-US/sugar/addon/4027), in what is now known as [Music Blocks visual programming language](https://www.sugarlabs.org/music-blocks/). It was also around this time in 2014 that I received a One Laptop Per Child (OLPC) laptop from Walter that I used to familiarize myself with the Sugar Learning Platform. - -Although I had shown Kai a few things on the OLPC when he was a toddler, such as creating a paint program for him in the Turtle Blocks Activity, it wasn't until he was about four years old that he really took to it. His first, most sustained, interest in the computer came when he was learning to read by himself. I remember that his desire to read was basically insatiable. In fact, he had memorized some sections of the graphic novel series _Dog Man_ by [Dav Pilkey](https://en.m.wikipedia.org/wiki/Dav_Pilkey), which I had read to him multiple times because he loved it so much. At four years old, Kai had memorized a lot of the story, but he wasn't yet reading himself; he was still dependent on others to read for him. It was at this point that he found the [Speak Activity](http://activities.sugarlabs.org/en-US/sugar/addon/4038) on his OLPC, and this is when he had a real breakthrough with reading. - - -*Kai, with his OLPC, running the Speak Activity on the Sugar Learning Platform.* - -The basic way that the Speak Activity works is by taking typed input from a user and speaking it back to them when they press return. I remember Kai walking around the house, finding words on various things around the house, typing those words into the computer, and listening to the result. It was in this way that he memorized the spelling of a few words, and, soon enough, he was creating sentences and telling the computer to speak those words back to him (or to me). It was also around this time that we went on a long family road trip, where Kai sat in the back seat typing various words and sentences and learning more and more about language. - - -*Kai, helping one of my students get up and running in Sugar for her first time.* - -Of course, I kept reading books to him, which is still invaluable to a child's development, but I am confident that the Speak Activity helped Kai become a more independent reader. The following year, Kai entered Kindergarten, where he learned phonics and he's been a solid reader ever since. He's now in second grade, and he often carries a few books around with him every day, everywhere he goes. - -## Reflections as a teacher in 2024 - -This year, I had a few memorable moments as a teacher in the classroom. This year, I mentored high school students in git version control, mentored another teacher in leading a Music Blocks class, and I even taught a group class for kids ages five and six on the Sugar Learning Platform. I'll share a little bit of what I learned from each experience here. - - -*Students in a Music Blocks class led by Rafael Moreno, who I guide as a teacher new to teaching programming.* - -Before the summer, I reached out to an acquaintance, Neil Plotnik, who teaches cybersecurity at a nearby high school. I [met Neil during my time at the Free Software Foundation](https://www.fsf.org/blogs/community/free-software-in-education-and-free-software-education) (FSF). He suggested that I reach out to the Computer Science (CS) teacher at his high school. Long story short, I spent a few weeks getting these youth ready to help with coding, mainly teaching them how to use git version control. These students had done a few coding projects at their school, but hadn't yet contributed to a community project. They hadn't used git before, which is important to know for software development (and the underlying concepts are important skills for any endeavor), so I spent most of the time showing them the basics. To be honest, I was a little bit surprised to find myself teaching git to a CS class, but I suppose this highlights one of the many reasons why an organization such as Sugar Labs is important. Sugar Labs offers pathways into collaborative software development that textbook coding exercises do not. - -Over the summer, I mentored a few contributors for Google Summer of Code (GSoC). A lot of this work is online, on our Medium blog and our YouTube channel. At the same time, however, I also worked with a student of mine, Nathan, who asked to have some internship experience over the summer. I've taught this particular student for almost ten years now. He's taken guitar lessons with me, and he's taken Music Blocks classes with Walter Bender and myself. First, I asked him to create some fun projects for kids, which he did with gusto. You can read about his projects here: [https://musicblocks.net/2024/08/05/nyc-interactive-subway/](https://musicblocks.net/2024/08/05/nyc-interactive-subway/) and [https://musicblocks.net/2024/07/18/sitar-tabla-and-tampura-for-makey-makey/](https://musicblocks.net/2024/07/18/sitar-tabla-and-tampura-for-makey-makey/). Then, I asked him to create lesson plans, which he also did very well. And then, near the end of the summer, I involved him with testing some of the latest development for Music Blocks, which included a few [AI projects](https://www.youtube.com/playlist?list=PLyTz5XRZyi-xR5NGo1fHLbYJYo2OwRFta). Testing these required that he set up a development environment, test the software as a user, and report the results as issues on GitHub. His work over the summer marked a good amount of growth and progress, which continues to this day. - - -*Nathan, testing new features for Music Blocks.* - -At the beginning of the school year in the fall, I began mentoring a fellow teacher who is leading a Music Blocks class on a weekly basis. I provide the teacher, Rafael Moreno, guidance in lesson planning and feedback on classes. Rafael is a singer from Panama, now living in Boston, MA, working as a teaching artist. - -Also in the fall, I started teaching kindergarten and first grade students in a weekly computer class. This class happens at the same time as Rafael teaches Music Blocks. We decided to split the group by age, and I decided that my (younger) group would benefit most from doing something a little more open ended and basic. So, for the first day, I prepared some OLPC laptops for the kids, and I had them just try the Speak Activity. They had a blast. At one point, I tried to show them another Activity, but they insisted on continuing with the Speak Activity. The following week, we had a new student and I didn't have more than two OLPCs, so I prepared two Thinkpad X1s with Sugar Toast installed for the new student and for Kai, who joined us that day to show the group what else the computers could do. Kai did a wonderful job leading this second day of classes, and it was heartwarming to see him share his knowledge with his new friends in the class. As of now, I've taught this class for a few months, and the kids have explored several of the Activities, including [Maze](http://activities.sugarlabs.org/en-US/sugar/addon/4071), [Write](http://activities.sugarlabs.org/en-US/sugar/addon/4201), [Chat](http://activities.sugarlabs.org/en-US/sugar/addon/4069), [Turtle Blocks](http://activities.sugarlabs.org/en-US/sugar/addon/4027), and several of the [games](http://activities.sugarlabs.org/en-US/sugar/browse/type:1/cat:60). At the end of each class, the kids are asked to share with the class what they're working on. And, on the last day of class before the break, they presented their work to their parents. - - -*Two of my students, smiling during their second class, using the Sugar Learning Platform on two OLPCs.* - -One of the things that strikes me the most from this particular class is the _joy_ that the kids show as they're working on their activities. It reminds me of a study I read by Bloom, described in Robert J. Trotter's article for _Psychology Today_, July 1986, "The Mystery of Mastery". Studying how people achieve mastery, Bloom observed a few common factors among those who became experts as adults. The children who later became experts were introduced to the field as a playful activity, and learning at this stage was "like a game." As for Sugar, the kids in my class are learning a lot of things in the class, such as spelling, typing, and language, but the playfulness they exhibit is developmentally appropriate. This is consistent with the research on human development, and I've found it to hold true during my own work in the classroom. - - -*Here are the notes I took in college that I used to reference the above paragraph. I add it here because I no longer have access to the original article, and I could not find a copy online. If you find a link to a electronic copy, please drop it into the comments below.* - -## Conclusions - -As I alluded to earlier, I have sometimes heard criticism of the Sugar Learning Platform, suspecting that it may be out of touch with the needs of the students. The criticism is typically accompanied by an argument that youth should be preparing for job skills by using a platform more similar to what an office worker uses (e.g. _Shouldn't the kids be taught how to use Microsoft Word instead?_). However, as an educator, I've never bought that argument. And now that I've spent ten years with Sugar — both as an educator and as a parent — I wholly reject it. I can say confidently that youth learn very important skills through their engagement with Sugar. And perhaps most importantly, they are introduced to concepts in stages that are appropriate to their development. - - -*One of the students in my Sugar class. She surprised me by coming in with this hand-drawn computer, which she made just a few days after taking one of her first classes.* - -I'm more proud than I ever have been to be a part of the Sugar community, and my decades' long experience with youth from ages five through college, only gives me stronger conviction that we're creating something of unique value for education. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2024-12-29-sweet-spot-002.md b/src/constants/MarkdownFiles/posts/2024-12-29-sweet-spot-002.md deleted file mode 100644 index 9815206d..00000000 --- a/src/constants/MarkdownFiles/posts/2024-12-29-sweet-spot-002.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -title: "The Sweet Spot – Issue 002" -excerpt: "The second issue of Sugar Labs' newsletter covering recent updates, events, volunteer opportunities, and community news from December 2024." -category: "COMMUNITY NEWS" -date: "2024-12-29" -slug: "the-sweet-spot-issue-002" -author: "Devin Ulibarri" -description: "Executive Director" -tags: "newsletter,community,updates,elections,social-media,volunteer,outreach,education" ---- -<!-- markdownlint-disable --> - -# Recent news for December 29, 2024 - -Welcome to the second issue of the **"Sweet Spot"**, a newsletter for Sugar Labs-related news in development, student and teacher work, events, how to get involved, and other news and information. This newsletter will be published semi-regularly for now, but the plan is to publish it on a bi-monthly, perhaps even monthly, basis in the future. Our aim with this newsletter is to help keep the growing body of Sugar Labs contributors on the same page, all while documenting our growth for our own and others' reference. - -These first issues are meant to set a precedent of communication and documentation, as well as to help inform the community of our current status, recent progress, and future plans. Its predecessor is the [Sugar Digest](https://lists.sugarlabs.org/archive/community-news/), which still serves as an important catalog of our activities. Like Sugar Digest, this newsletter is intended to keep community members in the loop about everything going on within Sugar Labs. It will highlight any recent publications from us. It will occasionally include links to third-party news and updates that our community finds relevant. - ---- - -## Updates - -### Today, help Sugar Labs continue to transform education - -**December 3, 2024** - - -*Your donation helps us in many ways.* - -Sugar Labs is in the middle of a campaign to raise funds necessary for outreach, software development, project maintenance, mentorship, and more. Having left Software Freedom Conservancy in 2020, this year is the first that Sugar Labs is investing financially in its own growth, and we'd love to have your participation in this pivotal moment. We've been particularly heartened to see volunteers in our community assist with various aspects of this campaign, such as making improvements to our website. You may also participate in our fundraiser, while getting something nice for yourself or a loved one, by purchasing Sugar Labs merchandise from our new store on Bonfire. - -Read executive director Devin Ulibarri's letter to the community to learn more about the work we've done this year, consider making a donation or purchasing merchandise, and please help spread the word. - -- [Learn more about our work](https://www.sugarlabs.org/community/2024/12/03/help-SL-continue-to-transform-education/) -- [Donate now](https://www.paypal.com/donate?campaign_id=NEAV3YL4H6B5S) -- [Visit the new donation banner](https://www.sugarlabs.org/) -- [Get Sugar Labs merchandise](https://www.bonfire.com/sugar-labs-education/) - ---- - -### Sugar Labs election information and results - -**December 19, 2024** - -Sugar Labs completed an election for three seats to its Board of Directors for the 2025–26 cycle. The results are out, and the winners are **Devin Ulibarri, Sumit Srivastava, and Sebastian Silva**. Read the articles to learn more about Sugar Labs's election process and how you can prepare to participate in the next election. - -- [Election results](https://www.sugarlabs.org/community/2024/12/19/election-results/) -- [Elections extension](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) -- [How to participate](https://www.sugarlabs.org/community/2024/11/08/fall-board-elections-how-to-participate/) - ---- - -### Sugar Labs expands its social media presence to Bluesky and WhatsApp - -**December 9, 2024** - -Sugar Labs is now on **Bluesky** and **WhatsApp**. Sugar Labs continues to maintain a presence on X (formerly Twitter), Facebook, Mastodon, Instagram, YouTube, LinkedIn, and GitHub. We decided to join Bluesky and WhatsApp in an effort to expand our reach. For those active on any of these platforms, please follow Sugar Labs to help our outreach efforts. - -- [Marketing announcement](https://lists.sugarlabs.org/archive/marketing/2024-December/004160.html) - -**Newly joined social media platforms:** -- [Follow us on Bluesky](https://bsky.app/profile/sugarlabs.bsky.social) -- [Reach out on WhatsApp](https://wa.me/16177024088) - ---- - -### Reflections from Constructing Modern Knowledge 2024 - -**November 27, 2024** - -Sugar Labs executive director and Music Blocks co-maintainer **Devin Ulibarri** attended **Constructing Modern Knowledge (CMK)**. In this post, Ulibarri shares his experience at the teacher institute, what he learned, and what it could mean for Sugar Labs. - -- [Read Devin's reflection on Medium](https://medium.com/@sugarlabs/reflections-from-constructing-modern-knowledge-2024-1ce7d60fbb1c) - ---- - -### James Simmons's Sugar Story: Writing new Activities and sharing Sugar with youth - -**September 3, 2024** - -Sugar Labs community member **James Simmons** shares his story about his involvement with Sugar Labs. Simmons tells us how he began contributing to the Sugar Learning Platform by expanding the functionality of the Read Activity and adding support for e-texts. - -- [Read James's story](https://medium.com/@sugarlabs/james-simmonss-sugar-story-writing-new-activities-and-sharing-sugar-with-youth-9282c66f9219) -- *Make Your Own Sugar Activities!*: - - [English (Internet Archive)](https://archive.org/details/MakeYourOwnSugarActivities) - - [Spanish (Internet Archive)](https://archive.org/details/ComoHacerUnaActividadSugar) -- [See all of James's Activities](https://activities.sugarlabs.org/en-US/sugar/user/45) - ---- - -## (Volunteer) Help wanted - -Sugar Labs is seeking volunteer assistance in various areas. If you are passionate about our mission and can commit time, we encourage you to apply. - -- [Help Wanted wiki](https://wiki.sugarlabs.org/go/Help_Wanted) -- [Watch volunteer appeal](https://www.youtube.com/watch?v=W5ZLFBZkE34) - ---- - -## Upcoming events and meetings - -**Regular meetings:** - -- **Music Blocks meetings**: Every Sunday at 7:00 EST (12:00 UTC) - [Join on Jitsi](https://meet.jit.si/ResponsibleMasksForecastHastily) -- **Sugar Activity meetings**: Every Wednesday at 7:00 EST (12:00 UTC) - [Join on Jitsi](https://meet.jit.si/ResponsibleMasksForecastHastily) -- **Sugar Labs Board of Directors meetings**: Every Wednesday at 14:30 EST (19:30 UTC) - [Join on Matrix](https://matrix.to/#/#sugar:matrix.org) - ---- - -## About Sugar Labs - -**Sugar Labs®** is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology for youth. Volunteers work together to develop activity-focused software for children. - -Support Sugar Labs by donating at [www.sugarlabs.org/donate](http://www.sugarlabs.org/donate/). - ---- - -## Social and Communication Links - -Stay connected with Sugar Labs on the following platforms: - -- [Bluesky](https://bsky.app/profile/sugarlabs.bsky.social) -- [Facebook](https://www.facebook.com/SugarLabsforall/) -- [GitHub](https://github.com/sugarlabs) -- [Instagram](https://www.instagram.com/sugarlabsforall/) -- [LinkedIn](https://www.linkedin.com/company/sugar-labs) -- [Mailing lists](https://wiki.sugarlabs.org/go/Mailing_Lists) -- [Mastodon](https://mastodon.social/@sugar_labs) -- [Matrix](https://matrix.to/#/#sugar:matrix.org) -- [Medium](https://medium.com/@sugarlabs) -- [Twitter/X](https://twitter.com/sugar_labs) -- [WhatsApp](https://wa.me/16177024088) -- [YouTube](https://www.youtube.com/@SugarlabsOrg-EN) - ---- - -## Back issues of "The Sweet Spot" - -Find this issue and past issues at: [sugarlabs.org/community-news](https://www.sugarlabs.org/community-news/) diff --git a/src/constants/MarkdownFiles/posts/2025-01-21-SoaS-USB-announcement.md b/src/constants/MarkdownFiles/posts/2025-01-21-SoaS-USB-announcement.md deleted file mode 100644 index 410c15f7..00000000 --- a/src/constants/MarkdownFiles/posts/2025-01-21-SoaS-USB-announcement.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "Get and gift Sugar: Purchase new Sugar on a Stick USBs" -excerpt: "Sugar Labs now offers pre-installed Sugar on a Stick USB drives for purchase, making it easier for educators and supporters to use and share our educational software." -category: "COMMUNITY NEWS" -date: "2025-01-21" -slug: "get-and-gift-sugar-soas-usbs" -author: "Devin Ulibarri" -description: "Executive Director" -tags: "products,merchandise,SoaS,USB,education,fundraising,open-source" ---- - -<!-- markdownlint-disable --> - -A few times in recent months, we received questions from folks about how to buy Sugar. Until now, the only response we had was that we didn't offer them for sale but that you could [create your own by following our instructions](https://wiki.sugarlabs.org/go/Sugar_on_a_Stick/Installation). If you wanted to [run Sugar on a Stick](https://www.sugarlabs.org/booting-soas/), you had to flash a USB drive yourself before using it. - -Of course, flashing a USB can be a great educational experience, and this will remain an option. However, what we heard from people asking this question was that they wanted a few things that they couldn't get from flashing a USB themselves. - -One is that they wanted the **convenience—and added assurance—of purchasing a USB from a reputable vendor**. Another is that some people were expecting something **branded with the Sugar Labs logo**. For some, it may be the ability to **gift a USB** for a friend or teacher. And, for the majority who reached out to us, it seemed that they wanted a way to **pay us for the software**, and, in so doing, **help sustain our work for years to come**. - -Well, we're excited to share the news that you are **now able to purchase a Sugar Labs-branded USB with Sugar on a Stick pre-installed!** - - -*Samples of two USBs with Sugar on a Stick pre-installed. All profits from purchases will go to Sugar Labs to help develop current and future learning projects.* - - -We partnered up with USB Memory Direct for this particular offering. USB Memory Direct (UMD) has a history of supporting [free/libre/open source projects such as ours](https://www.sugarlabs.org/about-us/). They will also be handling inventory and shipping & handling, which means that we at Sugar Labs can keep focusing on what we do best: create learning software for education! Plus, UMD will give **all profits from sales to Sugar Labs**, which we will use to further our mission in Constructionist education. - -Now that we have both clothing merchandise and SoaS USBs for purchase, we created a new [product page](https://www.sugarlabs.org/product/). - -- 🧁 [Buy Sugar on a Stick (SoaS) USBs](https://www.usbmemorydirect.com/store/novelty/sugarlabs/) -- 👕 [Buy Sugar Labs clothing merch](https://www.bonfire.com/store/sugar-labs-merch/) - -Detailed product information and specifications are on the respective landing pages. - -If you purchase a USB or clothing merchandise, **please let us know about it!** You can either [contact us](https://www.sugarlabs.org/contact-us/) directly, or you can create a post on social media with the hashtag [#SugarLabs](https://mastodon.social/tags/sugarlabs) for us to find. - -📹 And if you create a video of your experience on YouTube, let us know and we can add it to [our Sugar on a Stick playlist](https://www.youtube.com/playlist?list=PLyTz5XRZyi-xuPdS7kReqP5Nu5TAlTu4f). - -We love hearing from you! diff --git a/src/constants/MarkdownFiles/posts/2025-03-24-annual-report-2024.md b/src/constants/MarkdownFiles/posts/2025-03-24-annual-report-2024.md deleted file mode 100644 index aff03f25..00000000 --- a/src/constants/MarkdownFiles/posts/2025-03-24-annual-report-2024.md +++ /dev/null @@ -1,433 +0,0 @@ ---- -title: "2024 Annual Report" -excerpt: "A comprehensive overview of Sugar Labs' accomplishments, activities, and financial status throughout 2024, including development projects, outreach efforts, classroom implementations, and community growth." -category: "COMMUNITY NEWS" -date: "2025-03-24" -slug: "annual-report-2024" -author: "Devin Ulibarri" -description: "Executive Director" -tags: "annual-report,education,gsoc,outreach,classroom,finance,development,community" ---- -<!-- markdownlint-disable --> - -# Annual report for 2024 - -This report is meant to be an overview of the work Sugar Labs did in 2024. Looking back, we did a lot of work. We participated in events in the US and India. We mentored more than a dozen students over the summer for Google Summer of Code and the Dedicated Mentorship Program, the latter of which we participated in for the first time last year. - -We launched a series of online videos to showcase our work to the public while simultaneously giving a platform for young contributors to reflect upon their progress and be introduced to a larger developer community. We created a handful of entirely new software projects for learning, such as new math games and Sugarizer activities. We improved our existing software—implementing new features, fixing bugs, and making our learning software available on more platforms. We did all this and more in 2024, which I detail below. - -In many aspects, this report is highly personal. I share about my own journeys to conferences, photos of the people I met, and the students to whom I introduced Sugar. In 2024, I became Sugar Labs's first full-time staff member, which helped me fully dedicate myself to many aspects of the organization. We were also able to sponsor community members like Anindya Kundu to represent Sugar Labs internationally. - -As you read this report, please understand that the vision for Sugar Labs as a nonprofit organization is to grow to be able to support more and more people like myself, so we can have an even wider reach. That said, Sugar Labs, being a free/libre/open source community-driven project, makes its tools available to the public under free licenses, so anyone may use what we've created to support teachers and classrooms in their communities, regardless of their "status" within the organization. - -In other words, Sugar Labs is *not* a one-man-band. Instead, it's a community of orchestras and ensembles. The organization is meant to support those orchestras and ensembles, comprised of teachers and learners, listening to and responding to their needs. - -It is my hope that 2025's annual report includes even more stories and photos from the broader Sugar Labs community. Sugar Labs welcomes your interest, support, and contributions. I encourage you to join our community of teachers, learners, and parents working together to create better tools and a supportive environment for learning. - -I hope the annual publication of our work in the form of an executive summary will serve as a benchmark as we work toward continuous self-improvement as a nonprofit dedicated to serving our community of teachers and learners. - -## Development in 2024 - -### Google Summer of Code (GSoC) and Dedicated Mentorship Program (DMP) - -As for our work this summer, Sugar Labs participated in our fourteenth Google Summer of Code (GSoC) to assist students in working on [eleven projects](https://www.sugarlabs.org/press/2024/05/01/Sugar-Labs-receives-eleven-contributor-projects-for-GSoC-2024/). This, combined with our first-ever participation in Code4GovTech's Dedicated Mentorship Program (DMP), advanced our software development, mentoring a total of fourteen students who worked an estimated five thousand hours on projects ranging from maintaining and porting twelve activities to Flatpak, to creating new math games, to promising new generative-AI services for both teachers and learners. - -To get a better sense of all that we accomplished this summer, you are encouraged to watch the Finale series of students' presentations on our YouTube channel at [https://www.youtube.com/@SugarlabsOrg-EN](https://www.youtube.com/@SugarlabsOrg-EN). - -We also encourage you to check out the work in more detail by reading the reports published on Medium: - -- [https://medium.com/@sugarlabs/list/google-summer-of-code-d90eae4b54fb](https://medium.com/@sugarlabs/list/google-summer-of-code-d90eae4b54fb) -- [https://medium.com/@sugarlabs/list/code4govtech-3377e03c6dd5](https://medium.com/@sugarlabs/list/code4govtech-3377e03c6dd5) - -## Outreach and communications - -### Online events - -In 2024, I started a series of live events online where past and current contributors and students have a platform to tell their stories, as well as invite guests from other organizations to discuss the future of technology in education. - -I did this because, although Sugar Labs's impact is obvious to many in the community, I've found that there are still many untold stories from community members whose lives have been impacted by our work. Publishing these stories has continued to affirm the important role Sugar Labs plays in education. - -For example, in [my interview with Ibiam Chihurumnaya](https://youtu.be/JLsUiVzZ5Z0), he shared how the Sugar Learning Platform and community introduced him and his classmates to programming from a young age and gave him skills he continues to use to this day. - -### Expanded social media presence - -Last year, we expanded our presence on social media. In addition to Facebook, Instagram, YouTube, and LinkedIn, we are now on Bluesky, WhatsApp, and my personal favorite, Mastodon. - -If you are on any of these platforms, please follow Sugar Labs and boost our posts to support our outreach. If you're interested in helping with our outreach, join our marketing mailing list and express your interest: [https://lists.sugarlabs.org/listinfo/marketing](https://lists.sugarlabs.org/listinfo/marketing). - -### Reboot of regular newsletters - -In 2024, we relaunched regular newsletters, now sent approximately once every three months. These newsletters share our progress as an organization and news valuable to our community: - -- [https://www.sugarlabs.org/community/2024/09/20/sweet-spot/](https://www.sugarlabs.org/community/2024/09/20/sweet-spot/) -- [https://www.sugarlabs.org/community/2024/12/29/sweet-spot-002/](https://www.sugarlabs.org/community/2024/12/29/sweet-spot-002/) - -### Newsletter email subscription - -Our newsletters are published to the website and also sent via email. In 2024, we started using Buttondown to send newsletters to subscribers worldwide. If you're not subscribed yet, please do so: [https://buttondown.com/sugarlabs](https://buttondown.com/sugarlabs). - -### Reboot of Sugar Stories - -In 2024, we began collecting stories from our community. While it's still early, we've already received some fantastic articles. - -- From [James Simmons](https://activities.sugarlabs.org/en-US/sugar/user/45): [Helping others to create their own Sugar Activities](https://www.sugarlabs.org/stories/2024/09/13/Writing-new-Activities-and-sharing-sugar-with-youth/) -- From me: [Reflections as Parents and Teachers](https://www.sugarlabs.org/stories/2024/12/25/Reflections-as-Parents-and-Teachers-Sugar-at-home-and-in-their-classroom/) - -You can read these and more at: [https://www.sugarlabs.org/sugar-stories/](https://www.sugarlabs.org/sugar-stories/) - -If you have a story, share it via [info@sugarlabs.org](mailto:info@sugarlabs.org) or through the mailing lists: - -- Education: [https://lists.sugarlabs.org/listinfo/iaep](https://lists.sugarlabs.org/listinfo/iaep) -- Development: [https://lists.sugarlabs.org/listinfo/sugar-devel](https://lists.sugarlabs.org/listinfo/sugar-devel) - -### Major improvements to our website - -Throughout 2024, I worked on updating our website, which needed attention. Being unfamiliar with Jekyll (the framework it's built on), I struggled at first, but with help from the free software community, I learned enough to begin publishing updates more regularly. - -Near the end of the year, more folks from the development community pitched in. Now, the site is in much better shape, and we are working toward a completely revamped version set to launch in April 2025. - -Thanks to the many volunteers who helped! Interested in joining the web team? Visit [https://matrix.to/#/#sugarlabs-web:matrix.org](https://matrix.to/#/#sugarlabs-web:matrix.org). - -### Conference talks - -In 2024, we sent representatives to a few in-person conferences. With limited budget, we focused on visibility, sending me to several conferences in the US and sponsoring Anindya Kundu to represent us at the Opportunity Open Source Conference at IIT Kanpur. - -### - LibrePlanet - -In May, I attended the Free Software Foundation's annual LibrePlanet conference in Boston, MA. There, I [handed out flyers](https://mstdn.io/@codewiz/112384505018899979) and showed off a computer running the Sugar Desktop Environment. - - -*Devin Ulibarri and FSF executive director Zoë Kooyman, in front of the FSF office in Boston, MA. The FSF hosts the annual Libre Planet conference.* - -### - 2024 Micro Camp - -In June, I spent a weekend at a 2024 Micro Camp, a retreat for microtonal musicians, where I showcased the Music Blocks visual programming language. Music Blocks, a flagship Sugar Labs project, has rich microtonal capabilities. I showcased those features during one of the first talks of the retreat, and I even used Music Blocks as a musical instrument to perform a piece of music that requires twenty-two divisions of the octave—something for which I did not have a capable physical instrument, except for [a programmed instrument I created within Music Blocks](https://musicblocks.sugarlabs.org/index.html?id=1719093905649087&run=True). - -At the conference, I was also pleasantly surprised to meet so many free/libre/open source developers and educators. A large percentage—much larger than at most music conferences—were developing software. In retrospect, it makes sense that there are so many microtonalists who develop software, because these musicians typically need to create instruments that play pitches differently from what you would find in most stores, and they use both physical and digital mediums to craft such unique instruments. - - -*Music Blocks has many affordances for tuning and temperament, an important concept in music. The program in this screenshot performs a 22 equal-divisions-of-the-octave (EDO) pitch whenever you touch one of the mice.* - - -*Devin (at right) performs a piece, written in 22 EDO, together with an ensemble using Music Blocks on a tablet.* - - -*The ideas that inspire Music Blocks come from musical concepts, instruments, and traditions. Devin (at left) performs together with composer and microtonalist Kite Giedraitis.* - -### - CMK - -In July, I attended Constructing Modern Knowledge (CMK), a retreat for teachers, in Manchester, NH. This retreat is a good fit for Sugar Labs as it is focused on Constructionism. CMK brings together passionate educators from around the world to work on new and creative projects, which they bring back to their respective schools. - - -*Gary Stager is the organizer of CMK, a retreat for teachers to work together on Constructionism projects.* - - -*CMK participants are expected to work in groups create a project. On the final day, each group presents their project.* - - -*The 2024 CMK brought two esteemed individuals working in music education, Tricia Tunstall (left) and Melissa Walker* - - -*Devin (at left) collaborated with Jamie Chelel (MIT) to create lego notation for the blind.* - - -*Devin and Jamie created a simple and detailed notation system as a starting point to explore lego as a music notation system for the blind.* - - -*CMK attracts many passionate instructors. Devin (far left) had the pleasure of working together with Josh Burker (left), Tracy Rudzitis (right) and many others.* - -You can read my full article on the experience, as well as work done toward creating a system for using Lego blocks to encode musical data, here: -[https://medium.com/@sugarlabs/reflections-from-constructing-modern-knowledge-2024-1ce7d60fbb1c](https://medium.com/@sugarlabs/reflections-from-constructing-modern-knowledge-2024-1ce7d60fbb1c). - -### - FOSSY 2024 - -In August, I attended FOSSY, hosted by the Software Freedom Conservancy, in Portland, OR. I gave a talk titled "[Mentoring youth: The FOSS strategy we've been looking for](https://2024.fossy.us/schedule/presentation/202/)". You can watch the talk on our YouTube channel at -[https://www.youtube.com/watch?v=mKBXSC9Veq8](https://www.youtube.com/watch?v=mKBXSC9Veq8). - -I also ran two Birds of a Feather sessions. One was a Music Blocks workshop, where Bryan Ollendyke of [HAX](https://hax.psu.edu/) tested the limits of the JavaScript editor in Music Blocks. The other was a free/libre/open (FLO) music concert, where I joined [Aaron Wolf](https://blog.snowdrift.coop/author/wolftune/), [Timmy Barnett](https://gnulinux.love/), [Kite Giedraitis](https://tallkite.com/), and others to showcase [FLO](https://wiki.snowdrift.coop/about/free-libre-open) through instruments, software, and a variety of music. - - -*Music Blocks has an export to Javascript feature, which got the attention of Bryan Ollendyke, creator of HAX.* - - -*Music Blocks is a waypoint not a destination. That's why we offer learners the option to export to Lilypond, MIDI, and Javascript.* - - -*At FOSSY, Devin gave one talk and led two Birds of a feather sessions. One session was for Music Blocks, and the other was a music concert.* - - -*Sugar Labs Google Code-In mentor and Libre Learn Lab director Mariah Villarreal (left) has dedicated her career to STEAM education and free software.* - - -*Free software volunteer Jason Self attended FOSSY.* - - -*Bryan Ollendyke (left), creator of HAX, and his son attended the Music Blocks workshop at FOSSY.* - - -*Devin performed together with microtonalist Kite Giedraitis at FOSSY.* - - -*There were many "FLO musicians" at FOSSY. Among the musicians who performed in the concert who also gave a talk were Aaron Wolf of Snowdrift (2nd from the left), Timmy Barnett (third from left), and Devin Ulibarri (2nd from the right).* - - -*After the concert, audience members got a chance to play the instruments. Alternate tuning on the Linnstrument is made possible thanks to free/libre/open (FLO) source software, an important concept for Sugar Labs.* - -### - Internet-in-a-box demonstration - -Also in August, I attended a meetup to demonstrate [Internet-in-a-box](https://internet-in-a-box.org/) (IIAB), led by [Adam Holt](https://github.com/holta). Kids and teachers got an opportunity to see what IIAB does and to try it. [Sugarizer](https://sugarizer.org/), the web-based version of the Sugar Learning Platform, is among the packages chosen for IIAB, which empowers schools to use learning services that would otherwise require an internet connection. - - -*Internet-in-a-Box (IIAB) is a solution for communities that do not have internet access. It acts as a server with educational software and services pre-installed.* - - -*Sugarizer is one of the programs that comes pre-installed on IIAB.* - -### - GSoC Mentor Summit - -Sugar Labs has participated in GSoC almost every year since 2009. This year, we worked on a number of projects. I was sent to represent Sugar Labs at the conference, hosted at Google headquarters. I met with other mentors, attended talks, and gave a lightning talk on our unique approaches to mentoring. - - -*Sameer Verma (at left) is the organizer for OLPC San Francisco and has documented some of Sugar Labs's growth over the years in the form of interviews.* - - -*Karen Sandler (at right) is the executive director for Software Freedom Conservancy, which acted as fiscal sponsor Sugar Labs until 2019.* - - -*Google hosts many orgs and many, many mentors for GSoC every year. Devin is at lower-left.* - -### - Opportunity Open Source Conference at IIT Kanpur - -Sugar Labs was invited to present at the Opportunity Open Source Conference at IIT Kanpur. We sponsored community member and Music Blocks v4 maintainer, Anindya Kundu, to represent our organization. Anindya presented his journey in Sugar Labs through a talk titled *"The 'build to learn' guide for Google Summer of Code and beyond."* - - -*Former GSoC participant and Music Blocks v4 maintainer Anindya Kundu represented Sugar Labs at the Opportunity Open Source Conference at IIT Kanpur in August.* - -Comment on, like, and share the original post: <https://www.instagram.com/p/C_S_ccSRlFR/> - -Interested in representing Sugar Labs at a conference? Please reach out to us at [info@sugarlabs.org](mailto:info@sugarlabs.org) for presentation feedback and handout materials. - -### - Boston Code Camp - -Sugar Labs Executive Director Devin Ulibarri and board member Walter Bender led a session for [Boston Code Camp on November 23, 2024](https://www.bostoncodecamp.com/CC37/Schedule/SessionGrid) titled *"Create musical code with Music Blocks"*, where they introduced Music Blocks to an audience of educators and technologists. - - -*Devin Ulibarri (at left) and Walter Bender (at right) have been working together on Music Blocks since its start in 2014.* - - -*Devin and Walter presented Music Blocks at Boston Code Camp in November.* - -## Sugar Labs in the Classroom - -### Music Blocks - -This year marked significant progress in research and development for the Music Blocks visual programming language. Alongside the development work done during GSoC over the summer, I explored every opportunity to bring the new features to students, teachers, and classrooms. - -I collaborated with one of my students, Nathan, who has studied music with me for about a decade and has also taken over a year of Music Blocks classes directly from Walter Bender. Together, we tested the new AI features, such as MIDI import, as well as experimental features like music transcription and lesson plan generators. - -During the same period, I worked closely with teachers who were preparing innovative Music Blocks lessons. They provided valuable feedback by reporting bugs and suggesting new feature requests based on their classroom experiences. - - -*Nathan (at back) has studied with Devin for ten years. Over the summer, Nathan came in regularly to test new Music Blocks features that were being developed as part of Google Summer of Code.* - - -*Two instructors for a summer camp at MAP Family Learning Center worked together to create lessons for different themes, such as Egypt, Spain, and India. One instructor is primarily a programmer, the other is a Berklee-trained musician.* - - -*One of the projects for GSoC was a LLM-enabled lesson plan generator. Nathan (at right) and I tested it as we were helping the instructors create lesson plans for five weeks of summer classes.* - - -*Nathan was eventually recruited to help the instructors create lesson plans. He utilized his knowledge and understanding of both music and programming to create projects for the students.* - - -*Nathan created unique projects for Music Blocks, which are now uploaded to the Planet. He had to debug both the music and the logic in order to make his projects work.* - - -*Lesson plans created by Nathan and the two teachers were used over the summer. The students had a great time, and we received important feedback to improve Music Blocks.* - -### Sugar Learning Platform and Sugar Activities - -In the fall, I began teaching a small group of kindergarten and first-grade students using the Sugar Learning Platform. We started with a few One Laptop Per Child (OLPC) laptops and later transitioned to newer hardware. The students quickly fell in love with their computers — calling the chat robot their "robot friend" — and eagerly created art, composed music, and played educational games. - -Our sessions covered a variety of topics, from spelling to problem-solving. The foundation we built early on eventually led to the students learning to program using Turtle Blocks. The class is ongoing, and it has been both a joy for the students and an insightful experience for me. - -Additionally, my time in the classroom has allowed me to provide valuable feedback to developers for future improvements to the platform. - - -*Devin ran "Sugar classes" for kindergarten and second grade in the fall.* - - -*The students in Devin's class expressed much joy as they explored the tools in Sugar.* - - -*Soon after the computers were introduced to the students, one student brought in her own computer. She had drawn a computer with a monitor and keyboard, modeled after her experience using Sugar.* - - -*Devin's son Kai (at right) helped the students in their first weeks.* - - -*At first, the computers took some getting used to. Now, the students understand the basics.* - - -*The students had a blast learning together with the Sugar Learning Platform.* - -### Teaching Git to Students of Everett High School - -In the spring, a couple of teachers at a local high school approached me about training their students in collaborative software development practices. I met with the students twice and followed up with them via email and group chat to support their learning journey. -Together, we covered the basics of Git version control, using the command line, and making their first contributions to our repositories. It was a rewarding experience that gave the students practical skills and an introduction to open source collaboration. - - -*The high school students were eager to contribute. Contributing to free/libre/open source projects like Sugar Labs typically requires version-control collaborative tools like git.* - - -*Devin (at left) met with the students of Everett High School two times to get them started as contributors for Sugar Labs.* - -## Finances - -Last year, I spent time working on our finances — where we keep our money, which platforms can be used to donate to our organization, and increasing the number of financial tools available to us. I did this work primarily to ensure that charitable donations can be made with confidence, ultimately helping every contribution we receive go further. - -One of the major improvements I made to increase financial transparency was updating and publishing our 990 tax filings. All of our tax documents are now up to date and publicly available on our [donations page](https://www.sugarlabs.org/donate/) under the section "Our 990 tax filings." - -In addition, I helped Sugar Labs secure in-kind services that directly support our day-to-day operations at no cost. This year, we received: - -- **Open Source Credits from AWS**: These credits are helping us test and develop new educational software. -- **Over 100 terabytes of data storage** through Google Workspace for Nonprofits. -- **Other in-kind services** that allow us to run more efficiently and at a lower cost. - -Lastly, I laid the groundwork for accepting financial contributions through a wide variety of platforms, including ACH, stocks, and even cryptocurrency. We were also added to the PayPal Giving Fund, which makes us discoverable through multiple corporate donation programs. Employers can now support Sugar Labs via Benevity, and all these channels are now live as of 2025 — a result of the foundational work completed in 2024. - -### Ways to Give - -- [every.org/sugar-labs](https://www.every.org/sugar-labs) -- [Benevity Causes](https://causes.benevity.org/causes/840-843289298) -- [MyGoodness by Benevity](https://mygoodness.benevity.org/community/cause/840-843289298/donate) -- [PayPal Giving Fund (for businesses)](https://www.paypal.com/us/fundraiser/charity/4357440) -- [Our Donations Page (up-to-date list)](https://www.sugarlabs.org/donate/) - -### In-kind Donations - -We received eleven ThinkPads (X1 Yogas) from Beacon Communities, LLC in April. These laptops feature touchscreens — a particularly useful feature for children — and have been used to teach both Sugar Activities and Music Blocks effectively. - - -*Trisquel is a distribution of GNU/Linux that offers a version for download that has the Sugar Learning Platform as its default.* - - -*The computers were received near the end of the school year, so the obvious way to test them out was to let the kids play with them.* - - -*The donated computers helped us train teachers and interns to use Music Blocks.* - - -*These nine computers are now property of Sugar Labs. They've been used since we've received them to teach Sugar and Music Blocks, as well as to test new code created by GSoC participants.* - - -*All of the donated laptops have touchscreens.* - - -*Students are able to interact with the computers via touch and with a mouse. They also ahve headphones they can use to hear sounds from the computers.* - -### AWS Open Source Credits - -In 2024, we applied for and were awarded **open-source credits worth $8,000** from Amazon Web Services (AWS). These credits will help us continue testing and developing the large language model (LLM) and neural network services we worked on over the summer. - -### New Sugar Labs Merchandise for Sale - -We added a fun twist to our fundraising efforts last year! Inspired by the community reaching out with questions like *"How can I buy Sugar?"*, we launched a variety of branded merchandise. - -We now offer: - -- **Clothing items** – Hoodies and t-shirts in a range of colors. -- **SoaS (Sugar on a Stick) USBs** – Bootable drives ready for use. - -To minimize overhead and simplify logistics, we partnered with two trusted vendors: - -- [**Bonfire**](https://www.bonfire.com/store/sugar-labs/) for apparel -- [**USB Memory Direct**](https://www.usbmemorydirect.com/) for USB drives - -All proceeds directly support Sugar Labs' mission to create educational software based on Constructionist learning principles. - - -*USB Memory Direct partnered with us to sell and distribute USBs with Sugar on a Stick (SoaS) pre-installed.* - - -*In 2024, we started a merchandise store through Bonfire.* - - -*The test package came with smarties and a sticker. The USB was tested and proven to work as expected.* - - -*Our store on Bonfire offers a range of colors and styles.* - -*To view and purchase our merchandise, please go to: -[https://www.sugarlabs.org/products/](https://www.sugarlabs.org/products/).* - -*Read more about the launch of our products: -[https://www.sugarlabs.org/community/2025/01/21/SoaS-USB-announcement/](https://www.sugarlabs.org/community/2025/01/21/SoaS-USB-announcement/).* - - ---- - -## 2024 Accounting Details: Revenue and Expenses - -In 2024, Sugar Labs reported a **net loss of $62,629.28**. - -### Revenue: -- **Total**: $7,872.86 - -### Expenses: -- **Total**: $70,502.14 - -#### Top Expenses: -1. Payroll: $45,136.99 -2. Contractor expenses: $9,978.19 -3. Taxes: $6,356.05 -4. Legal & accounting fees: $2,793.00 -5. Travel (conferences): $2,792.66 -6. Conference fees: $1,345.00 -7. Other (mail, marketing, insurance, government fees, web hosting): $2,100.25 - -#### Revenue Sources: -1. Google: $6,700.00 -2. Donations\*\*: $786.05 -3. Interest (US Bank checking account): $350.57 -4. Bonfire merchandise sales: $36.24 - -\*\*Note: We use the cash accounting method. Donations sent in 2024 but not deposited until 2025 are not reflected here. - -### In-Kind Donations - -In addition to financial income, we received **$8,000 in AWS Open Source Credits** in Fall 2024, which we plan to use to test the tools developed during GSoC. - ---- - -## Membership - -In 2024, we made one significant change to how membership is maintained. In preparation for our annual election, we required community members to reapply for membership to ensure active participation, as our [bylaws](https://wiki.sugarlabs.org/go/Sugar_Labs/Governance) require a majority vote from members for some decisions. - -Aside from this participation requirement, the eligibility criteria remain unchanged: - -> "Any 'significant and sustained' contributor to Sugar Labs is eligible for membership... Contributions may be code, documentation, translations, maintenance of project-wide resources, running a Sugar deployment, or other non-trivial activities which benefit Sugar Labs." - -If you're an active contributor — technical or non-technical — we encourage you to [apply for membership](https://wiki.sugarlabs.org/go/Sugar_Labs/Members). Membership gives you the right to vote in board elections and other key decisions. - ---- - -## Election - -Sugar Labs held its annual **Board of Directors election** in 2024. The results, announced on **December 19, 2024**, elected the following three individuals for the 2024–2025 term: - -- **Devin Ulibarri** -- **Sumit Srivastava** -- **Sebastian Silva** - -Learn more about the process and outcomes here: - -- [How to participate in board elections (Nov 8)](https://www.sugarlabs.org/community/2024/11/08/fall-board-elections-how-to-participate/) -- [Elections extension notice (Nov 22)](https://www.sugarlabs.org/community/2024/11/22/elections-extension/) -- [Final election results (Dec 19)](https://www.sugarlabs.org/community/2024/12/19/election-results/) - ---- - -## Management and Board - -In 2024, [Devin Ulibarri was appointed Executive Director](https://www.sugarlabs.org/press/2024/05/08/Sugar-Labs-announces-nonprofit-status-new-executive-director/). Alongside his leadership, our membership also voted in three new board members, as noted in the section above, including one seat that had been previously vacant. \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-03-31-sweet-spot-003.md b/src/constants/MarkdownFiles/posts/2025-03-31-sweet-spot-003.md deleted file mode 100644 index 5115f9ad..00000000 --- a/src/constants/MarkdownFiles/posts/2025-03-31-sweet-spot-003.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: "The Sweet Spot – Issue 003" -excerpt: "Recent news from Sugar Labs including Sugarizer v1.9 release, annual report for 2024, contributor stories, and more community updates." -category: "COMMUNITY NEWS" -date: "2025-03-31" -author: "Devin Ulibarri" -tags: "markdown,parser,test,education,post,aigenerated" ---- -<!-- markdownlint-disable --> - -*Recent news for March 31, 2025* - -Welcome to the third issue of *The Sweet Spot*, a newsletter for Sugar Labs-related news in development, student and teacher work, events, how to get involved, and other related news and information. - -## Contents of this issue - -- Sugarizer v1.9 is available for your device -- Annual report for 2024 -- From beginner to number one on the contributors chart: My open-source journey -- Devin Ulibarri: How Sugar Labs empowers education via FLOSS -- Enhancing Sampler widget with drag and drop -- Sugar Labs is a mentoring organization for GSoC 2025 -- Two new ways to donate: Every.org and Benevity -- My open-source journey with Sugar Labs -- Volunteers wanted -- Upcoming events and meetings -- About Sugar Labs -- Social and communication links -- Back issues of *The Sweet Spot* - ---- - -## Updates - -### Sugarizer v1.9 is available for your device -**March 25, 2025** - -Sugarizer maintainer Lionel Laské has announced a new release of the multi-platform clone to Sugar Learning Platform. This release includes: - -- A new 3D volume activity (developed during GSoC) -- Improved stability -- A new "direct launch" feature to auto-start an activity on Sugarizer launch - -Check out the full details: - [Release notes](https://lists.sugarlabs.org/archive/sugar-devel/2025-March/059881.html) - [Try it live](https://try.sugarizer.org/) - -[youtube: r5yamM5j7rk] - ---- - -### Annual report for 2024 -**March 24, 2025** - -The newly released **Annual Report for 2024** includes highlights of our work in: - -- Software development -- Sugar in classrooms worldwide -- Outreach and conferences -- Preliminary financials - -Read the report: [Annual report – 2024](https://www.sugarlabs.org/community/2025/03/24/annual-report/) - ---- - -### From beginner to #1 on the contributors chart -**March 21, 2025 – by Om Santosh Suneri** - -Om shares his incredible journey from being new to open source to topping the contributors chart for Music Blocks. In his blog, he discusses his contributions, early learnings, and advice to newcomers. - -Read the full article: - [My Open-Source Journey](https://medium.com/@omsuneri/from-beginner-to-1-on-the-contributors-chart-my-open-source-journey-a0c4d07e1818) - ---- - -### 🎓 Devin Ulibarri: How Sugar Labs empowers education via FLOSS -**March 12, 2025 – by Max Roveri** - -In an interview with Linux Professional Institute, Devin Ulibarri dives into: - -- Sugar Labs' mission -- FLO (Free/Libre/Open) values -- Challenges in scaling -- Future goals for growth and mentorship - - [Read the Interview](https://www.lpi.org/blog/2025/03/12/devin-ulibarri-how-sugar-labs-empowers-education-via-floss/) - ---- - -### Enhancing Sampler widget with drag and drop -**March 6, 2025 – by Harshit Verma** - -New contributor Harshit Verma upgraded the Music Blocks Sampler widget. You can now drag and drop sound samples directly into the browser to generate code. - - [Enhancement details](https://musicblocks.net/2025/03/06/enhancing-sampler-widget-with-drag-and-drop-support-to-add-samples-music-blocks/) - ---- - -### Sugar Labs is a mentoring organization for GSoC 2025 -**February 28, 2025** - -Sugar Labs will mentor students in this year's **Google Summer of Code**! - - Explore our project ideas - Submit proposals by **April 8th, 18:00 UTC** - - [Mastodon announcement](https://mastodon.social/@sugar_labs/114083771631725400) - [Project Ideas](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md) - [Mailing List post](https://lists.sugarlabs.org/archive/sugar-devel/2025-March/059892.html) - ---- - -## Volunteers wanted - -We're growing and need **volunteer support** in various areas—tech, outreach, design, documentation, and more. - -If you're curious and committed, email us: [info@sugarlabs.org](mailto:info@sugarlabs.org) - Learn more: [Volunteering at Sugar Labs](https://www.sugarlabs.org/volunteering) - ---- - -## Upcoming events and meetings - -### Special Event -**New website launch party** - April 25, 2025 at 13:00 EDT / 17:00 UTC - [YouTube Stream](https://www.youtube.com/watch?v=v76Mw9wqO6E) - -### Regular Meetings -**Music Blocks Weekly Meetups** - Every Sunday – 7:00 EDT / 11:00 UTC - [Join here](https://meet.jit.si/ResponsibleMasksForecastHastily) - ---- - -## About Sugar Labs - -Sugar Labs® is a US-based 501(c)(3) nonprofit dedicated to creating educational tools that promote technology exploration and learning for youth globally. - -Support our work: [Donate here](https://www.sugarlabs.org/donate/) - ---- - -## Social and Communication Links - -- Bluesky: [@sugarlabs.bsky.social](https://bsky.app/profile/sugarlabs.bsky.social) -- GitHub: [github.com/sugarlabs](https://github.com/sugarlabs) - ---- - -## Back issues of *The Sweet Spot* - -Find this and previous issues at: - [Sugar Labs Community News](https://www.sugarlabs.org/community-news/) diff --git a/src/constants/MarkdownFiles/posts/2025-05-12-Role-of-generative-AI-in-education.md b/src/constants/MarkdownFiles/posts/2025-05-12-Role-of-generative-AI-in-education.md deleted file mode 100644 index b66bdef7..00000000 --- a/src/constants/MarkdownFiles/posts/2025-05-12-Role-of-generative-AI-in-education.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: "Live Session: Role of generative AI in education" -excerpt: "Join us with guest speaker Ken Kahn, PhD for a live session on the role of generative AI in education" -category: "EVENTS" -date: "2025-05-16" -slug: "role-of-generative-ai-education" -author: "Sugar Labs" -description: "Education Nonprofit" -tags: "gen-ai,education,live-session,guest-talk" ---- -<!-- markdownlint-disable --> - -**Join us live with researcher and author Ken Kahn, PhD for a live session on the role of generative AI in education. Watch live on Friday, May 16, 2025 at 13:00 EDT (17:00 UTC).** - -## Event information - -- **Title:** Live Session: Role of generative AI in education -- **Date:** May 16, 2025 -- **Time:** 13:00 EDT (17:00 UTC) -- **Watch Live:** [YouTube Link](https://www.youtube.com/watch?v=nn1jeQgKTOA) -- **Platform:** [Sugar Labs YouTube Channel](https://www.youtube.com/@SugarlabsOrg-EN/streams) - -## About Sugar Labs - -Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a global mission to create educational opportunities in technology to youth around the world. Volunteer mentors and contributors work together to develop activity-focused software for children. All software is developed with learning as the primary goal, necessitating the need for source code to be published publicly for study, licensed under a free/libre license for explicit permission to share and remix, and openly worked upon within a community where students are invited to make contributions, under guidance of experienced mentors. - -Support our work: [Donate here](https://www.sugarlabs.org/donate/) diff --git a/src/constants/MarkdownFiles/posts/2025-05-20-JSeditor-updates.md b/src/constants/MarkdownFiles/posts/2025-05-20-JSeditor-updates.md deleted file mode 100644 index 4ae4cc61..00000000 --- a/src/constants/MarkdownFiles/posts/2025-05-20-JSeditor-updates.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "JavaScript Editor Updates and Future Features" -excerpt: "Overview of changes being made to the JavaScript editor tool in MusicBlocks v3, and future plans" -category: "DEVELOPER NEWS" -date: "2025-05-20" -slug: "JSeditor-updates" -author: "@/constants/MarkdownFiles/authors/elwin-li.md" -description: "GSoC Contributor" -tags: "gsoc, javaScript editor, development, contribution, debugger" ---- - -This is the first update report on the MusicBlocks JavaScript editor enhancement project for -GSoC 2025. This and future reports will discuss the progress and future plans for the improvement -of user experience and features for the editor. - -## Contents -- Upcoming Features -- Motivation -- JavaScript to Music Blocks -- Debugger -- Syntax highlighting - ---- - -### Upcoming Features -This project aims to significantly enhance the JavaScript editor within Sugar Labs' -MusicBlocks environment. By implementing translation from JavaScript code to -MusicBlocks visual blocks, users will gain a powerful tool for iterative learning and code -exploration. Additionally, the project will introduce a JavaScript visualizer for step-by-step -debugging and syntax highlighting to improve the editor's usability and appeal to young -learners. This upgrade will bridge the gap between visual programming and text-based coding, -promoting a deeper understanding of real programming and empowering kids to debug -effectively. - -### Motivation -I believe that kids cannot learn to -code without coding. Although they can learn the concept of coding through MusicBlocks, they -still cannot learn text-based coding effectively. The JavaScript-to-MusicBlocks conversion feature -will enable them to better transition between visual block-based programming and -textual JavaScript coding. This promotes a deeper understanding of programming concepts and -has kids learn them more effectively. - -Even more important than learning how to code is learning how to problem solve. Debugging and -problem solving skills provide kids with the knowledge to overcome problems of any kind, not -just in programming. With the step by step debugger, kids will learn how to break a problem down, and -identify where problems are and track them. - -### JavaScript to Music Blocks -The JavaScript to Music Blocks feature is fairly simple as an end product: implementing the ability -for users to convert the JavaScript code in the editor to music blocks. The execution of this feature -is less simple. Currently, I have implemented support for all blocks from the rhythm, flow, number, and boolean palettes. There is also support for a few blocks from the pitch, tone, and action palettes. These implementations can be seen with the [first PR](https://github.com/sugarlabs/musicblocks/pull/4591) and the [second PR](https://github.com/sugarlabs/musicblocks/pull/4692). - -This was all done using the following process: - -1. Using the [acorn parser library](https://github.com/acornjs/acorn), convert the input code by the user in the editor into an -[**Abstract Syntax Tree**](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (AST) -2. Convert the AST into a custom intermediate representation - - In this case, it is a simpler tree consisting of all the different blocks that the code creates - - For each block in the intermediate tree, there is information on its type, arguments, children, and/or value if it has one -3. Convert the intermediate tree into a blocklist - - MusicBlocks generate blocks using the representation of a list of blocks, which are mostly in the form of - [id, name, x, y, [connections]] - - Carefully parsing through the intermediate tree and dealing with the connections produce a list of such blocks, - which MusicBlocks will then load into the visual programming blocks - - The connections are made during the process of creating the blocks. - - For each block, if it has arguments, they will be created and connected with the block - - Then its children are created and connected to each other - - Finally the first child is then connected back to the block itself - - During this process, vertical sizes of arguments are kept track of to insert the necessary amount of vertical spacers before the children - -Although this process is proven to work very well as shown by the [merged PR](https://github.com/sugarlabs/musicblocks/pull/4591), -adding future blocks is not yet as simple as it can be. - -Thus, I am currently working on refactoring the code to use JSON config files to store pairs of AST to block mappings, which would -make adding new blocks an extremely quick and trivial process. The next report may go into more details on this. - -### Debugger -The JavaScript editor debugger will be a tool located as a separate tab within the console space. I plan on implementing this tool as part of GSoC this summer. Although currently unavailable, I have created a simple design as to what it may look like. - - -The debugger will have the following functionalities: - - Ability to set one or multiple breakpoints - - Have the state of all variables at breakpoints - - Show function call frames - - User can run program all the way to the next breakpoint (stops in order until user goes to next one) - - User can step forward line by line or evaluate by unit - -### Syntax Highlighting -A good IDE or code editor will always have syntax highlighting. This makes the environment easier and more fun to work with. Thus, -this feature will also be added to the JavaScript editor in MusicBlocks. Although this also has not been implemented yet, I foresee this -part of the project being the fastest, as there are many established libraries that can provide syntax highlighting. Some candidates may include highlight.js, and CodeJar. - ---- - -This concludes the first report on the MusicBlocks JavaScript editor enhancement project for GSoC 2025. Thanks for reading, and more updates will come soon! \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-05-25-gsoc-25-AdityaKrSingh26-week01.md b/src/constants/MarkdownFiles/posts/2025-05-25-gsoc-25-AdityaKrSingh26-week01.md deleted file mode 100644 index 5ef9812e..00000000 --- a/src/constants/MarkdownFiles/posts/2025-05-25-gsoc-25-AdityaKrSingh26-week01.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: "GSoC ’25 Week 01 Update by Aditya Kumar Singh" -excerpt: "Refining human anatomy models and improving Sugarizer’s 3D Human Activity" -category: "DEVELOPER NEWS" -date: "2025-05-28" -slug: "2025-05-28-gsoc-25-AdityaKrSingh26-week01" -author: "@/constants/MarkdownFiles/authors/aditya-singh.md" -description: "GSoC'25 Contributor at SugarLabs (Sugarizer Human Activity Pack)" -tags: "gsoc25,sugarlabs,week01,AdityaKrSingh26" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Aditya Kumar Singh - -**Project:** [Sugarizer](https://github.com/llaske/sugarizer) -**Mentors:** [Lionel Laské](https://github.com/llaske) -**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) -**Reporting Period:** 2025-05-12 - 2025-05-18 - ---- - -## Goals for This Week - -- **Goal 1:** Identify missing human body assets in the current execution. -- **Goal 2:** Simplify models and increase spacing between organs. -- **Goal 3:** Remove redundant code from the current codebase and improve structure. - ---- - -## This Week’s Achievements - -1. **Identify missing human body assets in the current execution** - - Reviewed current assets and mapped out missing organs and systems (e.g., stomach, intestines, food pipe, kidneys, liver, eyes, brain, etc). - - This helps ensure educational completeness and anatomical accuracy for users. - -2. **Simplify Z-Anatomy models and increase spacing between organs** - - Removed mesh clutter and enhanced spacing between vital organs like heart, lungs, liver to improve visibility and user interaction. - - This change is aimed at improving user experience, especially on touch devices. -  -  - - -3. **Remove redundant code from the current codebase and improve structure** - - Removed redundant or deprecated functions, improved file modularity, and standardized naming across `activities\HumanBody.activity\js\activity.js`. - - Resolved duplicate `loader.load()` usage: Consolidated the skeleton model loading logic into a reusable function and invoked it from both `env.getEnvironment` and `onNetworkDataReceived`, removing redundancy. - - Optimized `env.getEnvironment` call: Now invoked only once and the result is reused where needed - - Unified zoom functions: Replaced `zoomInFunction`, `zoomOutFunction`, `zoomEqualFunction`, and `zoomToFunction` with a single parameterized `zoomCamera(type, targetFOV)` function to streamline logic. - - Links : PR [#1794](https://github.com/llaske/sugarizer/pull/1794). - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Code duplication across multiple model load functions and zoom handlers. - **Solution:** Abstracted the model loading into one reusable function to reduce maintenance overhead. Similarly, created a generalized zoom function with parameters for FOV and zoom type to replace multiple similar methods. - -- **Challenge:** Finding suitable 3D models with the right level of mesh detail. - **Solution:** Spent time evaluating and testing various anatomy models and 3D datasets. Balanced between model quality and performance ensuring the mesh was detailed enough for educational use but light enough for smooth rendering in Sugarizer’s environment. - ---- - -## Key Learnings - -- Got hands-on with **3D modeling tools like Blender** for optimization and export for web use. -- Understood modular design and best practices for maintaining scalable code in large open-source projects. - ---- - -## Next Week’s Roadmap - -- Refine the 3D models ,remove and merge unecessary parts. -- Integrate Organs 3D models for the basic paint activity. -- Import and test Human Body model for visual alignment. - ---- - - -## Resources & References - -- **Repository:** [github.com/AdityaKrSingh26/sugarizer](https://github.com/AdityaKrSingh26/sugarizer) -- **3D models used:** - - "Human" (https://skfb.ly/6Z8LI) by aaron.kalvin, - - "Realistic Human Lungs" (https://skfb.ly/oBDWI) by neshallads, - - "Human heart, realistic anatomical model" (https://skfb.ly/oXBxZ) by 3d Eye Catcher, - - "human-brain" (https://skfb.ly/6YqDO) by Yash_Dandavate, - - Organs by Z-Anatomy (https://github.com/LluisV/Z-Anatomy) - - ---- - - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - -## Connect with Me - -- GitHub: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) -- Gmail: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) -- LinkedIn: [Aditya Kumar Singh](https://www.linkedin.com/in/adityakrsingh26/) -- Twitter: [@AdityaKrSingh26](https://x.com/AdityaKrSingh26) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-01-gsoc-25-AdityaKrSingh26-week02.md b/src/constants/MarkdownFiles/posts/2025-06-01-gsoc-25-AdityaKrSingh26-week02.md deleted file mode 100644 index d6a5e4ad..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-01-gsoc-25-AdityaKrSingh26-week02.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: "GSoC ’25 Week 02 Update by Aditya Kumar Singh" -excerpt: "Merging anatomical models and enhancing Sugarizer’s Human Body Activity" -category: "DEVELOPER NEWS" -date: "2025-05-29" -slug: "2025-05-29-gsoc-25-AdityaKrSingh26-week02" -author: "@/constants/MarkdownFiles/authors/aditya-singh.md" -description: "GSoC'25 Contributor at SugarLabs (Sugarizer Human Activity Pack)" -tags: "gsoc25,sugarlabs,week02,AdityaKrSingh26" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 02 Progress Report by Aditya Kumar Singh - -**Project:** [Sugarizer](https://github.com/llaske/sugarizer) -**Mentors:** [Lionel Laské](https://github.com/llaske) -**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) -**Reporting Period:** 2025-05-19 - 2025-05-22 - ---- - -## Goals for This Week - -- **Goal 1:** Merge required segmented models into a single unified mesh. -- **Goal 2:** Integrate 3D organ models required for the initial version of the paint activity. -- **Goal 3:** Refactor and clean up code to improve maintainability of the Human Body Activity. -- **Goal 4:** Import and test a Human body model. - ---- - -## This Week’s Achievements - -1. **Merged intestine models into a single mesh** - - Used Blender to unify multiple intestine segments into a single watertight mesh. - - Simplified mesh topology while preserving anatomical details for better performance in-browser. -  -  - - -2. **Integrated 3D organ models for the basic paint activity** - - Selected essential models: heart, brain, lungs, and kidneys. - - Positioned and scaled them within the scene for the interactive paint activity. - - Confirmed interactivity through raycasting and model selection using three.js. -  -  - - -3. **Refactored and cleaned up existing code for Human Body Activity** - - Improved component structure and naming conventions in `activity.js`. - - PR merged: PR [#1794](https://github.com/llaske/sugarizer/pull/1794). - -4. **Imported and tested a Human body model** - - Imported an external Human body model and tested visual alignment. - - Adjusted scale, rotation, and pivot points in Blender. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Organs weren’t interacting properly in the paint activity due to non-unified object hierarchies. - **Solution:** Used grouping and bounding box checks to establish correct hit detection zones. Re-anchored object origins for each model. - ---- - -## Key Learnings - -- Improved skills in 3D mesh merging. -- Learned how to optimize **paintable 3D object interactions** within a browser canvas. -- Gained experience in **codebase refactoring for open-source projects** to enhance maintainability. - - ---- - -## Next Week’s Roadmap - -- Create a `credits.md` file to document and attribute all third-party 3D models used, following proper open-source licensing guidelines. -- Integrate additional organ models into paint mode to enrich the educational interactivity. -- Bisect the human body model into appropriate anatomical sections (e.g., upper/lower torso, head, limbs) for easier interaction and labeling. -- (Optional) Begin integrating the full human body model into paint mode, allowing users to interact with and label the complete anatomy structure. - - ---- - - -## Resources & References - -- **Repository:** [github.com/AdityaKrSingh26/sugarizer](https://github.com/AdityaKrSingh26/sugarizer) -- **3D models used:** - - “Z-Anatomy Human Body” (https://github.com/LluisV/Z-Anatomy) - - "Human" (https://skfb.ly/6Z8LI) by aaron.kalvin. - - Human Heart ,Lungs, etc from Sketchfab (refer Week 01 for links) - - ---- - - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - -## Connect with Me - -- GitHub: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) -- Gmail: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) -- LinkedIn: [Aditya Kumar Singh](https://www.linkedin.com/in/adityakrsingh26/) -- Twitter: [@AdityaKrSingh26](https://x.com/AdityaKrSingh26) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-07-gsoc-25-Elwin-Li-week01.md b/src/constants/MarkdownFiles/posts/2025-06-07-gsoc-25-Elwin-Li-week01.md deleted file mode 100644 index 9033f548..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-07-gsoc-25-Elwin-Li-week01.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: "GSoC '25 Week 1 Update by Elwin Li" -excerpt: "Weekly progress report for JSEditor updates" -category: "DEVELOPER NEWS" -date: "2025-06-07" -slug: "2025-06-07-gsoc-25-Elwin-Li-week01" -author: "@/constants/MarkdownFiles/authors/elwin-li.md" -description: "GSoC Contributor" -tags: "gsoc25,sugarlabs,week1,javaScript editor" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 1 Progress Report by Elwin Li - -**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/gsoc-2025/elwin) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) - -**Reporting Period:** 2025-06-02 - 2025-06-07 - ---- - -## Goals for This Week - -- **Goal:** Complete and deploy code to blocks functionality. - ---- - -## This Week’s Achievements - -**Refactored code to be config driven** -I refactored my code for code to block conversion to use a JSON config file so that the logic behind the conversion is as generic as possible. -An example config for a block is shown below: - - { - "name": "repeat", - "comments": "Repeat block in the Flow palette", - "arguments": [ - { - "type": "NumberExpression" - } - ], - "ast": { - "identifiers": [ - { - "property": "type", - "value": "ForStatement" - } - ], - "argument_properties": [ - "test.right" - ], - "children_properties": [ - "body.body" - ] - }, - "blocklist_connections": [ - "parent_or_previous_sibling", - "argument", - "first_child", - "next_sibling" - ], - "default_vspaces": { - "argument": 1 - } - } - -This config is for the repeat block, as conveniently stated in the comments section for readability. -There are several pieces of information we need for a block for the conversion code to work: -- The name of the block -- The number of arguments, and their types -- The associated AST information - - The identifiers, or the path to that block (needed for matching) - - The paths to the argument and children properties from the AST -- The connections the block has in the blocklist [parent/previous sibling, argument(s), child(ren), next sibling] -- vspace information - -Based on these pieces of information, the conversion code is generic enough to parse through and translate into blocklist format. -This is very important because this means that adding a new block for support is now as simple as adding a config like this to the JSON file. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Coming up with the config format. - - **Solution:** Lots of trial and error, and using many different examples to make the code generic. - -- **Challenge:** Argument handling was not working with configuration. - - **Solution:** Added a separate section in the config file for argument blocks, but made it as close to other blocks as possible. - ---- - -## Key Learnings - -- Deepened understanding of JSON configuration files. -- Improved skills in **debugging**, **code design**, and **collaboration workflows**. - ---- - -## Next Week’s Roadmap - -- Fully add all blocks that we want to support for code to block conversion, with corresponding documentation and error handling. -- Move on to next phase of the JSeditor project, which is the debugger -- Familiarize myself with the necessary files I will need to work with for the debugger -- Work on getting breakpoints to work - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - -## Connect with Me - -- GitHub: [@ebeetles](https://github.com/ebeetles) -- Gmail: [elwin.s.li@gmail.com](mailto:elwin.s.li@gmail.com) -- LinkedIn: [Elwin Li](https://www.linkedin.com/in/elwinsli/) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-AmanNaik-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-AmanNaik-week01.md deleted file mode 100644 index 019578b9..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-AmanNaik-week01.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: "DMP ’25 Week 1 Update by Aman Naik" -excerpt: "This week's focus was exploring the write-activity codebase, finding appropriate grammar correction models & understanding Abiword documentations." -category: "DEVELOPER NEWS" -date: "2025-06-08" -slug: "2025-06-08-dmp-25-AmanNaik-week01" -author: "@/constants/MarkdownFiles/authors/amannaik247.md" -description: "Member and DMP'25 Contributor at SugarLabs" -tags: "dmp25,writeactivity,write,sugarlabs,week01,amannaik247" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 1 Progress Report by Aman Naik - -**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) -**Reporting Period:** 2025-06-02 - 2025-06-08 - ---- - -## Goals for This Week - -- **Goal 1:** Understand write activity's codebase. -- **Goal 2:** Explore pertinent grammar correction models for real time grammar correction -- **Goal 3:** Understand the [Abiword](https://github.com/AbiWord) word-processor documentation - ---- - -## This Week’s Achievements - -1. **Understood the activity's codebase** - - Gained a clear understanding of the overall structure and logic of the Write activity's codebase. - - This includes identifying key components, data flow, and how the Abiword processor is leveraged for this activity. -2. **Explored pertinent grammar correction models** - - Shortlisted grammar correction models suitable for real time grammar correction and can be used with an open source software. - - Created API endpoints using Hugging Face spaces for quick testing in sugar. - -3. **Understood the Abiword processor** - - Abiword is an open source word processor, which is leveraged by the write activity. - - It has a parser called 'link-grammar' that was recently developed, which might be useful for grammar correction as well. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Difficulty in finding reliable grammar correction models on hugging face which can also be compatible open source software. -**Solution:** Found link-grammar that could be an option for reliable grammar correction feature. Also, found some hugging face models(relevant license) after rigorously searching. - -- **Challenge:** Testing hugging face models with no inference points and testing them inside Sugar. -**Solution:** Most Hugging Face models can’t be installed directly in Sugar because they require heavy dependencies like Torch and Transformers, which increase memory usage in a virtual machine. Therefore, I used hugging face spaces and ran the models there, which also provides API endpoints for quick testing inside Sugar. - ---- - -## Key Learnings - -- Gained a solid understanding of the Write activity's code structure and how it integrates the Abiword processor. -- Explored lightweight, open-source grammar correction models and successfully tested them using Hugging Face Spaces via API endpoints. -- Discovered that Abiword’s link-grammar parser might be leveraged for native grammar correction within the activity. - ---- - -## Next Week’s Roadmap - -- Finalise a grammar correction model and fine tune it if needed -- Create a FastAPI endpoint and upload the selected model on AWS for testing -- Integrate grammar correction into write-activity -- Explore better spelling correction models - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! - ---- - -## Connect with Me - -- GitHub: [@amannaik247](https://github.com/amannaik247) -- Gmail: [amancodes247@gmail.com](mailto:amancodes247@gmail.com) -- LinkedIn: [Aman Naik](https://www.linkedin.com/in/aman-naik/) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-AnvitaPrasad-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-AnvitaPrasad-week01.md deleted file mode 100644 index e4b88ea3..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-AnvitaPrasad-week01.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: "DMP '25 Week 01 Update by Anvita Prasad" -excerpt: "Improving Synth and Sample Features in Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-06-08" -slug: "2025-06-08-dmp-25-AnvitaPrasad-week01" -author: "Anvita Prasad" -description: "DMP'25 Contributor at SugarLabs (Music Blocks)" -tags: "dmp25,sugarlabs,week01,AnvitaPrasad" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Anvita Prasad - -**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) -**Mentors:** [Walter Bender](https://github.com/walterbender) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-02 - 2025-06-08 - ---- - -## Goals for This Week -- **Goal 1:** Update Tone.js to the latest version -- **Goal 2:** Begin tuner implementation with pitch detection -- **Goal 3:** Create basic tuner visualization - ---- - -## This Week's Achievements -1. **Updated Tone.js Library** - - Successfully upgraded from version 15.0.4 to 15.1.22 - - Verified compatibility with existing codebase - -2. **Implemented Pitch Detection** - - Integrated YIN algorithm for pitch detection - - Established foundation for note identification - -3. **Created Basic Tuner Interface** - - Implemented 11-segment tuner display - - Added initial cents adjustment UI - ---- - -## Key Learnings -- Gained familiarity with Tone.js API and audio processing -- Learned about pitch detection algorithms and their implementation - ---- - -## Next Week's Roadmap -- Complete tuner implementation with accurate visualization -- Implement cents adjustment calculations -- Add fine-tuning to pitch detection system -- Test with various audio sources -- Write Week 02 blog post summarizing progress and learnings - ---- - -## Acknowledgments -Thank you to my mentors, the Sugar Labs community, and fellow DMP contributors for ongoing support. Had a productive meeting with mentors this week to discuss the implementation approach. - ---- - -## Connect with Me -- GitHub: [@AnvitaPrasad](https://github.com/AnvitaPrasad) -- Email: [anvita.prasad1@gmail.com](mailto:anvita.prasad1@gmail.com) -- LinkedIn: [Anvita Prasad](https://www.linkedin.com/in/anvita-prasad) diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-justin212407-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-justin212407-week01.md deleted file mode 100644 index 743d10dd..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-justin212407-week01.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: "DMP ’25 Week 01 Update by Justin Charles" -excerpt: "Week 01 focused on understanding and creating the path file to render the outlines for the SVG Paths for different brick types." -category: "DEVELOPER NEWS" -date: "2025-06-09" -slug: "2025-06-09-dmp-25-justin212407-week01" -author: "Justin Charles" -description: "Member and DMP'25 Contributor at SugarLabs" -tags: "dmp25,sugarlabs,week01,justin212407" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Justin Charles - -**Project:** [Music Blocks 4 Masonry Module](https://github.com/sugarlabs/musicblocks-v4/issues/430) -**Mentors:** [Anindya Kundu](https://github.com/meganindya/) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/), [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-02 - 2025-06-08 - ---- - -## Goals for This Week - -- **Goal 1:** Figure out the constants required for building the outline of the different brick SVGs. -- **Goal 2:** Find out formulae for creation of dynamic parts for the creation of the brick outlines. -- **Goal 3:** Creating functions for rendering different brick types given a set of parameters. - ---- - -## This Week’s Achievements - -1. **Identified core constants for SVG brick outlines** - - Analyzed existing functions to extract constants and segment lengths. - - Documented fixed edge sizes and arc parameters required for rendering base brick structure. Here is the doc regarding the same - https://docs.google.com/document/d/1AUlA2leDJIfV3ZXceLhCaITftExq6c5BcUBMZOtZBvE/edit?usp=sharing -2. **Derived dynamic formulae for brick segments** - - Broke down SVG path logic to understand variable-dependent segments (e.g., based on presence of notches or arguments). - - Reverse-engineered svg paths into configurable logic blocks. - -3. **Implemented param-based render logic for brick types** - - Created functions to output valid SVG paths. - - Ensured functions deliver the correct kind of brick based on the parameters given to it. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Understanding how fixed and dynamic SVG path parts interac - **Solution:** Visually inspected path output, compared it to expected segments, and mapped patterns to conditional logic. - -- **Challenge:** Ensuring proper rendering across all brick types - **Solution:** Used example bricks for side-by-side validation; gradually modularized logic to support extensibility. - ---- - -## Key Learnings - -- Gained clarity on **brick geometry constants** and their significance in SVG construction. -- Improved ability to **translate SVG paths into conditional logic functions**. -- Strengthened understanding of **segment chaining**, **arc-to-curve translations**, and **parametric shape rendering**. - ---- - -## Next Week’s Roadmap - -- Complete the path file to begin rendering bricks dynamically via input-driven SVG generation. -- Create React components for different brick types. -- Collaborate with mentors to refine design and implementation plans. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! - ---- - -## Connect with Me - -- GitHub: [@justin212407](https://github.com/justin212407) -- Gmail: [charlesjustin2124@gmail.com](mailto:charlesjustin2124@gmail.com) -- LinkedIn: [Justin Charles](https://www.linkedin.com/in/justin-c-663840297/) diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-therealharshit-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-therealharshit-week01.md deleted file mode 100644 index 7b90123d..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-dmp-25-therealharshit-week01.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: "DMP ’25 Week 01 Update by Harshit Verma" -excerpt: "Week 01 focused on understanding the Pippy codebase, testing Sugar-AI endpoints, and evaluating AI models for the debugger." -category: "DEVELOPER NEWS" -date: "2025-06-09" -slug: "2025-06-09-dmp-25-therealharshit-week01" -author: "@/constants/MarkdownFiles/authors/harshit-verma.md" -tags: "dmp25,sugarlabs,week01,therealharshit" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Harshit Verma - -**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-02 - 2025-06-08 - ---- - -## Goals for This Week - -- **Goal 1:** Study Pippy codebase. -- **Goal 2:** Explore Sugar AI and test its endpoints. -- **Goal 3:** Research suitable AI models for debugging. - ---- - -## This Week’s Achievements - -1. **Studied the Pippy codebase** - - Spent time navigating through the Pippy repository to understand how activities are structured and how debugging might integrate. - - Cloned and set up the development environment locally to test and experiment changes. -2. **Tested Sugar-AI API endpoints** - - Successfully ran the FastAPI server and tested endpoints like /ask and /ask-llm. - - Validated the flow from input to model response, which sets the stage for integrating custom prompts and debugging logic. - -3. **Evaluated model options for Pippy Debugger** - - Tested Codellama and Mistral locally using Ollama, which provided quick setup and testing on my local machine. - - After discussing with my mentor, I’ve shifted focus to using models directly from Hugging Face, as it aligns better with our deployment plans and integration goals. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Understanding the Pippy codebase and its dependencies. - **Solution:** Followed documentation and explored Sugar Labs learning resources. Used Ubuntu in a virtual machine to setup sugar desktop. - -- **Challenge:** Running Sugar AI locally to test endpoints. - **Solution:** Followed the documentation to run the sever but the default model was taking too long to download so I changed it to a smaller model. - ---- - -## Key Learnings - -- Gained familiarity with the **Pippy codebase and its structure.**. -- Learned to work with **FastAPI**, **Linux** and **Virtual Machine**. -- Developed better understanding of **LLM system requirements**, **quantization**, and **local model serving**. - ---- - -## Next Week’s Roadmap - -- Create a basic FastAPI server **(/debug endpoint)** that accepts Python code and suggests debugging steps. -- Integrate the **selected LLM** to respond to debugging prompts. -- Collaborate with mentors to refine design and implementation plans. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-AdityaKrSingh26-week03.md b/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-AdityaKrSingh26-week03.md deleted file mode 100644 index 46f8b4c0..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-AdityaKrSingh26-week03.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "GSoC ’25 Week 03 Update by Aditya Kumar Singh" -excerpt: "Organ integration, anatomical bisection, and open-source attributions in Sugarizer's Human Body Activity" -category: "DEVELOPER NEWS" -date: "2025-06-02" -slug: "2025-06-02-gsoc-25-AdityaKrSingh26-week03" -author: "@/constants/MarkdownFiles/authors/aditya-singh.md" -description: "GSoC'25 Contributor at SugarLabs (Sugarizer Human Activity Pack)" -tags: "gsoc25,sugarlabs,week03,AdityaKrSingh26" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 03 Progress Report by Aditya Kumar Singh - -**Project:** [Sugarizer](https://github.com/llaske/sugarizer) -**Mentors:** [Lionel Laské](https://github.com/llaske) -**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) -**Reporting Period:** 2025-05-23 - 2025-05-29 - ---- - -## Goals for This Week - -- **Goal 1:** Create a **credits.md** file to attribute and list licenses for all 3D assets used. -- **Goal 2:** Integrate organ models into the interactive paint mode. -- **Goal 3:** Bisect the full human body model into meaningful anatomical sections using Blender. -- **Goal 4:** Time-permitting, begin integration of the bisected full-body model into paint mode. - - ---- - -## This Week’s Achievements - -1. **Created credits.md file for 3D model attribution** - - Documented sources, authors, and licenses for each 3D model used in the activity. - - Ensured compliance with open-source licensing (CC, GPL, etc.) where applicable. - - -2. **Integrated additional organ models into paint mode** - - Added 3D human organs model containing: stomach, liver, intestines, etc to the interactive paint activity. - - Verified clickable regions and ensured raycasting targets are accurate and intuitive. - - Updated model hierarchy for smoother interactivity and better scene management. - - Refactored the existing click handler for better mesh selection using **screen-space testing**. -  - - -3. **Bisected full human body model into anatomical sections** - - Used Blender’s Bisect tool to separate the full mesh into functional regions: head, torso, arms, and legs. - - Cleaned geometry to avoid overlapping or orphaned faces. - - Exported and tested the segmented meshes in the Three.js scene. -  -  -  - - -4. **(Bonus) Partial integration of bisected model into paint mode** - - Imported segmented torso and head into paint mode as a pilot test. - - Validated paint interactions on new sections to ensure consistency. -  - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Bisecting the human body mesh led to artifacts and unclean separations. - **Solution:** Used high-precision knife and cleanup tools in Blender and manually adjusted vertex groups. - ---- - -## Key Learnings - -- Improved proficiency with Blender’s mesh slicing and cleanup tools. -- Learned proper practices for open-source asset attribution. - ---- - -## Next Week’s Roadmap - -- Write Weekly Blog Post summarizing progress, screenshots, and key learnings from Week 03. -- Implement a model selection palette that allows users to toggle between different anatomical models (e.g., organs, skeleton, full body). -- Integrate the full human body model into the paint activity to allow direct interaction and labeling across complete anatomy. -- Rename labels in the skeleton model to reflect accurate anatomical terminology and improve educational clarity. -- Add localization support for the 3D Human Body Activity to make it accessible in multiple languages. - - ---- - - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - -## Connect with Me - -- GitHub: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) -- Gmail: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) -- LinkedIn: [Aditya Kumar Singh](https://www.linkedin.com/in/adityakrsingh26/) -- Twitter: [@AdityaKrSingh26](https://x.com/AdityaKrSingh26) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-BishoyWadea-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-BishoyWadea-week01.md deleted file mode 100644 index 9533255f..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-BishoyWadea-week01.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: "GSoC ’25 Week 01 Update by Bishoy Wadea" -excerpt: "Bonding and Four Color Map puzzle" -category: "DEVELOPER NEWS" -date: "2025-06-07" -slug: "2025-06-07-gsoc-25-BishoyWadea-week01" -author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" -tags: "gsoc25,sugarlabs,week01,BishoyWadea" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Bishoy Wadea - -**Project:** [Four Color Map Puzzle](https://github.com/Bishoywadea/Four-Color-Map) -**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) -**Reporting Period:** 2025-06-01 - 2025-06-07 - ---- - -## Goals for This Week - -- **Goal 1:** Define game features and core mechanics. -- **Goal 2:** Design and plan a child-friendly, interactive game UI. -- **Goal 3:** Implement the core game logic for map coloring and rule enforcement. - ---- - -## This Week’s Achievements - -1. **Initial Game Implementation** - - Implemented the basic game loop, event handling, and win condition detection. This created the foundation for gameplay. - - Added support for checking that no two adjacent regions have the same color. - - commit: [Gameplay Base](https://github.com/Bishoywadea/Four-Color-Map/commit/91eabce38439fc08da652d1de309b556393fcee3) - -2. **UI Enhancements & Interaction Features** - - Designed and integrated colorful buttons, icons, and zoom functionalities to make the UI more appealing to children. - - Added menu navigation for selecting countries and levels. - - Added Undo, Erase, and Help buttons for better usability. - - commit: [UI Enhancment](https://github.com/Bishoywadea/Four-Color-Map/commit/4fe1c755c47696cc20e6dd757190ed1f3df98717) - -3. **Map Data Integration** - - Generated and added regional map data for Egypt, US, Nigeria, and India. - - Developed a script to convert GeoJSON files into game-ready polygon data. - - Screenshot of gameplay: - commit: [Data Integration](https://github.com/Bishoywadea/Four-Color-Map/commit/de018722d2d32d3ebd40429f8e59e1793cd34e9c) - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Generating accurate and clean polygon data from raw GeoJSON files. - **Solution:** Wrote a custom Python script to extract, simplify, and format the regions into usable coordinates while preserving geographical structure. - -- **Challenge:** Preventing adjacent regions from being colored the same. - **Solution:** Implemented an adjacency-check function that verifies constraints during each coloring action. - ---- - -## Key Learnings - -- Gained proficiency in using **Pygame** for interactive game development. -- Improved understanding of **map projections** and **GeoJSON** parsing. -- Learned about structuring a project for open-source collaboration (commits, PRs, README, file organization). -- Practiced test-driven logic development and clean UI design tailored for children. - ---- - -## Next Week’s Roadmap - -- Checking if any bugs appears -- develop broken calculator game - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for the warm support and constant feedback during this bonding period. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-FirePheonix-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-FirePheonix-week01.md deleted file mode 100644 index f796118a..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-FirePheonix-week01.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "GSoC ’25 Week 01 Update by Shubham Singh" -excerpt: "Creating UIs and visuals for addition of Lego Bricks " -category: "DEVELOPER NEWS" -date: "2025-06-07" -slug: "2025-06-07-gsoc-25-FirePheonix-week01" -author: "Shubham Singh" -description: "Maintainer and GSoC'25 Contributor at SugarLabs" -tags: "gsoc25,sugarlabs,week01,FirePheonix" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Shubham Singh - -**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) -**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-06-01 - 2025-06-07 - ---- - -## Goals for This Week - -- **Goal 1:** Basic UI for Image Upload/Real time Video upload and adjust. -- **Goal 2:** Putting the developed UIs onto the widget blocks. -- **Goal 3:** Searching for exisiting audios in the phrase maker and note blocks. - ---- - -## This Week’s Achievements - -1. **Interface for Image upload for Lego Notations** - - Music Blocks has a feature to detect the color of pixels generated from drawing within the program, but it cannot detect the color of pixels from images that are either uploaded or from a webcam. - - By adding a feature to detect color from both uploaded images and a live webcam stream, users would be able to implement Lego music notation for the blind and similarly interactive programs. - -  - - -2. **Live webcam feed and editing options** - - The following feature helps to use a real time video(webcam) onto the Lego Notation detection interface. Also, you may freely edit and move it around the canvas. -  - - - Here's the reference video regarding lego bricks as musical notes: - [youtube: LOfrCPf3XJU] - - - Here's Devin's CMK project for color sensor project in music blocks: - [Reflections from constructing modern knowledge](https://medium.com/@sugarlabs/reflections-from-constructing-modern-knowledge-2024-1ce7d60fbb1c) - -3. **Identified methods to making a new widget block in music blocks** - - I read and went through a lot of documentation, searching for how we can add a new widget block in music blocks. I figured out a few flaws and how can the documentation be improved for future contributors. -  - - From what I've realized working on it, for adding a new block on the music blocks, I definitely think that for adding a new block, a lot of the code - UIs, features, etc. would already exist and you can just inherit those exisiting classes. And also, you'll have to edit and change a LOT of files and add new methods for your own new block. -  - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Getting started on features and UIs with a lot of doubts about how it should look like. -- **Solution:** Consulting my mentors, presenting variations of "How it could be" to them, refering to EXISTING UIs in Music Blocks. - ---- - -## Key Learnings - -- Gained familiarity with **making new blocks**. -- Deepened understanding of **inheritance and code modularity** -- Improved skills in **exports, imports, code reusability**, **documentation**, and **collaboration workflows**. - ---- - -## Next Week’s Roadmap - -- Implement **mapping of musical notes to lego bricks' colors**. -- Refine **UIs** based on mentor feedback. -- Inherit the exisiting code inside **WidgetBlocks.js** code as UI. -- Target: Completing the **core implementation** in the week number 2 and 3. - ---- - -## Acknowledgments - -Thanks to some old pull requests and documentation available in music blocks, I was able to figure out on a lot about how new blocks are created on the music blocks interface. Will definitely add on more. - ---- - -## Connect with Me - -- GitHub: [@FirePheonix](https://github.com/FirePheonix) -- Gmail: [shubhsoch@gmail.com](mailto:shubhsoch@gmail.com) -- LinkedIn: [Shubham Singh](https://www.linkedin.com/in/shubham-singh-8a5643198/) -- Twitter: [@DevNinjaShubham](https://x.com/DevNinjaShubham) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-MebinThattil-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-MebinThattil-week01.md deleted file mode 100644 index 3eca8076..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-MebinThattil-week01.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: "GSoC ’25 Week 01 Update by Mebin J Thattil" -excerpt: "Experimenting, Benchmarking and Researching" -category: "DEVELOPER NEWS" -date: "2025-06-06" -slug: "2025-06-06-gsoc-25-mebinthattil-week1" -author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" -tags: "gsoc25,sugarlabs,week01,mebinthattil,speak_activity" -image: "assets/Images/GSOCxSpeak.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Mebin J Thattil - -**Project:** [Speak Activity](https://github.com/sugarlabs/speak) -**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-02 - 2025-06-06 - ---- -## Introduction & About Me -Hey, I'm Mebin 👋🏻! I'm a first year student at PES University, Bangalore, India, currently pursuing a BTech in Computer Science. I’ve had a deep passion for tech ever since I was 10, when I first learned in a CS class that you could write a couple of lines of code and build a (barely functional) website. That simple idea sparked something in me, and over the years, my love for computer science has only grown—especially while building a bunch of cool things along the way. - -About a month ago, I launched my personal portfolio website: [mebin.in](https://mebin.in/). It runs on an 8-year-old Raspberry Pi sitting at home 🤩, so apologies in advance if the site is occasionally slow or down (power cuts are a real pain). I'll be posting a copy of these blogs there as well. Go check 'em out and a bunch of other blogs I've written there! - -I'm also building a Bluesky client in the Nim programming language. I'm a strong advocate for education in technology. In the past, I built a web application aimed at connecting students in rural areas with those in urban areas to help foster a free and open peer-to-peer learning ecosystem. - -To say that I’m thrilled to be working on the Speak Activity would be an understatement. I can’t wait for an amazing summer filled with learning, collaboration and helping enhance educational journey for millions of learners world-wide. - ---- - -## Goals for This Week - -- **Goal 1:** Benchmark and test various models and architectures. -- **Goal 2:** Evaluate the feasibility and implementation approach based on project constraints such as hardware limitations and size requirements. - ---- - -## This Week’s Achievements - -1. **Created a Streamlit benchmark app** - - A simple streamlit app was made to compare responses of different Large Language Models (LLMs) & Small Language Models (SLMs). This was done to understand which models were a good fit for our requirements. - - Links: [Streamlit App](https://llm-benchmarking-sugar.streamlit.app/), [GitHub](https://github.com/mebinthattil/LLM-benchmarking). - - ---- - -## Selection Of Models and Challenges - -- The selection of the LLM was fairly easy, as all the models in the 30-ish billion parameter range performed reasonably well without any fine-tuning. These models were _smart_ but required significant resources to run. That was fine, since the model was intended to be hosted on AWS and accessed via an API endpoint managed by Sugar-AI. -- The selection of the SLM was a bit tricky. Initially, we looked at models under 1B parameters like the Qwen3-0.6B, and the responses were hilariously bad as expected. Later, I experimented with a dual-model architecture, where one model would generate the answer and another model (or the same model with a different system prompt) would refine the answer. I tried this with the Gemma3-1B model as the generating model and the same Gemma3-1B(with a different system prompt), as the evaluation/refinement model. The results were surprisingly good! This model generated answers that were up there with the 30B parameter models! The only caveat is that it technically takes twice the time for inference, but considering the model is pretty small, it wasn’t too bad. -- That said, Gemma3-1B Instruct even after 4-bit quantization is still around 1GB in size, which is much more than we can package with the Speak activity. So now I’m going to be looking into even lighter models like TinyBERT and will update the benchmarks soon. -- Fine-tuning in the next step should hopefully improve the performance of these models as well. Considering that we also need to package the TTS model, we really need to make sure the SLM is as lightweight as possible. - -**TLDR:** -LLM selection was easy — they all perform pretty well. SLM poses some challenges. Dual-model (generation + evaluation/refinement) seems to produce much better responses. Size of the SLM needs to be reduced further (hopefully under 100MB). - - - ---- - -## Key Learnings - -- Dual model architecture (generation model + evaluation/refinement model) produces some great results, even if the individual models are very small or perform bad individually! - ---- - -## Next Week’s Roadmap - -- Setup AWS for fine-tuning the model. -- Finalize on the model to go forward with. -- Finalize on the dataset to start fine-tuning SLM with. -- Include much smaller models like TinyBert in the benchmark. -- Start fine-tuning TinyBert or any other SLM on the agreed upon dataset in the hopes to improve performance. - - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-Nikhil-Bhatt-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-Nikhil-Bhatt-week01.md deleted file mode 100644 index 7cc8de34..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-Nikhil-Bhatt-week01.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: "GSoC ’25 Week 01 Update by Nikhil" -excerpt: "Implemented repository creation via GitHub App, secure key generation, and metadata integration" -category: "DEVELOPER NEWS" -date: "2025-06-08" -slug: "2025-06-08-gsoc-25-Nikhil-Bhatt-week01" -author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" -tags: "gsoc25,sugarlabs,week01,Nikhil-Bhatt" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Nikhil Bhatt - -**Project:** [Git backend for Musicblocks](https://github.com/BeNikk/git-backend) -**Mentors:** [Walter Bender](https://github.com/walterbender) -**Assisting Mentors:** [Sumit Srivastava](https://github.com/sum2it) -**Reporting Period:** 2025-06-02 - 2025-06-08 - ---- - -## Goals for This Week - -- **Goal 1:** Implement GitHub App JWT + Installation Token Authentication -- **Goal 2:** Set Up Repository Creation from Backend -- **Goal 3:** Write Metadata and Content Files to Repository -- **Goal 4:** Design Backend Folder Structure for Scalability - - ---- - -## This Week’s Achievements - -1. **GitHub App JWT + Installation Token Auth Flow Implemented** - - Created a Github app and installed it on a separate organisation account. - - Implemented JWT generation using App ID and private key. - - Fetched installation token dynamically to create repositories securely within the GitHub organization. - - -2. **Created Repositories via Backend with Files** - - Built an Express-based controller to create repositories inside the organization. - - On repository creation, wrote three files: - - `README.md` - - `projectData.json` (from frontend) - - `metaData.json` (containing hashed key, theme, and timestamp) - - -3. **Implemented Unique Ownership via Hashed Keys** - - Generated a random project key and stored a hashed version in metadata. - - Only the original key holder (sent to frontend) can perform future edits, ensuring project ownership. - - -4. **Structured Clean Codebase for Scalability** - - Organized backend into proper folders: `controllers`, `services`, `utils`, `routes`, `config`, and `types`. - - Made the repo production-ready with readable service-based architecture. - - Check the project at [Link](https://github.com/benikk/musicblocks-backend) - -5. **Optimized Token Management & Project Creation** - - Validated rate limits (15,000 requests/hour for GitHub App installation tokens). - - Each request generates a fresh installation token, no collisions or race conditions observed so far. - - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Writing multiple files to a new GitHub repository using Octokit caused noticeable delays -- **Solution:** Batched file uploads with asynchronous control using a loop and base64-encoded content, I plan to imrove it - by exploring GitHub’s Create a tree and commit API to upload multiple files in a single commit for performance optimization. - ---- - -## Key Learnings - -- Deep understanding of GitHub App authentication using JWT + installation tokens. -- Secure project ownership enforcement using hashing and metadata tracking. -- Octokit’s repo/file handling APIs and best practices for GitHub integrations. - ---- - -## Next Week’s Roadmap - -- Add **edit project** functionality: Only owner (with original key) can update content. -- Implement **key-based ownership check middleware** to protect sensitive routes. -- Allow users to **open GitHub issues** on created repositories via the backend. - - ---- - - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - -## Connect with Me - -- GitHub: [BeNikk](https://github.com/BeNikk) -- Gmail: [bhattnik442@gmail.com](mailto:bhattnik442@gmail.com) -- LinkedIn: [Nikhil](https://www.linkedin.com/in/nikhil-bhatt-3b37a0255/) -- Twitter: [Nikhil Bhatt](https://x.com/Be_Nikkk) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-SafwanSayeed-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-SafwanSayeed-week01.md deleted file mode 100644 index 49553b64..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-SafwanSayeed-week01.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "GSoC ’25 Week 1 Update by Safwan Sayeed" -excerpt: "Kickoff of Music Blocks 4 Program Engine development" -category: "DEVELOPER NEWS" -date: "2025-06-08" -slug: "2025-06-08-gsoc-25-sa-fw-an-week1" -author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" -tags: "gsoc25,sugarlabs,week1,sa-fw-an" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 1 Progress Report by Safwan Sayeed - -**Project:** Music Blocks 4 Program Engine -**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-06-02 - 2025-06-08 - ---- - -## A Blog-style Retrospective - -Last week marked the official start of the coding phase for the Music Blocks 4 Program Engine. I spent the first few days translating our planning sessions into a concrete technical specification. Crafting the spec helped me clarify the core constructs, their key properties, and how they will map to interfaces. The early draft already feels like a solid roadmap for the engine’s evolution. - -Midweek, I teamed up with Karan Palan to begin coding the skeleton of our abstract classes. We paired on Replit to code the classes. - ---- - -## Goals for This Week - -- Draft a comprehensive tech spec detailing engine constructs, class interfaces, and example workflows. -- Implement the initial set of abstract classes in TypeScript. -- Outline AST build steps and prepare a simple program example. - ---- - -## This Week’s Highlights - -1. **Tech Specification Draft** - - Wrote the first section of the tech spec covering . - - Link: [Tech Spec Document](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.otbw6ldsc32w) - -2. **Abstract Classes Implementation** - - Started coding the core abstract classes in TypeScript alongside [Karan Palan](https://github.com/Karan-Palan). - - Link: [Replit: Engine Abstract Classes](https://replit.com/@karanpalan007/engine-abstract-classes?v=1#README.md) - -3. **AST Discussion & Planning** - - Held discussions with Anindya on AST constructs, class instantiation workflow, and example program build. - - Outlined next steps for documenting AST examples in the tech spec. - ---- - -## Challenges & Solutions - -- **Syncing Edits on Replit:** - We initially clashed on file versioning. - *Solution:* Established a clear editing schedule and used commit comments to track changes. - -- **Defining Spec Scope:** - The broad set of music constructs felt overwhelming. - *Solution:* Prioritized a core subset to include in the first draft. - ---- - -## Key Learnings - -- Mastered TypeScript abstract classes and interface patterns. -- Reinforced the importance of early design documentation. -- Gained clarity on AST building workflows through Anindya's feedback. - ---- - -## Next Week’s Roadmap - -- Finalize abstract class implementations and interfaces. -- Expand the spec with AST examples and UML class diagrams if needed. - ---- - -## Resources & References - -- **Tech Spec:** [Google Docs](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.otbw6ldsc32w) -- **Code Skeleton:** [Replit Engine Abstract Classes](https://replit.com/@karanpalan007/engine-abstract-classes?v=1#README.md) - ---- - -## Acknowledgments - -Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their continual guidance and support. - ---- - -## Connect with Me - -- GitHub: [@sa-fw-an](https://github.com/sa-fw-an) -- Email: [isafwansayeed@gmail.com](mailto:isafwansayeed@gmail.com) -- LinkedIn: [Safwan Sayeed](https://www.linkedin.com/in/safwan-sayeed-6a3a482a9/) -- Twitter: [@safwan_say](https://twitter.com/safwan_say) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-SaumyaShahi-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-SaumyaShahi-week01.md deleted file mode 100644 index 3cadb15c..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-SaumyaShahi-week01.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "GSoC ’25 Week 01 Update by Saumya Shahi" -excerpt: "Weekly Progress Report on the Masonry Module for GSoC '25" -category: "DEVELOPER NEWS" -date: "2025-06-08" -slug: "2025-06-08-gsoc-25-saumya-week01" -author: "Saumya Shahi" -description: "GSoC '25 Contributor at SugarLabs" -tags: "gsoc25,sugarlabs,masonry,week01,saumya-shahi" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Saumya Shahi - -**Project:** [Masonry Module - Music Blocks v4](https://github.com/sugarlabs/musicblocks-v4) -**Mentors:** [Anindya Kundu](https://github.com/meganindya/) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/), [Devin Ulibarri](https://github.com/pikurasa/) -**Reporting Period:** 2025-06-01 - 2025-06-08 - ---- - -## Goals for This Week - -- Understand the working of SVGs and path rendering logic. -- Create an exhaustive list of all configurations needed to render each visual brick type. -- Formulate the path rendering logic to dynamically generate each brick. -- Implement rendering logic for SVG bricks based on the provided configurations. -- Ensure each brick type renders correctly with various parameters. - ---- - -## This Week’s Achievements - -1. **Explored SVG-based Brick Rendering** - - Used [SVG Playground](https://yqnn.github.io/svg-path-editor/) to manually draw and style bricks. - - This helped me understand SVG path syntax, positioning, scaling, and how `viewBox` works for consistent rendering. - - Also referred to the [MDN SVG Docs](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorials/SVG_from_scratch/Getting_started) for deeper insights into SVG internals. - -2. **Compiled a Comprehensive List of Brick Types** - - Created a detailed list of all visually distinct brick types to be supported by the Masonry module. - - This helped identify variation across different bricks and how they interact in Music Blocks. - - [Brick Types Document](https://docs.google.com/document/d/1BswWHadyy4yC3_3vK6KHZnMn0u6jbbYiQ6JQWiqRMLw/edit?tab=t.0) - -3. **Mapped Configurations for Each Brick Type** - - Listed out all the necessary configurations (similar to React props) for each brick — including label size, number of arguments, shape flags, etc. - - This configuration map allows dynamic rendering logic per brick type. - - [Configurations Document](https://docs.google.com/document/d/1UJXh3734S138BoTsGulzeTlZXstyvWd6syJK2eclMKI/edit?usp=sharing) - -4. **Implemented SVG Brick Rendering** - - Successfully implemented dynamic SVG rendering logic. - - Given a configuration, each brick now generates an accurate path representation. - - The system supports variation in label length, slot types, and layout, making the rendering pipeline fully flexible. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Brick structures vary significantly, making a one-size-fits-all rendering approach difficult. - **Solution:** Broke down commonalities across bricks and created modular rendering components that dynamically adapt based on type and config. - -- **Challenge:** Path distortion with varying argument lengths and labels. - **Solution:** Used live preview tools and console-based debugging to isolate scaling issues. The SVG path editor was extremely useful in this phase. - ---- - -## Key Learnings - -- Gained strong understanding of **SVG path syntax** and dynamic drawing. -- Improved in building **config-driven rendering pipelines** with a clean separation of data and UI logic. -- Learned how to break down complex visual requirements into **reusable, parameterized components**. -- Realized that **explaining your thought process to mentors** is invaluable — it clarifies confusion and leads to better solutions. - ---- - -## Next Week’s Roadmap - -- Work on edge cases and introduce early validation of config inputs. -- Build a **basic layout logic** that dynamically generates a SVGs for a tree of bricks (Multiple bricks rendering). -- Begin implementing **connection logic** based on bounding box / collision detection. - ---- - -## Resources & References - -- [Brick Types Doc](https://docs.google.com/document/d/1BswWHadyy4yC3_3vK6KHZnMn0u6jbbYiQ6JQWiqRMLw/edit?tab=t.0) -- [Brick Configurations Doc](https://docs.google.com/document/d/1UJXh3734S138BoTsGulzeTlZXstyvWd6syJK2eclMKI/edit?usp=sharing) -- [SVG Path Editor](https://yqnn.github.io/svg-path-editor/) -- [MDN SVG Tutorial](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial) - ---- - -## Acknowledgments - -Grateful to my mentors Anindya, Walter, and Devin for their constant guidance and insightful feedback. Thanks to the Sugar Labs community for their welcoming support! - ---- - -## Connect with Me - -- GitHub: [@saumyashahi](https://github.com/saumyashahi) -- Gmail: [saumyashahi05@gmail.com](mailto:saumyashahi05@gmail.com) -- LinkedIn: [Saumya Shahi](https://www.linkedin.com/in/saumya-shahi/) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-diwangshu-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-diwangshu-week01.md deleted file mode 100644 index 861d9494..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-diwangshu-week01.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "GSoC ’25 Week 01 Update by Diwangshu Kakoty" -excerpt: "Deploying a Streamlit app for testing" -category: "DEVELOPER NEWS" -date: "2025-06-04" -slug: "2025-06-04-gsoc-25-Diwangshu-week01" -author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" -tags: "gsoc25,sugarlabs,week01,AI" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Diwangshu Kakoty - -**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [ Ajeet Pratap Singh](https://github.com/apsinghdev) -**Reporting Period:** 2025-06-01 - 2025-06-07 - ---- - -## Goals for This Week - -- **Goal 1:** Refine prompt templates and instructions for the LLM. -- **Goal 2:** Host the project on Streamlit Cloud. -- **Goal 3:** Develop Fast API endpoints. -- **Goal 4:** Find an alternative cloud-based vector database. - ---- - -## This Week’s Achievements - -1. **Fast API Endpoints** - - Although I kept this task later in my proposal but it became necessary when I wanted to deploy the project for testing purposes. The endpoints /chat and /summary are used by the client-side app when having a conversation with the user. It is working perfectly in my local development environment, but it caused an issue when I tried to host the Fast API server on [Render](https://render.com/). After several trials, I found that the embedding model I am using - 'all-MiniLM-L6-v2' is a bit heavy, and the RAM usage given by the free service is not enough. - But anyway, this is a success as we will need Fast API during the final deployment. - - -2. **Cloud based vector database - Qdrant** - - For development, I have been using ChromaDB, which is pretty good for testing and developing RAG applications locally. I have now opted to use Qdrant, which provides cloud-based vector database. It is working well with the Streamlit app. - - [Qdrant](https://qdrant.tech/documentation/) - -3. **Hosted Streamlit App** - - Because the Fast API server was not deployed, I simply wrote the RAG code in the Streamlit code itself. Now that it is hosted, mentors and contributors can test it and give feedback. - - [Streamlit app](https://reflectionapp-2yoxtvn6sknvktme2zorvq.streamlit.app/) - -4. **Refined Prompts** - - Prompt Engineering is the key to get a well structured and quality response from any LLM. I improved the instructions for the LLM to ask follow up questions to get quality answers from users. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Fast API deployment fails. - **Solution:** The overall goal was to deploy the project so that mentors can test it and give me feedback for the summer period. Therefore, I modified the streamlit code to handle the RAG application by itself. Hence, I tackled the problem by avoiding server deployment. - ---- - -## Key Learnings - -- I learned new technologies: Fast API and Streamlit. I watched tutorials on YouTube and read their documentations as well. -- Learned how API endpoints work and how to manage API keys while deploying it. - ---- - -## Next Week’s Roadmap - -- Work on things suggested by mentors. -- Improve the analysis phase. This phase of the reflection learning cycle is suppose to compare and contrast user development over a period of time. Currently it uses a hardcoded summary but it needs to be dynamic. -- Write documentation for Music Blocks. Some topics still needs to get covered. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-mostlyk-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-mostlyk-week01.md deleted file mode 100644 index 064339ea..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-mostlyk-week01.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: "GSoC '25 Community Bonding and First Week by Krish" -excerpt: "A deep dive into the GTK4 migration journey for Sugar Labs - exploring the challenges, progress, and tooling setup" -category: "DEVELOPER NEWS" -date: "2025-06-04" -slug: "2025-06-04-gsoc-25-mostlyk-community-bonding" -author: "@/constants/MarkdownFiles/authors/krish-pandya.md" -description: "GSoC'25 Contributor working on GTK4 migration for Sugar Labs" -tags: "gsoc25,sugarlabs,gtk4,mostlyk,community-bonding" -image: "assets/Images/GSOC.png" ---- - - -<!-- markdownlint-disable --> - -# Community Bonding Period Progress Report by Krish Pandya - -**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) -**Mentors:** [Walter Bender](https://github.com/walterbender) , [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky) -**Organization:** Sugar Labs -**Reporting Period:** May 15, 2025 till June 4, 2025 - ---- - -## Introduction & About Me - -Hey everyone! This is probably going to be my biggest blog post of the GSoC journey haha — and I'm excited to share my thoughts on the GTK4 migration project during the community bonding period and some work done till the first week. I will just give a short introduction— - -I'm Krish Pandya aka MostlyK, a B.Tech student in Electronics and Communication Engineering at IIITH. While my degree says ECE, I've found myself gravitating toward robotics, graphics, software , and most imporatant of them all open source development. When I'm not debugging ~~C++~~ (Rust/Python now) code or setting up new linux systems, you'll find me reading philosophy (currently juggling reading Sartre's Nausea and Red Rising), creating music, or tinkering with RISC-V processors. I believe in doing things properly , whether it's writing neat code, understanding the philosophy behind API changes, or setting up development workflows that actually make sense. And writing stuff so coming back , anyone can just give a glance and thank me for writing this, I know my future self is going to read this a lot! - -The Sugar desktop environment currently relies on GTK3, which is approaching end-of-life. My mission? Modernize Sugar by completing its migration to GTK4, ensuring long-term sustainability, improved performance, and access to modern UI features. This involves porting the core toolkit (sugar-toolkit-gtk3), porting an activity to GTK4 and making a new activity along with the new features that will be added and testing the changes. - ---- - -## My Approach & Tooling Setup - -Before diving into the actual porting work, I spent considerable time setting up an efficient development workflow. Coming from other projects, I knew that having quick way to test my changes, that is currently I just have to build the toolkit first but later on testing , it helps to have a faster way to test stuff, I may even bring out some tmux scripts later down the weeks but as of now the following is enough: - -### Development Scripts That Saved My Sanity - -I created a couple of shell snippets that became essential during this period: - -```bash -# Replace system sugar3 with development version -# This ensures activities use the modified toolkit instead of the old system version -sudo rm -rf /usr/lib/python3.13/site-packages/sugar3;sudo cp -r ./src/sugar3 /usr/lib/python3.13/site-packages/sugar3 - -# Complete rebuild and install cycle -sudo ./autogen.sh;sudo make clean;sudo make;sudo make install -``` - -The first script is particularly crucial - it replaces the system's sugar3 package with my development version. Without this, Sugar activities would continue using the old GTK3 toolkit, making it impossible to test the GTK4 migration properly. The second command handles the full build cycle, all these small changes help a lot in the long run. I also knew that because I had to write a lot, I developed my own espanso setup and added stuff like em dashes , en dashes, some template code, and a bunch of stuff that come useful while writing. - -### The Work Begins - -1. **Started with the obvious**: Updated all `gi.require_version` calls from GTK 3.0 to 4.0 -2. **Build system updates**: Modified GIR includes to use Gtk-4.0 and Gdk-4.0 -3. **The part to work around**: Dealing with GTK4's opaque structures and API changes - ---- - -## The Challenges & My Thought Process - -### 1: GdkEvent Becomes Opaque - -This was my first real "welcome to GTK4" moment. In GTK3, you could directly access event fields like `event->type` or `event->grab_broken.keyboard`. GTK4 said "nope!" and made GdkEvent structures completely opaque. - -**My approach:** -- Systematically went through each event controller file -- Replaced direct field access with proper accessor functions -- `event->type` became `gdk_event_get_event_type()` -- `event->touch.x/y` became `gdk_event_get_position(event, &x, &y)` - -**The human moment:** I'll be honest, this felt tedious at first. But then I realized GTK4's approach actually makes the code more maintainable and future-proof. The accessor functions provide better type safety and clearer intent. - -### 2: GDK_GRAB_BROKEN Disappears - -The `GDK_GRAB_BROKEN` event type just... vanished. After diving into GTK4 documentation, I learned that GTK4 handles grab management automatically now. - -**Solution:** Removed the grab broken handling entirely. Well I am not sure if that's a good choice , let's see what happens next week, if we have to come here! -### 3: Goodbye GdkPoint, Hello Custom Structures - -GTK4 removed the `GdkPoint` structure that Sugar was using. So naturally, I created a custom `SugarPoint` structure: - -```c -typedef struct { - double x; - double y; -} SugarPoint; -``` - -**The learning:** Sometimes migration isn't just about updating APIs, it's about understanding when to create your own abstractions. - ---- - -## Current Progress Snapshot - -Here's where things stand after the community bonding period: - -### Completed -- Updated all `gi.require_version` calls to 4.0 in Python files -- Updated import statements across the codebase -- Fixed build system GIR includes (Gtk-4.0, Gdk-4.0) -- **Fixed GdkEvent opaque struct access** in sugar-event-controller.c -- **Migrated all event controllers** to GTK 4 event handling -- **Created and implemented SugarPoint** structure to replace GdkPoint - -### In Progress -- Hunting down remaining 3.0 version references (they're sneaky!) -- Fixing eggaccelerator errors (legacy code is fun, right?) - -### Next on the Roadmap -- Replace GtkToolbar with GtkBox -- Migrate GtkEventBox to GtkWidget + EventControllers -- Update GtkContainer usage to new child management APIs -- Convert draw() methods to snapshot() -- Update size request/allocation APIs - ---- - -## Key Learnings & Insights - -This period taught me that migration projects are as much about understanding the philosophy behind changes as they are about updating code. GTK4 isn't just GTK3 with new version numbers, it represents this shift toward: - -- Better memory safety with opaque structures -- Cleaner event handling with dedicated controllers -- Modern rendering with the snapshot model - - The most valuable skill I've developed is learning to read the porting doc, and understand where to add my own implementation or follow the documentation. I try to reason my changes, so most of the time I am trying to argue to myself why this change compared to something else. - ---- - -## Resources & References - -- Project Page – [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) -- Sugar Toolkit Repository(original) – [sugar-toolkit-gtk3](https://github.com/sugarlabs/sugar-toolkit-gtk3) -- Draft PR ( on the gtk4 repository ) – [Initial GTK4 Migration Work](https://github.com/sugarlabs/sugar-toolkit-gtk4/pull/1/) -- GTK4 Migration Guide – [docs.gtk.org/gtk4/migrating-3to4.html](https://docs.gtk.org/gtk4/migrating-3to4.html) - ---- - -## Acknowledgments - -Huge thanks to Walter Bender for the guidance during this exploration phase, and to the Sugar Labs community for maintaining such well-documented code. I will be contacting other Mentors for their guidance as well and to know their thoughts!. - ---- - -Looking forward to sharing more updates, - - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-omsuneri-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-omsuneri-week01.md deleted file mode 100644 index e8648ff6..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-gsoc-25-omsuneri-week01.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: "GSoC ’25 Week 01 Update by Om Santosh Suneri" -excerpt: "Refining the JSON to text convertor code and creating a basic streamlit debugger app UI" -category: "DEVELOPER NEWS" -date: "2025-06-07" -slug: "2025-06-07-gsoc-25-omsuneri-week01" -author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" -tags: "gsoc25,sugarlabs,week01,Debugger,AI,Music Blocks" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Om Santosh Suneri - -**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) -**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) -**Reporting Period:** 2025-06-02 - 2025-06-07 - ---- - -## Goals for This Week - -- **Goal 1:** To refine the JSON to text convertor code. -- **Goal 2:** To convert the convertor's Javascript code to Python. -- **Goal 3:** To create a basic Streamlit debugger app UI. - ---- - -## This Week’s Achievements - -1. **JSON to Text Converter Refinement** - - I focused on refining the JSON to Text Converter for Music Blocks. I improved the metadata representation of the "start" block to make it more accurate and readable in the text format. Additionally, I added support for more block types, ensuring that their text representations are consistent with the design format. - - This refinement is important because the JSON to Text Converter is a core part of our AI-powered Debugger. A clear and structured text format makes it easier for both the AI model and human users to understand the program logic. - -2. **Javascript to Python Conversion** - - Following suggestions from mentors Walter and Devin, I began creating a Streamlit-based debugger interface. Since Streamlit is a Python framework, my first step was to convert the existing JSON to Text Converter—originally written in JavaScript—into Python. This involved translating the logic and formatting rules to ensure the output remained consistent. - - This conversion is crucial because it enables seamless integration of the converter into the Streamlit app, which will serve as the initial interface for our debugger. By moving the code to Python, I ensured compatibility with the app’s backend, allowing further development like live user queries, debugging and feedback—all in one cohesive Python environment. - -3. **Streamlit Debugger App UI Creation** - - As a beginner to Streamlit, I started building the UI for the debugger app. I successfully created a basic Streamlit interface that allows users to input text queries. To handle these queries, I integrated the free Google Gemini API, enabling the app to return LLM-generated responses. Currently, the app supports simple user input and displays the corresponding Gemini response. - - This is an important first step in building an interactive AI-powered debugger. Even though it’s still in an early stage, this app lays the foundation for integrating core features like JSON-to-text conversion, error analysis, and user feedback. The goal is to evolve this into a fully functional debugging tool that enhances the Music Blocks experience. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Learning the Streamlit framework and creating a basic UI app as a complete beginner. - **Solution:** To overcome this, I referred to the official Streamlit documentation, followed beginner tutorials, and experimented with small components to understand the structure. This hands-on approach helped me build a working basic UI that takes user input and integrates it with the Gemini API. - -- **Challenge:** Converting all methods and functions from JavaScript to Python was time-consuming and introduced several errors. - **Solution:** I carefully mapped the logic from JavaScript to Python, using Pythonic alternatives where necessary. I used print-based debugging and Python’s error messages to identify issues. Although some minor bugs remain, I have a clear plan to fix them in the coming days and will be testing each function thoroughly for accurate output. - ---- - -## Key Learnings - -- I gained an understanding of Streamlit’s basic architecture and learned how to build and deploy a Streamlit app -- I explored advanced Python techniques to effectively translate the JavaScript code into Python for smoother integration. - ---- - -## Next Week’s Roadmap - -- My goal for the next week is to fully convert the JSON to Text Converter, originally written in JavaScript, into Python. -- I also plan to integrate this Python version directly into the Streamlit debugger app to enable seamless JSON conversion within the app interface. -- Additionally, I aim to make the basic functionality of the app usable so that users can begin interacting with it and provide initial feedback. This feedback will help identify usability issues early and guide further improvements in the UI and debugging workflow. - ---- - -## Resources & References - -- **Repository:** [AI-powered-Debugger-for-MB(JSON convertor)](https://github.com/omsuneri/AI-powered-Debugger-for-MB/blob/main/Convertor/converting-json-txt.js) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-08-ssoc-2025-MuhammadHaroon-week01.md b/src/constants/MarkdownFiles/posts/2025-06-08-ssoc-2025-MuhammadHaroon-week01.md deleted file mode 100644 index e309243f..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-08-ssoc-2025-MuhammadHaroon-week01.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: "SSoC ’25 Week 01 Update by Muhammad Haroon" -excerpt: "Kick off Generative AI Instrument Sample Generation for Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-06-08" -slug: "2025-06-08-ssoc-25-MuhammadHaroon-week01" -author: "@/constants/MarkdownFiles/authors/muhammad-haroon.md" -tags: "ssoc25,sugarlabs,week01,GenAI,MusicBlocks,Music" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Muhammad Haroon - -**Project:** [Generative AI Instrument Sample Generation for Music Blocks](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md#Generative-AI-Instrument-Sample-Generation-for-Music-Blocks) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-02 - 2025-06-08 - ---- - -## Progress - -I am excited to announce that I have been selected for Sugar Summer of Code 2025. This summer I would be working on creating a Generative AI tool that would create endless sound samples that can be then used in Music Blocks. - -This week I kicked off my project, I had a meeting with my mentors, and discussed my approach with them. For the next week, it was decided to create a basic frontend using streamlit and for the backend will be using [MusicGen](https://audiocraft.metademolab.com/musicgen.html). - -I will begin by testing some prompts and generating some samples from it, to test whether they can be used in Music Blocks or further refinement of the pipeline is needed. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-09-KaranPalan-week01.md b/src/constants/MarkdownFiles/posts/2025-06-09-KaranPalan-week01.md deleted file mode 100644 index 0997fda7..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-09-KaranPalan-week01.md +++ /dev/null @@ -1,111 +0,0 @@ ---- - -title: "Community Bonding & Week 1 Update by Karan Palan" -excerpt: "From compiler theory deep-dives to brick-rendering math—mentoring the 2025 Music Blocks Masonry & Engine cohorts." -category: "DEVELOPER NEWS" -date: "2025-06-09" -slug: "2025-06-09-KaranPalan-week01" -author: "Karan Palan" -description: "GSoC 2024 mentee, now volunteering and peer-mentoring on Music Blocks 4" -tags: "gsoc25,sugarlabs,communitybonding,week1,karanpalan" ---- - -<!-- markdownlint-disable --> - -# Community Bonding + Week 1 Progress Report - -**by Karan Palan** - -**Projects:** Music Blocks 4 **Masonry** & **Program Engine** -**Role:** Volunteer & Peer-Mentor (GSoC 2024 alumnus) -**Mentor:** [Anindya Kundu](https://github.com/meganindya/) -**Mentees:** [Justin Charles](https://github.com/justin212407), [Saumya Shahi](https://github.com/saumyashahi) (Masonry) • [Safwan Sayeed](https://github.com/sa-fw-an) (Engine) -**Reporting Period:** 2025-05-20 → 2025-06-08 - ---- - -Community bonding this year felt less like “hello world” and more like an accelerated CS grad course. Anindya flipped the script: before writing a single line of code we dissected *how* languages work, explored compiler pipelines, and compared micro-compilers. - -### Mapping Bricks to LLVM IR - -Armed with that theory, each of us reverse-mapped **Music Blocks bricks → LLVM intermediate representation** to ground our designs in real compiler constructs. My early spreadsheet of brick vs. IR became a north star for future optimizations. - -### Defining Music Blocks Grammar - -After digesting JavaScript’s formal grammar, we drafted a Music Blocks-specific one that is lean, kid-friendly, but still transpilable to JS. This fed directly into the Engine tech spec. - -### Meeting with Andres - -Anindya set up a fireside chat with his former manager **Andrés**, giving us a crash-course in real-world engineering. Andrés drilled home that *“quick fixes live for 18 months,”* scope must be ruthlessly trimmed, and the true mark of a pro is writing code a stranger can maintain five years later, all while treating teammates (coders or not) with respect. - -### Two Tracks, One Vision - -We split weekly calls: - -| Track | Focus | Key Doc | -| ------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| Masonry | SVG brick generation & formulae | [Brick Sides & Formulae](https://docs.google.com/document/d/1AUlA2leDJIfV3ZXceLhCaITftExq6c5BcUBMZOtZBvE/) | -| Engine | AST, runtime, class hierarchy | [Engine Tech Spec + AST](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/) | - ---- - -## Highlights So Far - -1. **Project-wide Knowledge Base** - *Spreadsheet* of compiler concepts & Music Blocks parallels—anchors every design choice. - Link ➜ [Mentor Context Sheet](https://docs.google.com/spreadsheets/d/1LFuIlzRiMlEfeLr21x8_SYnVIQ5baVQv8tz2GWN9PfU/) - -2. **Brick Taxonomy Drafted** - Classified each brick against LLVM constructs for easy reasoning about side-effects and type constraints. - Link ➜ [Brick ↔️ LLVM Mapping](https://docs.google.com/document/d/1BswWHadyy4yC3_3vK6KHZnMn0u6jbbYiQ6JQWiqRMLw/) - -3. **Brick Geometry Formulae** - With Justin & Saumya, derived parametric equations for every brick edge—vital for responsive SVG. - Link ➜ [Brick Formulae Doc](https://docs.google.com/document/d/1AUlA2leDJIfV3ZXceLhCaITftExq6c5BcUBMZOtZBvE/) - -4. **Engine Class Skeleton** - Safwan and I scaffolded core *abstract* and initial *concrete* classes in TypeScript. - Code ➜ [Replit Workspace](https://replit.com/@karanpalan007/engine-abstract-classes?v=1) - - - -## Key Learnings - -* **Teach, then build:** A solid mental model of compilers made later coding decisions friction-less. -* **Visual specs pay off:** Equation-driven SVG means less pixel-pushing, more deterministic rendering. -* **Peer-mentoring ≠ lecturing:** Guiding Justin, Saumya, and Safwan taught me to ask leading questions instead of prescribing answers. - ---- - -## Next Week’s Roadmap - -* **Masonry:** Finish implementing '_generateLeft()' so *all* brick types respect left-side notches. -* **Engine:** Flesh out 'Expression' subclasses and prototype a minimal AST → JS transpile step. -* **Docs & CI:** Auto-publish rendered SVG examples in PR previews to catch geometry regressions early. - ---- - -## Resources & References - -* Mentor Notes → [Spreadsheet](https://docs.google.com/spreadsheets/d/1LFuIlzRiMlEfeLr21x8_SYnVIQ5baVQv8tz2GWN9PfU/) -* Brick ↔️ LLVM Mapping → [Google Doc](https://docs.google.com/document/d/1BswWHadyy4yC3_3vK6KHZnMn0u6jbbYiQ6JQWiqRMLw/) -* Engine Tech Spec → [Google Doc](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/) -* Brick Geometry → [Formulae Doc](https://docs.google.com/document/d/1AUlA2leDJIfV3ZXceLhCaITftExq6c5BcUBMZOtZBvE/) -* Code Skeleton → [Replit](https://replit.com/@karanpalan007/engine-abstract-classes?v=1) - ---- - -## Acknowledgments - -Huge thanks to **Anindya** for the deep-dive lectures and mentoring, and to **Justin, Saumya, and Safwan** for matching my energy sprint-for-sprint. SugarLabs’ culture of mentoring forward keeps the snowball rolling. - ---- - -## Connect with Me - -* GitHub: [@Karan-Palan](https://github.com/Karan-Palan/) -* Email: [karanpalan007@gmail.com](mailto:karanpalan007@gmail.com) -* LinkedIn: [karan-palan-476472289/](https://www.linkedin.com/in/karan-palan-476472289/) -* Twitter: [Karan_Palan7](https://x.com/Karan_Palan7) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-10-gsoc-25-AdityaKrSingh26-week04.md b/src/constants/MarkdownFiles/posts/2025-06-10-gsoc-25-AdityaKrSingh26-week04.md deleted file mode 100644 index 2ca43897..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-10-gsoc-25-AdityaKrSingh26-week04.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: "GSoC ’25 Week 04 Update by Aditya Kumar Singh" -excerpt: "localization for 3D Human Activity in Sugarizer, palette switcher, and skeletal improvements." -category: "DEVELOPER NEWS" -date: "2025-06-10" -slug: "2025-06-10-gsoc-25-AdityaKrSingh26-week04" -author: "@/constants/MarkdownFiles/authors/aditya-singh.md" -description: "GSoC'25 Contributor at SugarLabs (Sugarizer Human Activity Pack)" -tags: "gsoc25,sugarlabs,week04,AdityaKrSingh26" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Aditya Kumar Singh - -**Project:** [Sugarizer](https://github.com/llaske/sugarizer) -**Mentors:** [Lionel Laské](https://github.com/llaske) -**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) -**Reporting Period:** 2025-05-30 - 2025-06-05 - ---- - -## Goals for This Week - -- **Goal 1:** Add a model selection palette UI to toggle between models. -- **Goal 2:** Integrate the Human-body model into the paint activity and set the Human-body human model as the default view. -- **Goal 3:** Refactor and improve naming conventions for bones in the skeleton model. -- **Goal 4:** Localize the Human Body Activity using i18next.js, supporting English and French. - - ---- - -## This Week’s Achievements - -1. **Model Palette Implementation** - - Developed a new model selection palette in the UI allowing users to switch between: - - Human body - - Skeleton - - Organs - - Set the Human body as the default model loaded on activity start. - - Palette updates the 3D scene dynamically without requiring a full reload. -  - - -2. **Human-Body Model Paint Integration** - - Integrated the Human body model with the interactive paint activity. - - Ensured hierarchical structure for smooth interactivity and logical mesh grouping -  - - -3. **Improved Bone Naming in Skeleton Model** - - Refactored the skeletal model for accurate and educational naming: - - Replaced generic labels like “Lower Leg” with specific names like **Tibia** and **Fibula**. - - Split forearm into **Radius** and **Ulna**, adjusting geometry and mesh positions. - - - -4. **Implemented i18next.js to support internationalization.** - - Implemented **i18next.js** to support internationalization. - - Completed full translation of Human Body Activity in **English** and **French**. - - Translation files follow standard .json structure for easy future expansion. - - Example image for French: -  - - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Naming skeleton bones accurately without anatomical overlap. - **Solution:** Cross-referenced medical diagrams and validated model mesh mapping manually in Blender. - ---- - -## Key Learnings - -- Deepened understanding of scene management in Three.js and optimized mesh rendering for performance. -- Gained experience in internationalization using i18next.js -- Developed more precise anatomical terminology awareness and importance of educational clarity. - ---- - -## Next Week’s Roadmap - -- Write Weekly Blog Post summarizing progress, screenshots, and key learnings. -- Fix Organs model. Distance between eyes and mouth seems to be more than required, reduce that and see if there is some alignment issue. -- Integrate the full human body model into the paint activity to allow direct interaction and labeling across complete anatomy. -- Merge Paint and Learn mode to show a popup at bottom of screen when user click a part - ---- - - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - -## Connect with Me - -- GitHub: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) -- Gmail: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) -- LinkedIn: [Aditya Kumar Singh](https://www.linkedin.com/in/adityakrsingh26/) -- Twitter: [@AdityaKrSingh26](https://x.com/AdityaKrSingh26) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-Elwin-Li-week02.md b/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-Elwin-Li-week02.md deleted file mode 100644 index bbfbd015..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-Elwin-Li-week02.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "GSoC '25 Week 2 Update by Elwin Li" -excerpt: "Weekly progress report for JSEditor updates" -category: "DEVELOPER NEWS" -date: "2025-06-14" -slug: "2025-06-14-gsoc-25-Elwin-Li-week02" -author: "@/constants/MarkdownFiles/authors/elwin-li.md" -tags: "gsoc25,sugarlabs,week2,javaScript editor" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 2 Progress Report by Elwin Li - -**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/config_driven_conversion/elwin) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) - -**Reporting Period:** 2025-06-07 - 2025-06-14 - ---- - -## Goals for This Week - -- **Goal:** Complete and deploy code to blocks functionality with full documentation and begin work on debugger. - ---- - -## This Week’s Achievements - -**Added All Blocks for Code to Blocks Support** - -I added all blocks that are supported for block to code conversion to be supported for code to blocks conversion. I also added all necessary unit tests, and very [detailed documentation](https://github.com/sugarlabs/musicblocks/blob/master/js/js-export/CONVERSION_GUIDE.md) on how to add new blocks for support. - -**Optimized Files** - -I added a script to minify the JSON config so that musicblocks doesn't need to load the entire large file. I also merged many blocks that have the same path in the AST so that the config looks cleaner, and adding new blocks of the same path is even easier. - -**Deployed Project** - -The code to blocks project has been complete and deployed, as seen in this [merged PR](https://github.com/sugarlabs/musicblocks/pull/4707). To test, simply write your musicblocks program in Javascript in the editor and press the convert button. Note that the only blocks supported are those supported by block to code conversion, so it won't work on every single block possible, but will work on most of them. - -<a href="https://ibb.co/qLNNyH8W"><img src="https://i.ibb.co/V0ggjFGQ/Screenshot-2025-06-14-at-2-25-05-PM.png" alt="Conversion Example"></a> - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Minimizing file size of config file - - **Solution:** Merging configs, and using minified JSON for loading. - -- **Challenge:** Never-seen-before git errors when trying to push commit - - **Solution:** Image size as part of the documentation was too large, had to compress it. - ---- - -## Key Learnings - -- Deepened understanding of git. -- Improved skills in **debugging**, **code design**, and **collaboration workflows**. - ---- - -## Next Week’s Roadmap - -- Begin debugger project -- Being able to set breakpoints in the code -- Add ability to trigger status block in the code as the debugger - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-MebinThattil-week02.md b/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-MebinThattil-week02.md deleted file mode 100644 index c0bb9d9c..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-MebinThattil-week02.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: "GSoC ’25 Week 02 Update by Mebin J Thattil" -excerpt: "Fine-Tuning, Deploying, Testing & Evaluations" -category: "DEVELOPER NEWS" -date: "2025-06-14" -slug: "2025-06-14-gsoc-25-mebinthattil-week2" -author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" -tags: "gsoc25,sugarlabs,week02,mebinthattil,speak_activity" -image: "assets/Images/GSOCxSpeak.png" ---- - -<!-- markdownlint-disable --> - -# Week 02 Progress Report by Mebin J Thattil - -**Project:** [Speak Activity](https://github.com/sugarlabs/speak) -**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-08 - 2025-06-14 - ---- - -## Goals for This Week - -- **Goal 1:** Setup AWS for Fine-Tuning. -- **Goal 2:** Fine-Tune a small model on a small dataset. -- **Goal 3:** Deploy the model on AWS and create an API endpoint. -- **Goal 4:** Test the endpoint using a python script. -- **Goal 5:** Evaluate the model responses and think about next steps. - ---- - -## This Week’s Achievements - -1. **Setup AWS for Fine-Tuning** - - Setup AWS SageMaker. - - Provisioned GPUs on AWS SageMaker to fine-tune Llama3-1B foundation model. - -2. **Dataset & Cleaning** - - Used an open dataset. It was a dataset about conversations between a student and a teacher. - - The dataset was cleaned and converted into a format that Llama needed for fine-tuning. - - Wrote a small script to convert the dataset into a format that Llama can understand. - - The dataset along with the script is available [here](https://github.com/mebinthattil/Education-Dialogue-Dataset). - -3. **Fine-tuning** - - Fine-tuned the model on a small set of the dataset, just to see how it performs and to get familar with AWS SageMaker. - - The training job ran on a `ml.g5.2xlarge` instance. - - The hyperparameters that were set so as to reduce memory footprint and mainly to test things. I'll list the hyperparameters, hoping this would serve as documentation for future fine-tuning. - - **Hyperparameters**: - - | Name | Value | - |----------------------------------|----------------------------------------------------| - | add_input_output_demarcation_key | True | - | chat_dataset | True | - | chat_template | Llama3.1 | - | enable_fsdp | False | - | epoch | 5 | - | instruction_tuned | False | - | int8_quantization | True | - | learning_rate | 0.0001 | - | lora_alpha | 8 | - | lora_dropout | 0.08 | - | lora_r | 2 | - | max_input_length | -1 | - | max_train_samples | -1 | - | max_val_samples | -1 | - | per_device_eval_batch_size | 1 | - | per_device_train_batch_size | 4 | - | preprocessing_num_workers | None | - | sagemaker_container_log_level | 20 | - | sagemaker_job_name | jumpstart-dft-meta-textgeneration-l-20250607-200133| - | sagemaker_program | transfer_learning.py | - | sagemaker_region | ap-south-1 | - | sagemaker_submit_directory | /opt/ml/input/data/code/sourcedir.tar.gz | - | seed | 10 | - | target_modules | q_proj,v_proj | - | train_data_split_seed | 0 | - | validation_split_ratio | 0.2 | - -4. **Saving the model** - - The safetensors and other model files were saved in an AWS S3 bucket. The URI of the bucket is: ``` s3://sagemaker-ap-south-1-021891580293/jumpstart-run2/output/model/ ``` - -5. **Deploying the model** - - The model was deployed on AWS SageMaker and an API endpoint was created. - -6. **Testing the model** - - A python script was written to test the model using the API endpoint. - -7. **Evaluation** - - The model responses were tested using the same questions used in my [benchmark](https://llm-benchmarking-sugar.streamlit.app/) done before. - - ---- - -## Unexpected Model Output - -- After fine-tuning the model, I noticed that the model was producing some unexpected output. I expected the model to behave like general chatbot but in a more friendly and teacher-like manner. While the model's responses did sound like a teacher, the model would often try to create an entire chain of conversations generating the next response from a students perspective and then proceeed to answer itself. -- This behaviour was becaues of the way the dataset was strucutred. The dataset was enssentially a list of back and forth conversations between a student and a teacher. So it makes sense that the model would try to create a chain of conversations. But this is not what we need from the model. -- The next step is to change the strucutre of the dataset to make it just answer questions, but also to make it more conversational and understand the nuaces of a chain of conversations. -- The temporary fix was the add a stop statement while generating responses and also tweaking the system prompt. But again, this is not the right way to go about it. The right was is to change the dataset structure. - ---- - -## Sample model output with stop condition - - - ---- - -## Key Learnings - -- Structure of dataset needs to be changed, in order to make it more conversational and understand the nuances of a chain of conversations. - ---- - -## Next Week’s Roadmap - -- Re-structure the dataset -- Re-Train and Fine-Tunethe model on the new dataset -- Deploy, create endpoint and test the model on the new dataset -- Evaluate the model on the new dataset and add to benchmarks - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - diff --git a/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-firepheonix-week02.md b/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-firepheonix-week02.md deleted file mode 100644 index ee57b80e..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-firepheonix-week02.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "GSoC '25 Week 2 Update by Shubham Singh" -excerpt: "Adding the entire prototyped interface ON TO the music blocks" -category: "DEVELOPER NEWS" -date: "2025-06-14" -slug: "2025-06-14-gsoc-25-firepheonix-week02" -author: "@/constants/MarkdownFiles/authors/shubham-singh.md" -tags: - - gsoc25 - - sugarlabs - - week02 - - firepheonix -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 2 Progress Report by Shubham Singh - -**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) -**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-06-08 – 2025-06-15 - ---- - -## Goals for This Week - -- Basic UI for Image Upload/Real-time Video upload and adjustment. -- Integrating the developed UIs onto the widget blocks within Music Blocks. -- Researching existing audio integration patterns in the phrase maker and note blocks. - ---- - -## This Week's Achievements - -1. **Interface Implementation for Lego Notations** - - Successfully integrated the LegoBricks block directly onto the Music Blocks canvas. - - Modified 6 different files to implement an entirely new block type. - - Music Blocks already has sophisticated color detection for internal pixels, but couldn't detect colors from external sources like uploaded images or webcam feeds — this limitation was addressed. - - The codebase proved beautifully encapsulated and thoroughly documented, making the learning curve smoother. -  - -2. **Real-time Video Integration** - - Implemented real-time video functionality through webcam integration. - - Added full editing capabilities and canvas manipulation for live video feeds. - - Interface provides seamless interaction between video feed and detection algorithms. -  - -3. **Export Mechanism Research** - - Conducted extensive research into existing export mechanisms within Music Blocks. - - Deep-dived into Phrase Maker widget documentation and codebase. - - Studied how different blocks export output as both MIDI files and action blocks. -  - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** UI integration complexity — getting the UI integrated into Music Blocks proved more challenging than expected due to intricate dependencies and specific implementation patterns required by the block system. -**Solution:** Leveraged multiple resources including mentor consultations, existing documentation on "how to add new blocks," and analyzed previous implementations for reference patterns. - -- **Challenge:** User workflow design — determining optimal user workflow for the Lego Bricks block required careful consideration of user interaction patterns and integration with existing functionality. -**Solution:** Scheduled focused discussion with mentor during regular meeting to analyze phrase maker export functionality, gaining crucial insights into user experience patterns and technical approaches. - ---- - -## Key Learnings - -- Gained comprehensive understanding of **output mechanisms** and how different blocks handle their output generation and processing. -- Deepened appreciation for **code architecture** including inheritance patterns, code modularity, and custom return types within the Music Blocks ecosystem. -- Improved skills in **development workflow** including exports, imports, code reusability, documentation practices, and collaborative development workflows. - ---- - -## Next Week's Roadmap - -- Implement comprehensive mapping of musical notes to Lego brick colors. -- Complete the core implementation during weeks 2 and 3, ensuring robust functionality and thorough testing. -- Focus on algorithmic challenges for note-to-color mapping system. - ---- - -## Resources & References - -- **Project Issue:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) -- **Music Blocks Repository:** [sugarlabs/musicblocks](https://github.com/sugarlabs/musicblocks) -- **Documentation:** Music Blocks Developer Guide - ---- - -## Acknowledgments - -Thank you to my mentors [Walter Bender](https://github.com/walterbender) and [Devin Ulibarri](https://github.com/pikurasa) for invaluable guidance throughout this development phase. Special thanks to Walter for his advice during our biweekly meeting on how the phrase maker exports output as ACTION blocks. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-mostlyk-week02.md b/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-mostlyk-week02.md deleted file mode 100644 index 4b0d5ad4..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-mostlyk-week02.md +++ /dev/null @@ -1,286 +0,0 @@ ---- -title: "GSoC '25 Week 2 Update by Krish Pandya" -excerpt: "From initial GTK4 porting to building a solid foundation with separate C and Python libraries" -category: "DEVELOPER NEWS" -date: "2025-06-14" -slug: "2025-06-14-gsoc-25-mostlyk-week02" -author: "@/constants/MarkdownFiles/authors/krish-pandya.md" -tags: "gsoc25,sugarlabs,week02,mostlyk" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 2: Strategic Pivot and Foundation Building - -**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky), [Juan Pablo Ugarte](https://github.com/xjuan) -**Reporting Period:** June 06, 2025 till June 14, 2025 - ---- - - -## The Meeting that changed everything - -On Friday(06-06-2025), we had a pivotal video call with Juan Pablo Ugarte and Ibiam Chihurumnaya that completely reshaped the porting approach. -What started as a discussion about my initial porting work evolved into something much more strategic and forward-thinking. - -> While the time of writing this, another meet that happened on 13-06-2025 , we discussed about the API versioning and updating with pytest, ideas about testing, more porting golden advice, more about this on next week's blog. - -### The New Architecture Vision - -The mentors introduced a brilliant modular approach that addresses the core challenges of the GTK4 migration: - -**1. Two Separate Libraries Strategy** -- C Library 'sugar-ext': Core objects and reusable GTK widgets -- Python Wrapper Library: Python widgets and wrapper functions - - - -> Subject to change - -**2. Independent Development & Testing** -Each library will be developed in its own repository with simple Python example scripts. This approach offers several advantages: -- Clear separation of concerns between C and Python components -- Easier debugging and testing -- Better CI/CD pipeline management -- Modular, incremental development that reduces complexity - -**3. Meson Build System Foundation** -We'll use Meson's shared library template from GNOME Builder as our base. This gives us: -- Modern build system designed for GTK4 -- Better dependency management -- Cleaner project structure - -### Why This Approach Made Sense - -The more I thought about this strategy, the more I realized how elegant it is. Instead of trying to port everything at once (my initial approach, by changing the orignal toolkit and it's systems), we're building a solid foundation that can support the entire Sugar ecosystem. This modular approach means: - -- Maintainability — Each component can be updated independently -- Testing — Smaller, focused libraries are easier to test thoroughly -- Future-proofing — The architecture can adapt as GTK continues to evolve -- Support — Due to the new build system, we would have more support and we can also remove things we find deprecated. ---- - -## Implementation - -Following the meeting – I immediately got to work implementing. -The result that came out was [Pull Request #1](https://github.com/sugarlabs/sugar-ext/pull/1) in the new 'sugar-ext' repository. - -### What I Built - -**Project Structure:** -- Complete Meson build system setup -- GObject Introspection integration for seamless Python bindings -- Initial API implementation (starting with XO Colors for testing) -- Comprehensive documentation and development tools - -**Key Technical Decisions:** -```c -// API versioning strategy -api_version = '1.0' // Maintaining compatibility with existing SugarExt -package_version = '0.122.0' // Following Sugar's versioning convention - -// GIR configuration for Python bindings -symbol_prefix: 'sugarext' -identifier_prefix: 'SugarExt' -``` - -> This was discussed later in the meet and we decided to keep the packages version 2.0 or 4.0 because GTK4. Will be confirmed by the next blog, - -- Included comprehensive build and test scripts - -### Testing Framework - -The project includes a robust testing setup: -```bash -meson test -C builddir -``` - -This runs the test suite, validating that the C library builds correctly and the test written should pass. - ---- - -### To my Fellow Devs - -- I have few files that can help you get your setup right. If you like clangd and use it as your LSP. Here's the .clangd configuration I used for sugar-ext. - -```yaml -CompileDatabase: ./builddir - -If: - PathMatch: .*\.(c|h)$ -CompileFlags: - Add: [ - -I./src, - -I./builddir, - -I/usr/include/gtk-4.0, - -I/usr/include/glib-2.0, - -I/usr/lib/glib-2.0/include, - -I/usr/include/pango-1.0, - -I/usr/include/harfbuzz, - -I/usr/include/fribidi, - -I/usr/include/gdk-pixbuf-2.0, - -I/usr/include/cairo, - -I/usr/include/freetype2, - -I/usr/include/libpng16, - -I/usr/include/pixman-1, - -I/usr/include/graphene-1.0, - -I/usr/lib/graphene-1.0/include, - -I/usr/include/libmount, - -I/usr/include/blkid, - -I/usr/include/sysprof-6, - -I/usr/local/include/sugar-ext, - -D_FILE_OFFSET_BITS=64 - ] - -Diagnostics: - ClangTidy: - Add: [ - readability-*, - bugprone-*, - performance-*, - misc-* - ] - Remove: [ - modernize-*, - readability-isolate-declaration, - readability-function-cognitive-complexity - ] - UnusedIncludes: Strict - -InlayHints: - Enabled: Yes - ParameterNames: Yes - DeducedTypes: Yes - -Hover: - ShowAKA: Yes - -Index: - Background: Build - -Completion: - AllScopes: Yes - -Format: - Style: GNU -``` - -- And if you are using VSCode and the C/C++ extension, here's the c_cpp_properties.json. -```json -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/**", - "${workspaceFolder}/builddir", - "/usr/include/gtk-4.0", - "/usr/include/pango-1.0", - "/usr/include/fribidi", - "/usr/include/harfbuzz", - "/usr/include/gdk-pixbuf-2.0", - "/usr/include/cairo", - "/usr/include/freetype2", - "/usr/include/libpng16", - "/usr/include/pixman-1", - "/usr/include/graphene-1.0", - "/usr/lib/graphene-1.0/include", - "/usr/include/glib-2.0", - "/usr/lib/glib-2.0/include", - "/usr/include/libmount", - "/usr/include/blkid", - "/usr/include/sysprof-6" - ], - "defines": [ - "_FILE_OFFSET_BITS=64" - ], - "cStandard": "gnu11", - "cppStandard": "c++17", - "intelliSenseMode": "linux-gcc-x64", - "compilerPath": "/usr/bin/gcc", - "compileCommands": "${workspaceFolder}/builddir/compile_commands.json" - } - ], - "version": 4 -} -``` - -## Lessons from the PR Review Process - -- To be added on week 3 as it gets merged! - - -# Migration List - -- Here Use as-is means if we decide to keep it we use it or it's newer version or alternatives. Port meaning we would have to change stuff, and whenever I have mentioned GTK4 we will use the new API directly rather than implementing from scratch. -## C Objects Migration List - -| Object | Dependencies | Purpose | Port/Use GTK4 | -|--------|--------------|---------|---------------| -| sugar-grid.c/h | GLib + GDK | Grid-based layout calculations | Port | -| sugar-fatattr.c/h | Pure C, sys headers | FAT filesystem attribute utilities | Use as-is | -| acme-volume.c/h | GLib, ALSA | Audio volume control | Use as-is | -| acme-volume-alsa.c/h | GLib, ALSA | ALSA backend for volume control | Use as-is | -| sugar-wm.c/h | GLib, GDK, X11 | Window manager interaction utilities | Port | -| sugar-clipboard.c/h | GLib, GTK3 | Clipboard helper functions | Port (GdkClipboard) | -| eggdesktopfile.c/h | GLib, GTK3, GDK | Desktop file parsing and launching | Port | -| sugar-key-grabber.c/h | GLib, GDK, X11 | Global key binding system | Port (GTK4 shortcuts) | -| sugar-cursor-tracker.c/h | GLib, GDK, X11, XInput2 | Mouse cursor visibility tracking | Port (GTK4 events) | -| sugar-gesture-grabber.c/h | GLib, GDK, X11, XInput2 | Global gesture capture system | Port (GTK4 gestures) | -| sugar-event-controller.c/h | GLib, GTK4 | Base event controller | Port | -| sugar-long-press-controller.c/h | GLib, GTK4 | Long press gesture detection | Port | -| sugar-swipe-controller.c/h | GLib, GTK4 | Swipe gesture detection | Port | -| sugar-touch-controller.c/h | GLib, GTK4 | Touch event handling | Port | -| sugar-zoom-controller.c | GLib, GTK4 | Zoom gesture detection | Port | -| sugar-rotate-controller.c | GLib, GTK4 | Rotation gesture detection | Port | -| eggaccelerators.c/h | GLib, GTK3, GDK, X11 | Keyboard accelerator handling | Port | -| eggsmclient.c/h | GLib | Session management client | Use as-is | -| eggsmclient-xsmp.c/h | GLib, X11, ICE, SM | XSMP session management backend | Use as-is | -| gsm-app.c/h | GLib | Session management application handling | Use as-is | -| gsm-client.c/h | GLib | Session management client base | Use as-is | -| gsm-client-xsmp.c/h | GLib, X11, ICE, SM | XSMP client implementation | Use as-is | -| gsm-session.c/h | GLib | Session management core | Use as-is | -| gsm-xsmp.c/h | GLib, X11, ICE, SM | XSMP protocol implementation | Use as-is | - - - -## Next Steps: Building the Foundation - -### Immediate Priorities (Week 3) - -1. Finalize C Library Scaffold -- Address remaining PR feedback -- Implement proper copyright and licensing -- Add core Sugar widgets starting with `sugar-grid` -- Sugar-Grid was added on 14-June-2025 while I am writing this. - -2. Begin Python Wrapper Development -- Set up the Python-side repository -- Create example scripts demonstrating usage - - - ---- - - -## Resources & References - -- Project Page – [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) -- New C Library - [sugar-ext repository](https://github.com/sugarlabs/sugar-ext) -- Active PR - [Establish C library base template with Meson for GTK4](https://github.com/sugarlabs/sugar-ext/pull/1) -- Sugar Toolkit Repository(original) – [sugar-toolkit-gtk3](https://github.com/sugarlabs/sugar-toolkit-gtk3) -- GTK4 Migration Guide – [docs.gtk.org/gtk4/migrating-3to4.html](https://docs.gtk.org/gtk4/migrating-3to4.html) - - ---- - -## Acknowledgments - -Huge thanks to Juan Pablo Ugarte first of all for being the official mentor and Ibiam Chihurumnaya for the guidance that that changed this project's direction. Their architectural vision has transformed porting into a comprehensive modernization effort. Thanks also to Walter Bender for mentorship. - ---- - -THe architecture is building itself, and I'm excited to lay down the foundations! - diff --git a/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-saumya-week02.md b/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-saumya-week02.md deleted file mode 100644 index bc2cd5d2..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-14-gsoc-25-saumya-week02.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: "GSoC '25 Week 02 Update by Saumya Shahi" -excerpt: "This week focused on documenting the brick tree structure, refining SVG path generation, and learning testing tools like Storybook." -category: "DEVELOPER NEWS" -date: "2025-06-14" -slug: "2025-06-14-gsoc-25-saumya-shahi-week02" -author: "@/constants/MarkdownFiles/authors/saumya-shahi.md" -tags: "gsoc25,sugarlabs,week02,saumya-shahi" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 02 Progress Report by Saumya Shahi - -**Project:** [Masonry Module - Music Blocks v4](https://github.com/sugarlabs/musicblocks-v4) -**Mentors:** [Anindya Kundu](https://github.com/meganindya/) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-08 – 2025-06-14 - ---- - -## Goals for This Week - -- Refine and complete configuration-driven rendering logic. -- Test rendering of multiple brick types and validate correctness using sample input. -- Document how brick configurations and connections should be modeled. -- Start building foundational elements for brick tree rendering. - ---- - -## This Week's Achievements - -1. **Dynamic SVG Brick Rendering** - - Finalized implementation for rendering SVG paths dynamically based on type-specific configurations. - - Different bricks (e.g., nested bricks, simple bricks, expression bricks) now render accurately according to their label sizes, scale, and other config props. - - Output adjusts responsively with different numbers of arguments, notches, and labels. - -2. **Rendered Output Validation & Screenshots** - - Verified each visual brick against expected path geometry. - - Screenshots below show rendered bricks: -  -  -  - -2. **Bug Fix: Left SVG Path Issue** - - * Fixed a critical error in path rendering for bricks — the left edge generation wasn’t calculating offsets correctly. - * Cleaned up related path logic to improve readability and scalability for future nested structures. - -3. **Storybook & Testing Familiarization** - - * Understood how Storybook is used for visual component testing. - * Learnt how to set up unit tests and component test files. - * Setup groundwork for adding future test cases. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Mapping the brick tree vs AST was initially confusing. -**Solution:** Spent focused time breaking down what each structure is supposed to represent and clarified use cases. - -- **Challenge:** SVG left path errors were hard to trace visually. -**Solution:** Used visual diffing and debugger to narrow down bounding box and stroke-width miscalculations. - ---- - -## Key Learnings - -- Improved understanding of **SVG rendering logic** and path construction. -- Got hands-on exposure to **Storybook**, and how visual tests can improve modular development. -- Understood the **difference between data representations** for view (brick tree) and logic (AST). - - ---- - -## Next Week's Roadmap - -- Start implementing **multi-brick layout rendering**: bricks with children rendered as a tree in the workspace. -- Introduce bounding box calculation utilities for each rendered brick. -- Plan initial strategy for brick connection detection and snapping logic. - ---- - -## Resources & References - -- **Brick Rendering:** [Google Doc](https://docs.google.com/document/d/1UJXh3734S138BoTsGulzeTlZXstyvWd6syJK2eclMKI/edit?tab=t.dxoea5urpxyl#heading=h.wa29sjgrasfn) -- **SVG Path Reference:** [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) -- **Playground for Manual SVG Paths:** [SVG Path Editor](https://yqnn.github.io/svg-path-editor/) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for support and insightful feedback throughout the week. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-AmanNaik-week02.md b/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-AmanNaik-week02.md deleted file mode 100644 index e7ae7ed4..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-AmanNaik-week02.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "DMP ’25 Week 2 Update by Aman Naik" -excerpt: "This week's focus was on creating a story builder feature in such a way that it engages creativity of the children." -category: "DEVELOPER NEWS" -date: "2025-06-15" -slug: "2025-06-15-dmp-25-AmanNaik-week02" -author: "@/constants/MarkdownFiles/authors/amannaik247.md" -tags: "dmp25,writeactivity,write,sugarlabs,week01,amannaik247" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 2 Progress Report by Aman Naik - -**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) -**Reporting Period:** 2025-06-09 – 2025-06-15 - ---- - -## Goals for This Week - -- **Goal 1:** Design a story builder feature to help children write stories -- **Goal 2:** Explore ways to integrate AI into the feature -- **Goal 3:** Document the architecture and workflow -- **Goal 4:** Focus on developing creative features that support learning - ---- - -## This Week’s Achievements - -1. **Explored Engaging Approaches to Story Writing** - - Through guidance from mentors in biweekly and one-on-one meetings, I explored effective ways to encourage children to write creatively. This included analyzing architecture ideas that support active participation in storytelling. - -2. **Finalized the Architecture for the Story Builder Feature** - - After research and discussions, I finalized an architecture that aids students in story writing while ensuring that the AI guides rather than writes the story for them. - -  - -  - -3. **Created Documentation for Future Reference** - - I’ve documented the feature's flow and design so it can be referred to later. [Link](https://docs.google.com/document/d/14V_FreatUU-gGgiHRdlvNDUXUgmBTWIeFyDaap38RnA/edit?usp=sharing) - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** The grammar correction feature was too strict for learning environments. - **Solution:** Since the goal is to foster creativity, I decided to shift focus from strict grammar correction to more engaging, story-focused features. Grammar support can be introduced later as an enhancement. - -- **Challenge:** Stories don’t always follow a fixed pattern (e.g., not every story has a villain). - **Solution:** I designed the AI to categorize responses into typical story elements automatically. This adaptive framework allows story parts like “villain” or “sidekick” to remain optional and dynamically appear based on user input. - -- **Challenge:** Prevent the AI from writing the story directly. - **Solution:** Due to the resource constraints of Sugar’s environment, I couldn’t run large models locally. I used Hugging Face Spaces to host the models externally and used their APIs inside Sugar for lightweight testing. This also helped keep the feature lightweight and modular. - ---- - -## Key Learnings - -**Developed Engaging Pedagogical Strategies for Story Writing** - - Mentors helped me explore interactive ways to encourage children’s creativity, shifting from passive AI responses to more guided interactions. - -**Designed and Finalized a Guided AI Architecture** - - I developed a modular design that prompts students to build stories step by step, ensuring they stay involved and learn narrative structure. - -**Learned Effective Student-AI Interaction Techniques** - - I realized that giving the AI a playful personality that gently prompts students can make the writing process more enjoyable and educational. - ---- - -## Next Week’s Roadmap - -- Begin coding the designed architecture -- Develop a basic Streamlit application to test the feature outside Sugar -- Work on feedback provided by mentors - ---- - -## References - -Here’s an insightful video shared by Walter Bender: -[CBS: The Thinking Machine (MIT Film, 1961)](https://www.youtube.com/watch?v=HCl19WKrfeg) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for their continued support and encouragement! - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-justin212407-week02.md b/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-justin212407-week02.md deleted file mode 100644 index f17ce41e..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-justin212407-week02.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "DMP’25 Week 02 Update by Justin Charles" -excerpt: "Completed SVG path logic for all brick types and documented props and rendering states" -category: "DEVELOPER NEWS" -date: "2025-06-15" -slug: "2025-06-15-dmp-25-justin212407-week02" -author: "@/constants/MarkdownFiles/authors/justin-charles.md" -tags: "dmp25,sugarlabs,week2,justin212407" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 2 Progress Report by Justin Charles - -**Project:** Music Blocks 4 Masonry -**Mentors:** [Anindya Kundu](https://github.com/meganindya/) -**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Reporting Period:** 2025-06-09 - 2025-06-15 - ---- - - -## Goals for This Week - -- Finalize SVG path logic for all three types of bricks -- Categorize and document all props passed into bricks -- Identify all visual states a brick can be rendered in -- Differentiate props and states across brick types -- Write comprehensive tests to verify correctness - ---- - -## This Week’s Highlights - -### 1. Full SVG Path Generation Logic - -- Completed `generatePath` support for all three brick types (Simple, Expression and Compound) -- Rendering now properly reflects scaling, argument slots, top/bottom notches, and label widths -- Edge cases such as bricks with long labels or stacked arguments handled correctly - -### 2. Brick Input Prop Categorization - -- Catalogued all props across types (`strokeWidth`, `scaleFactor`, `bBoxLabel`, `bBoxArgs`, etc.) -- Documented their role in layout computation and how they influence final SVG shape - -### 3. Brick State Documentation - -- Mapped out all possible states a brick can be rendered in (e.g. with/without label, multiple args, missing notches) -- This will help improve clarity for both debugging and future features - -### 4. Type-wise Prop/State Differentiation - -- Clearly separated the logic for how each brick type handles its props and rendering states -- This abstraction allows brick-specific customizations without breaking general rendering flow - -### 5. Unified Brick Test File - -- Created a comprehensive Jest test file to validate path generation against expected output -- Covers edge cases like empty arguments, multiple stacked args, and variable heights - -📄 Reference: [Props & States Document – Tab 3](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.99d6uc7vheda) - ---- - -## Challenges & Solutions - -**Challenge: Mismatched Bounding Box Heights in Some Brick Types** -In initial tests, actual brick heights didn’t match the combined heights of `bBoxLabel` and `bBoxArgs`. -**Solution:** Identified a calculation flaw in vertical layout stacking. Corrected it by properly summing scaled heights and applying consistent spacing logic in path computation. - -**Challenge: Supporting All Brick Variants with Shared Logic** -Bricks share many layout rules, but also diverge in rendering. -**Solution:** Broke down `generatePath` into side-specific functions (`_generateLeft`, `_generateRight`, etc.) with override support depending on brick type and features like notches. - ---- - -## Key Learnings - -- Improved understanding of scalable vector graphics and path-based layout systems -- Gained hands-on experience in building testable, modular rendering logic -- Developed systematic thinking around UI state modeling and prop-driven rendering behavior - ---- - -## Next Week’s Roadmap - -- Create React Components(View) to render the bricks with all its properties. -- Create the Model components for the different Brick Types. - ---- - -## Resources & References - -- [Props & States Document](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.99d6uc7vheda) -- [musicblocks-v4 Repository](https://github.com/sugarlabs/musicblocks-v4) - ---- - -## Acknowledgments - -Thanks to my mentors for helping review the rendering logic and for encouraging a structured approach to SVG layout systems. Their early feedback made the path code significantly more robust and maintainable. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-therealharshit-week02.md b/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-therealharshit-week02.md deleted file mode 100644 index 861daadc..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-15-dmp-25-therealharshit-week02.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: "DMP ’25 Week 02 Update by Harshit Verma" -excerpt: "To develop a basic FastAPI server and integrate it with Pippy." -category: "DEVELOPER NEWS" -date: "2025-06-15" -slug: "2025-06-15-dmp-25-therealharshit-week02" -author: "@/constants/MarkdownFiles/authors/harshit-verma.md" -tags: "dmp25,sugarlabs,week02,therealharshit" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 02 Progress Report by Harshit Verma - -**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-09 - 2025-06-15 - ---- - -## Goals for This Week - -- **Goal 1:** Set up a basic FastAPI server. -- **Goal 2:** Integrate a Hugging Face model. -- **Goal 3:** Add 'Run and Debug' buttons to Pippy UI. -- **Goal 4:** Connect Pippy to the FastAPI Server. - ---- - -## This Week’s Achievements - -1. **Built FastAPI Server with `/debug` Endpoint** - - Created a simple FastAPI app that listens for POST requests at `/debug`. - - The endpoint accepts raw Python code, forwards it to the model, and returns debug tips. - -2. **Integrated Hugging Face Model** - - Loaded a lightweight model (Qwen/Qwen2.5-1.5B-Instruct) from Hugging Face using `transformers`. - - Connected the model with the `/debug` endpoint to generate relevant debugging suggestions. - -3. **Updated Pippy UI with Debugging Controls** - - Added 'Run and Debug' buttons to the Pippy interface. -  - - This was designed to trigger actions like execute code and get debugging feedback. - -4. **Connected Pippy to the FastAPI Server** - - Implemented functionality to extract code from the Pippy editor. - ```Python - #To extract the source code - - def _get_current_code(self): - pippy_tmp_dir = '%s/tmp/' % self.get_activity_root() - current_file = os.path.join( - pippy_tmp_dir, - self._source_tabs.get_current_file_name() - ) - - try: - with open(current_file, 'r') as f: - return f.read() - except Exception as e: - print(f"Error reading file {current_file}: {e}") - return None - ``` - - Successfully set up an API call from Pippy to the FastAPI server when the 'Run and Debug' button is clicked. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Running the model locally on CPU. - **Solution:** Faced performance limitations due to lack of GPU support. I resolved this by selecting a small, efficient model from Hugging Face. - -- **Challenge:** Using GTK for Pippy UI integration. - **Solution:** Since GTK was new to me, adding buttons and handling events required exploring GTK documentation and existing Sugar activity patterns. With guidance and trial-and-error, I successfully added and wired up the 'Run and Debug' button to Pippy’s interface. - ---- - -## Key Learnings - -- Learned how to build and structure an API with FastAPI. -- Gained experience integrating Hugging Face models programmatically. -- Understood how to bridge frontend (Pippy) with backend (FastAPI) effectively. -- Improved at working across virtual machines, ports, and networking setups. - ---- - -## Next Week’s Roadmap - -- Improve prompt engineering for better debugging tips. -- Add visual display of debug tips in the Pippy interface. -- Integrate sugar-ai with Pippy. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-BishoyWadea-week02.md b/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-BishoyWadea-week02.md deleted file mode 100644 index da2da74a..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-BishoyWadea-week02.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: "GSoC ’25 Week 02 Update by Bishoy Wadea" -excerpt: "Broken Calculator" -category: "DEVELOPER NEWS" -date: "2025-06-15" -slug: "gsoc-25-BishoyWadea-week01" -author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" -tags: "gsoc25,sugarlabs,week02,BishoyWadea" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Bishoy Wadea - -**Project:** [Broken Calculator](https://github.com/Bishoywadea/Broken-Calculator) -**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) -**Reporting Period:** 2025-06-08 - 2025-06-15 - ---- - -## Goals for This Week - -- **Goal 1:** Define game features and core mechanics. -- **Goal 2:** Design and plan a child-friendly, interactive game UI. -- **Goal 3:** Implement the core game logic. - ---- - -## This Week’s Achievements – *Broken Calculator Game* - -1. **Initial Setup & Core Functionality** - - Added starter files and project structure. - - Implemented basic game manager functionality to handle state, inputs, and equation validation. - - commit: [Initial Commit](https://github.com/Bishoywadea/Broken-Calculator/commit/9615fe64467e538e4b2d3df2ba6a0059177d31a7) - -2. **UI Foundation and Target Display** - - Created basic UI layout with the target number display. - - Integrated equation panel and on-screen keyboard for child-friendly input. - - commit: [UI Target + Equation Panel](https://github.com/Bishoywadea/Broken-Calculator/commit/fb52777a698d0846b3012140a796024edef5e577) - -3. **Button Logic and Interaction** - - Added calculator buttons and implemented event handling logic. - - Created class-based structure for reusable buttons and interactions. - - commit: [Calc Buttons Logic](https://github.com/Bishoywadea/Broken-Calculator/commit/f5201b9cf17c37fb70502fda55fd190b2143bca2) - -4. **Gameplay Enhancements** - - Added scoring system and validation logic for player input. - - Implemented completion message upon solving the puzzle correctly. - - commit: [Game Logic & Completion](https://github.com/Bishoywadea/Broken-Calculator/commit/2f985799faab59d590adae38b349c20dc0b432f9) - -5. **Visual & UX Improvements** - - Introduced dark theme palette for better visual experience. - - Added menu buttons, teacher image, and stars animation for child appeal. - - Relocated help button for better accessibility. - - commit: [UI/UX Polish](https://github.com/Bishoywadea/Broken-Calculator/commit/c97ade0610d606672a99522b944ed4ec24018c02) - ---- - -## Challenges & Solutions - -- **Challenge:** Handling math equation input using only a restricted set of digits/operators. - **Solution:** Wrote logic to dynamically validate inputs and compute results with constraints. - -- **Challenge:** Making the interface engaging for children. - **Solution:** Added animations, character images, and accessible visual elements. - ---- - -## Key Learnings - -- Gained proficiency in using **Pygame** for interactive game development. -- Improved understanding of **map projections** and **GeoJSON** parsing. -- Learned about structuring a project for open-source collaboration (commits, PRs, README, file organization). -- Practiced test-driven logic development and clean UI design tailored for children. - ---- - -## Key Learnings - -- Enhanced skills in **Pygame** UI design and interaction patterns. -- Practiced breaking down UI into components (buttons, input panels, layout regions). -- Understood how to make gameplay intuitive without written instructions—especially for kids. - -## Next Week’s Roadmap - -### Soma Cubes Game: Initial Insights & Exploration -- Begin designing core mechanics and gameplay flow for a Soma Cubes puzzle activity. -- Prototype user interactions: piece manipulation, rotation, and snapping into place. -- Investigate how to integrate puzzle constraints and feedback for users. -- Sketch out UI layout and controls tailored for children. - ---- - -### Fix Open Issues - -#### Four-Color Map Activity -- **[#1 Move buttons on the activity canvas to the activity toolbar](https://github.com/Bishoywadea/Four-Color-Map/issues/1)** - Adjust UI so that control buttons (e.g., Undo, Help, Menu) are relocated from the map canvas into a consistent toolbar above or beside it. -- **[#2 Sugarize activity icon](https://github.com/Bishoywadea/Four-Color-Map/issues/2)** - Update the icon to conform with Sugar activity design standards—ensure correct dimensions, transparency, and consistency with Sugar's visual language. - -#### Broken Calculator -- **[#1 Make calculator fill activity canvas](https://github.com/Bishoywadea/Broken-Calculator/issues/1)** - Refactor layout to scale the calculator panel to full canvas size at any screen resolution or window rescaling. -- **[#2 Improve UI](https://github.com/Bishoywadea/Broken-Calculator/issues/2)** - Polish button styles, spacing, theme consistency (light/dark), and overall visual clarity based on user feedback. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-Nikhil-Bhatt-week02.md b/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-Nikhil-Bhatt-week02.md deleted file mode 100644 index 675ec5cc..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-Nikhil-Bhatt-week02.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: "GSoC '25 Week 02 Update by Nikhil Bhatt" -excerpt: "Implemented edit functionality for project repositories and introduced a forking mechanism for collaborative workflows." -category: "DEVELOPER NEWS" -date: "2025-06-10" -slug: "2025-06-10-gsoc-25-nikhilbhatt-week02" -author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" -tags: "gsoc25,sugarlabs,week02,nikhilbhatt" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 02 Progress Report by Nikhil Bhatt - -**Project:** [Git backend for Musicblocks](https://github.com/benikk/musicblocks-backend) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Reporting Period:** 2025-06-7 – 2025-06-14 - ---- - -## Goals for This Week - -- **Implement an edit route** to allow users to update project data securely using hashed keys. -- **Design and implement a forking mechanism** where users can fork existing project repositories into new independent ones. -- **Integrate project origin tracking** in forked repos through metadata. - ---- - -## This Week's Achievements - -1. **Edit Project Functionality** - - Created a secure API endpoint that allows users to update their project repository content using a key-authenticated system. - - The backend checks the key hash stored in the `metaData.json` before applying any updates. - - PR: [Edit Project API](https://github.com/BeNikk/musicblocks-backend/commit/1f61a089de7d8dbede2d46a101611133a1190bf6) - -2. **Fork Project Repository** - - Developed a new feature that enables students to fork other students' public projects into their own repositories under the same organization. - - Forked repositories retain original content (`projectData.json`, `metaData.json`) and include the original repository link in the metadata (`forkedFrom` field). - - PR: [Fork Feature](https://github.com/BeNikk/musicblocks-backend/commit/d1b7220476dc1fd58c1b38dc59c8a4991871ac45) - -3. **Project Metadata Enhancements** - - Updated the metadata structure to support fork tracking and improve key validation. - - Ensured consistency between project ownership, fork source, and editing rights. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Understanding and handling GitHub’s `SHA` and `Base64` requirements when editing file content through the API. - **Solution:** Read GitHub API docs and integrated `Buffer.from(...).toString('base64')` and used file `sha` to ensure proper file overwrites. - -- **Challenge:** Unsure if re-initializing Octokit and generating a new installation token per request was optimal. - **Solution:** Kept this approach for now as each request is stateless and works correctly. Optimization will be explored after baseline features are stable. - ---- - -## Key Learnings - -- Learned how to **authenticate and authorize edits** to GitHub repos using hashed keys and GitHub’s content API. -- Understood the internal structure of GitHub forks and metadata handling. -- Improved knowledge of **Octokit**, GitHub APIs, and best practices for writing file content (`projectData.json`, `metaData.json`) to a repo. - ---- - -## Next Week's Roadmap - -- Add **pull request functionality** between forked and original projects. -- Improve project listing UI with fork indicators. -- Begin planning for collaborator permissions and PR review workflow. - ---- - -## Resources & References - -- **GitHub API Docs:** [REST Reference](https://docs.github.com/en/rest) -- **Octokit:** [octokit/rest.js](https://github.com/octokit/rest.js) -- **MetaData Example:** `metaData.json` includes `hashedKey`, `theme`, and `forkedFrom`. - ---- - -## Acknowledgments - -Thank you to my mentors and the Sugar Labs community for guidance and feedback, and to the GitHub community for their detailed API documentation and tooling support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-SafwanSayeed-week02.md b/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-SafwanSayeed-week02.md deleted file mode 100644 index 1a23effa..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-SafwanSayeed-week02.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "GSoC '25 Week 2 Update by Safwan Sayeed" -excerpt: "Memory Module Architecture and CRUD Operations Development" -category: "DEVELOPER NEWS" -date: "2025-06-15" -slug: "2025-06-15-gsoc-25-sa-fw-an-week2" -author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" -tags: "gsoc25,sugarlabs,week2,sa-fw-an" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 2 Progress Report by Safwan Sayeed - -**Project:** Music Blocks 4 Program Engine -**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-06-09 - 2025-06-15 - ---- - -## A Blog-style Retrospective - -This week was all about diving deep into the memory architecture for the Music Blocks program engine. After completing our comprehensive AST framework in week 1, we shifted focus to building the foundational memory management system that will power program execution. The challenge was designing a three-scope memory hierarchy (Global, Thread, Local) with full CRUD operations while keeping the implementation clean and focused. - -Working alongside Karan Palan, we expanded our tech spec to include detailed memory module specifications. The mentors provided crucial guidance on scope requirements, emphasizing the need for thread isolation, and multi-level local scope support. - ---- - -## Goals for This Week - -- Complete the memory module technical specification with three-scope architecture details. -- Develop full CRUD operations for global variables accessible from any scope. -- Implement it with tests. - ---- - -## This Week's Highlights - -1. **Memory Module Tech Specification** - - Expanded the tech spec with comprehensive memory architecture documentation covering three-scope system. - - Detailed CRUD operation requirements for global, thread, and local scope variables. - - Link: [Tech Spec Document - Memory Section](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.3xe7coiooljb#heading=h.s3q9swsg3ifd) - - -2. **Memory Module CRUD Operations** - - Started Implementing the CRUD Operations for the Scopes - ---- - -## Challenges & Solutions - -- **Understanding Scope Hierarchy Complexity:** - The three-scope system (Global, Thread, Local) with proper variable shadowing was conceptually challenging. - *Solution:* Studied the existing reference implementation and created detailed diagrams to visualize scope relationships. - - ---- - -## Key Learnings - -- Mastered hierarchical data structure design with proper encapsulation and scope isolation. -- Gained deep understanding of variable shadowing and scope resolution mechanisms. -- Enhanced collaboration skills working on complex architecture with multiple contributors. - ---- - -## Next Week's Roadmap - -- Begin symbol table implementation building on the memory module foundation. -- IR Implementation -- Write comprehensive unit tests for all memory module CRUD operations. - ---- - -## Resources & References - -- **Tech Spec:** [Memory Module Architecture](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.3xe7coiooljb#heading=h.s3q9swsg3ifd) -- **Repository:** [musicblocks-v4](https://github.com/sugarlabs/musicblocks-v4) -- **Reference Implementation:** [For conceptual guidance](https://github.com/sugarlabs/musicblocks-v4-lib/tree/develop/src/execution/scopeexecution/scope) - ---- - -## Acknowledgments - -Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their detailed guidance on memory architecture design and scope management. Their clarification on keeping the focus on memory module fundamentals was crucial for this week's progress. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-diwangshu-week02.md b/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-diwangshu-week02.md deleted file mode 100644 index b5b5884a..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-diwangshu-week02.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: "GSoC ’25 Week 02 Update by Diwangshu Kakoty" -excerpt: "Multi-AI Agent Chat Model" -category: "DEVELOPER NEWS" -date: "2025-06-15" -slug: "diwangshu-kakoty" -author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" -tags: "gsoc25,sugarlabs,week02,AI" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 02 Progress Report by Diwangshu Kakoty - -**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) -**Reporting Period:** 2025-06-08 - 2025-06-14 - ---- - -## Goals for This Week - -- **Goal 1:** Develop a chat model consisting of multiple AI agents/mentors. -- **Goal 2:** Improve the 'Analysis' generation. -- **Goal 3:** Try and test different embedding models. -- **Goal 4:** Fix bugs occured by these changes. - ---- - -## This Week’s Achievements - -1. **AI Mentors** - - From the last meeting with my mentor, I received feedback on having specialised AI mentors for areas of expertise, such as music and coding. Hence, I have implemented a way to have conversations with mentors in music, code, and meta. - - - *Music Mentor* : Handles reflection for music learning. - - - *Code Mentor* : Handles programming concepts and debugging reflection. Users can paste their simplified project code for better feedback and guidance. - - - *Meta Facilitator* : Guides general reflective thinking (learning goals, struggles, progress). - -2. **Improve Analysis Generation** - - As mentioned in the last report, the analysis was inaccurate. I have refined the instructions, and now it functions effectively. It did not take much time. - -3. **Tested various Embedding Model** - - Embedding models are machine learning models that convert complex data such as text, images, or audio into numerical representations called embeddings. I am using `all-MiniLM-L6-v2`, which is lightweight and fast. Although it is lightweight, it is still quite effective. I have not found better models than this, so I will stick with this model for now. - ---- - -## Challenges & How I Overcame Them - -- **Challenge 1 :** The LLM needs to be invoked with the user query, retrieved context, and message history. Since this project involves multiple AI agents, it is somewhat tricky to decide what kind of memory space to use. Possible ways to store messages: - - i) Shared memory space: Each agent will use one common message history with named tags to differentiate among themselves. This way, the AI agents won't repeat questions. - - ii) Separate memory space: Each agent will have their own space. This way, we can prevent confusion for the LLM. However, the trade-off is space. Additionally, we need to pass these message histories separately for summary generation. - - **Solution:** I first implemented the second option because it is simple and works fine, but the summary generation needs to be done separately for each agent, which I don't think is ideal. Therefore, I have decided to try the first option. I have already started working on it. I need to fix some bugs, and it will be completed by tomorrow (2025-06-16). - -- **Challenge 2 :** Retrieved context is irrelevant when the project code is passed. The retriever component returns three chunks arranged in priority. However, a project code can contain many keywords, making the retriever not particularly useful. - - **Solution:** I am considering scanning all the keywords (like block names) first and passing their information to the LLM. This data will be stored in a dictionary. Example: - -```python -blocks = { - "Action": "An Action block contains a sequence of actions that will only be executed when the block is referred to by something else, such as a start block.", - "Start": "A Start Block is an Action that will automatically be executed once the start button is pressed." -} -``` -This way the LLM can understand block structure and their meaning as well. - ---- - -## Key Learnings - -- The prototype for this project is developing in Streamlit, and I am learning Streamlit a lot. -- Also gainig experience in LangChain as this is the primary tool of development. - ---- - -## Next Week’s Roadmap - -- Work on things suggested by mentors. -- Fix challenge no. 2 as mentioned above. -- Start preparing for the frontend interface. - ---- - -## Resources & References - -- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) - - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-omsuneri-week02.md b/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-omsuneri-week02.md deleted file mode 100644 index b5ac1e5f..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-15-gsoc-25-omsuneri-week02.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "GSoC ’25 Week 02 Update by Om Santosh Suneri" -excerpt: "To Develop a Basic RAG Debugger for Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-06-14" -slug: "2025-06-14-gsoc-25-omsuneri-week02" -author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" -tags: "gsoc25,sugarlabs,week02,Debugger,AI,Music Blocks" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 02 Progress Report by Om Santosh Suneri - -**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) -**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) -**Reporting Period:** 2025-06-08 - 2025-06-14 - ---- - -## Goals for This Week - -- **Goal 1:** Enhance and Polish the Converter code -- **Goal 2:** To Make the JSON to Text Converter Publicly Accessible -- **Goal 3:** To Develop a Basic RAG Debugger for Music Blocks - ---- - -## This Week’s Achievements - -1. **Enhance and Polish the Converter code** - - I refined the output of the JSON to Text Converter by improving how blocks, parameters, and nested structures are represented. I also optimized the formatting and added clearer visual symbols to make the structure easier to follow. - - A well-structured and readable output is critical for debugging and learning. These enhancements make the converter not only functional but truly useful, especially for beginners who may be overwhelmed by raw JSON. The clarity improvements bridge the gap between raw code and conceptual understanding. - - GitHub Repository: [JSON to Text representation](https://github.com/omsuneri/JSON-to-Text-representation) - -2. **To Make the JSON to Text Converter Publicly Accessible** - - I deployed the Music Blocks JSON to Text Converter as a static web tool using GitHub Pages. This involved setting up the project structure for deployment, ensuring browser compatibility, and verifying that the tool works seamlessly for any user without needing local installation. - - By making the converter publicly accessible, I’ve removed a major barrier for non-technical users who want to understand or debug Music Blocks projects. Now, anyone can paste their JSON and instantly see a human-readable text format, making it easier to interpret the project logic, especially for educators and learners. - - JSON to Text Converter: [Live Demo](https://omsuneri.github.io/JSON-to-Text-representation/) - -3. **To Develop a Basic RAG Debugger for Music Blocks** - - I created the initial version of a Retrieval-Augmented Generation (RAG) app that acts as a debugger for Music Blocks. It uses Google Gemini (free API) for natural language responses and Qdrant as a vector database to search over relevant Music Blocks documentation and sample project data. - - This is the first step toward an AI-powered assistant that can help users understand errors, debug project files, and learn concepts interactively. It lays the groundwork for a smarter, more accessible debugging experience tailored specifically to the Music Blocks environment. - - GitHub Repository: [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) - ---- - - -## Challenges & How I Overcame Them - -- **Challenge:** Error 99 – Deployment Failure due to Network Binding - **Solution:** I updated the Gemini API implementation to avoid explicitly binding to a local address and ensured it followed the correct networking model for serverless deployment. I also verified that no hardcoded host values (like 127.0.0.1) were used and that the requests use standard internet routes. - -- **Challenge:** Reducing Container Size from 7.1 GB to Under 4 GB - **Solution:** I explored two approaches: - - Optimization: I removed redundant or unused files from the embedding directory and ensured the vector database stored only the most relevant documents. - - Cloud-based Embeddings: I evaluated storing the embeddings externally (e.g., by using a hosted Qdrant instance or remote storage) so that the app could load them at runtime, rather than bundling them in the container.These optimizations brought the container size within limits and made the app deployable on Railway. - ---- - -## Key Learnings - -- Deployment environments have strict constraints that require optimization and flexibility -I learned that successful deployment isn’t just about writing functional code — it's equally about managing resources (like container size) and handling platform-specific limitations, such as networking and storage. -- Early-stage AI apps benefit greatly from clear modularity and cloud-ready design -While building the RAG debugger, I realized the importance of designing components (like embeddings, API logic, and vector search) to be loosely coupled and scalable, which helps avoid technical roadblocks during cloud deployment. - ---- - -## Next Week’s Roadmap - -- Deploy the AI-Powered Debugger App to a Cloud Hosting Platform. -- Create Embeddings from Music Blocks Project Text Representations. -- Improve LLM Response Language for Kids and Junior Learners. - ---- - -## Resources & References - -- **Repository:** [JSON to Text representation](https://github.com/omsuneri/JSON-to-Text-representation) -- **Repository:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-15-ssoc-2025-MuhammadHaroon-week02.md b/src/constants/MarkdownFiles/posts/2025-06-15-ssoc-2025-MuhammadHaroon-week02.md deleted file mode 100644 index a63d2400..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-15-ssoc-2025-MuhammadHaroon-week02.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: "SSoC ’25 Week 02 Update by Muhammad Haroon" -excerpt: "Setting up AudioGen locally and building a simple user interface using Streamlit for generating audio from text." -category: "DEVELOPER NEWS" -date: "2025-06-15" -slug: "2025-06-15-ssoc-25-MuhammadHaroon-week02" -author: "@/constants/MarkdownFiles/authors/muhammad-haroon.md" -tags: "ssoc25,sugarlabs,week02,GenAI,MusicBlocks,Music" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 02 Progress Report by Muhammad Haroon - -**Project:** [Generative AI Instrument Sample Generation for Music Blocks](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md#Generative-AI-Instrument-Sample-Generation-for-Music-Blocks) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-09 - 2025-06-15 - ---- - -## Goals for This Week - -- **Goal 1:** Set up AudioGen locally. -- **Goal 2:** Create a UI using streamlit. - ---- - -## This Week's Achievements - -1. **Set up AudioGen locally** - - I was able to set up AudioGen locally for that I followed [AudioGen docs](https://github.com/facebookresearch/audiocraft/blob/main/docs/AUDIOGEN.md). I also created a virtual environment and a requirements.txt file to make the project easier to run. - -2. **Create a UI using streamlit** - - I also created a UI using streamlit with the help of the [Streamlit docs](https://docs.streamlit.io/). - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** The challenge I actually faced was due to limited resources. AudioCraft (which provides AudioGen) requires a GPU with at least 16 GB of memory for running inference with the medium-sized models (~1.5B parameters). For generating 5 minutes duration of audio, it took around 15-20 minutes. -- **Solution:** I ran the model and used the waiting time to complete other tasks. I plan to deploy the model on AWS, where I expect significantly better performance. - ---- - -## Key Learnings - -- Gained familiarity with **Streamlit** - ---- - -## Next Week's Roadmap - -- Generate more samples using AudioGen and save them in Google Drive. -- Experiment with temperature and top_p parameters in AudioGen. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-17-gsoc-25-AdityaKrSingh26-week05.md b/src/constants/MarkdownFiles/posts/2025-06-17-gsoc-25-AdityaKrSingh26-week05.md deleted file mode 100644 index f580747f..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-17-gsoc-25-AdityaKrSingh26-week05.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: "GSoC ’25 Week 05 Update by Aditya Kumar Singh" -excerpt: "UI improvements, model fixes, skeletal updates, and continued localization work for the 3D Human Activity in Sugarizer." -category: "DEVELOPER NEWS" -date: "2025-06-17" -slug: "2025-06-17-gsoc-25-AdityaKrSingh26-week05" -author: "@/constants/MarkdownFiles/authors/aditya-singh.md" -description: "GSoC'25 Contributor at SugarLabs (Sugarizer Human Activity Pack)" -tags: "gsoc25,sugarlabs,week05,AdityaKrSingh26" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 05 Progress Report by Aditya Kumar Singh - -**Project:** [Sugarizer](https://github.com/llaske/sugarizer) -**Mentors:** [Lionel Laské](https://github.com/llaske) -**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) -**Reporting Period:** 2025-05-06 - 2025-06-12 - ---- - -## Goals for This Week - -- **Goal 1:** Fix and enhance model selection palette to reflect current selection. -- **Goal 2:** Refine and divide bones in the skeleton model for improved clarity and continue localization efforts for Human Activity. -- **Goal 3:** Improve organ model proportions (eye-mouth distance). -- **Goal 4:** Update UI layout for model filter (mode selector). -- **Goal 5:** Merge Paint and Learn mode to show a popup at bottom of screen when user click a part - ---- - -## This Week’s Achievements - -1. **Model Selection Palette Fix** - - Resolved issue where the palette UI did not reflect the currently selected model. - - Now dynamically highlights the active selection across Human, Skeleton, and Organs views. -  -  - -2. **Skeleton Bone Naming and Splitting Update** - - Expanded the skeletal model by splitting compound bones and renaming: - - For example, **“Arm”** is now divided into **Humerus**, **Radius**, and **Ulna**. - - Ensured correct orientation and geometry alignment across these divisions. - - -3. **Localization Progress** - - Continued translation integration using **i18next.js**. - - Initiated support for dynamically changing labels based on selected language. - - -4. **Organ Model Alignment Fix** - - Reduced the gap between eyes and mouth in the 3D organ model. - - Realigned surrounding features to maintain anatomical accuracy. -  - - -6. **Vertical Mode Selector UI Implementation** - - Reworked the mode selection UI to display vertically. - - Inspired by Dollar Street UI design, this improves accessibility. - - Earlier : -  - - Now : -  - - -7. **Merged Paint and Learn mode** - - Implemented a modal system that appears in the bottom-right corner when users click on body parts in paint mode. - - Added fade-in/fade-out transitions with CSS transforms for better user experience and added duplicate prevention system that removes existing modals before showing new ones. -  - - - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Maintaining proper alignment while modifying 3D organ models. - **Solution:** Used Blender’s measurement tools to iteratively adjust spacing, followed by live testing in the Sugarizer environment. - -- **Challenge:** Creating paint mode notifications that don't interfere with 3D interaction. - **Solution:** Developed bottom-right positioned modals with smooth animations and automatic cleanup to maintain workflow continuity while providing clear user feedback. - - ---- - -## Key Learnings - -- Gained experience in internationalization using i18next.js -- Learned UI layout best practices for improving accessibility across devices. -- Gained practical Blender experience for precision model editing. -- Developed more precise anatomical terminology awareness and importance of educational clarity. - ---- - -## Next Week’s Roadmap - -- Write Weekly Blog Post summarizing progress, screenshots, and key learnings. -- Reduce file size of the organ model to improve load time and performance across devices (optimize meshes, reduce texture resolution). -- Add an onboarding tutorial for users -- Create and integrate .json files containing metadata (name, position, mesh reference) for body parts and organs to simplify mesh mapping and future i18n support. -- Begin developing shared logic for **Paint Mode** and **Tour Mode**. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - -## Connect with Me - -- GitHub: [@AdityaKrSingh26](https://github.com/AdityaKrSingh26) -- Gmail: [adityakrsingh2604@gmail.com](mailto:adityakrsingh2604@gmail.com) -- LinkedIn: [Aditya Kumar Singh](https://www.linkedin.com/in/adityakrsingh26/) -- Twitter: [@AdityaKrSingh26](https://x.com/AdityaKrSingh26) - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-20-gsoc-25-AdityaKrSingh26-week06.md b/src/constants/MarkdownFiles/posts/2025-06-20-gsoc-25-AdityaKrSingh26-week06.md deleted file mode 100644 index 4d184ed9..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-20-gsoc-25-AdityaKrSingh26-week06.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: "GSoC ’25 Week 06 Update by Aditya Kumar Singh" -excerpt: "Model optimizations, onboarding tutorial, adding json for body parts, and Shared mode enhancements in Paint Mode for the 3D Human Activity in Sugarizer." -category: "DEVELOPER NEWS" -date: "2025-06-20" -slug: "2025-06-20-gsoc-25-AdityaKrSingh26-week06" -author: "@/constants/MarkdownFiles/authors/aditya-singh.md" -tags: "gsoc25,sugarlabs,week06,AdityaKrSingh26" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 06 Progress Report by Aditya Kumar Singh - -**Project:** [Sugarizer](https://github.com/llaske/sugarizer) -**Mentors:** [Lionel Laské](https://github.com/llaske) -**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) -**Reporting Period:** 2025-05-12 - 2025-06-18 - ---- - -## Goals for This Week - -- **Goal 1:** Optimize organ model to reduce file size and improve performance. -- **Goal 2:** Add a onboarding tutorial for users. -- **Goal 3:** Improve organ model proportions (eye-mouth distance). -- **Goal 4:** Create and integrate `.json` file for body parts and organs. -- **Goal 5:** Enhancing shared mode logic for **Paint Mode**. - ---- - -## This Week’s Achievements - -1. ***Organ Model Optimization** - - Reduced the organ model size from **19MB to 5.92MB** by applying **Merge Vertices by Distance** and **Mesh Decimation** in Blender. - - These steps simplified mesh geometry while retaining anatomical accuracy. - - Resulted in faster loading on low-end devices and web platforms without compromising visual quality. - -2. **Onboarding Tutorial Integration** - - Implemented an interactive onboarding experience using the **Intro.js** library, following Sugarizer's developer tutorial guidelines. - - Integrated a custom help button in the toolbar (`help.svg`) to trigger the tutorial on demand. - - Defined tutorial steps in a dedicated `tutorial.js` module using `introJs().setOptions()` to guide users through the UI. - - Customized the UI using Sugarizer-themed CSS classes for a consistent visual style. - - Enabled full localization support using `l10n.get()` to adapt tutorial text based on the user’s language settings. -  -  - - -3. **Body Parts Metadata via JSON** - - Introduced a new `.json` file structure to define: - - **Name** - - **Mesh name** - - **Position (x, y, z)** - - Enables simpler mapping between UI and 3D model meshes. - - Supports future work on localization, click handling, and performance enhancements. - ```json - { - { "name": "Hair", "mesh": "Hair_mesh", "position": [-0.01, 7.03, -0.32] }, - { "name": "LeftEyebrow", "mesh": "Mesh0207_1", "position": [0.06, 6.69, 0.63] }, - { "name": "RightEyebrow", "mesh": "Mesh0207_3", "position": [0.06, 6.69, 0.63] }, - { "name": "Left Ear", "mesh": "leftear_mesh", "position": [0.62, 6.42, -0.13] }, - { "name": "Right Ear", "mesh": "righear_mesh", "position": [-0.53, 6.4, -0.13] }, - { "name": "Face", "mesh": "Face_mesh", "position": [0.05, 6.35, 0.36] }, - { "name": "Neck", "mesh": "Neck_mesh", "position": [0.04, 5.54, -0.23] }, - { "name": "Chest", "mesh": "Chest_mesh", "position": [0.04, 4.55, 0.11] }, - { "name": "Back", "mesh": "back_mesh", "position": [0.04, 3.78, -0.83] }, - { "name": "Stomach", "mesh": "stomach_mesh", "position": [0.04, 2.41, 0.2] }, - ... - } - - -4. **Shared Mode enhancements for Paint Mode** - - **Model sync:** when any participant switches to a different anatomical model, the client now emits a `switchModel` event; all connected users load the same model instantly. - - **Shared painting:** a `paintPart` broadcast (object name, color, body-part name, painter ID) lets everyone see the newly painted part in real time. A modal on each peer shows **“<user> painted: <part>”** for clear attribution. -  - - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Displaying context-aware feedback for painting actions without breaking UX flow. - **Solution:** Built a shared modal system that shows **“User X painted: Part Y”** without interrupting interactions. Ensured consistent color application using hex values and mesh IDs. - -- **Challenge:** Keeping the tutorial visually aligned with Sugarizer UI guidelines while supporting localization. - **Solution:** Customized Intro.js with Sugarizer-style buttons, icons, and tooltips. Integrated `l10n.get()` to provide multilingual support across tooltips, button labels, and descriptions. - - ---- - -## Key Learnings - -- Gained practical experience in implementing **real-time collaboration** using socket-based event broadcasting for 3D interactions. -- Learned how to **synchronize complex state changes** (like model switching, paint actions, and UI mode transitions) across multiple clients in a shared environment. -- Deepened understanding of **modular and scalable architecture** by separating shared logic into dedicated handlers and avoiding code duplication. - ---- - -## Next Week’s Roadmap - -- Write Weekly Blog Post summarizing progress, screenshots, and key learnings. -- Reduce file size of the organ model to improve load time and performance across devices (optimize meshes, reduce texture resolution). -- Add an onboarding tutorial for users -- Create and integrate .json files containing metadata (name, position, mesh reference) for body parts and organs to simplify mesh mapping and future i18n support. -- Begin developing shared logic for **Paint Mode** and **Tour Mode**. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-21-dmp-25-AmanNaik-week03.md b/src/constants/MarkdownFiles/posts/2025-06-21-dmp-25-AmanNaik-week03.md deleted file mode 100644 index 74de5bef..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-21-dmp-25-AmanNaik-week03.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: "DMP ’25 Week 3 Update by Aman Naik" -excerpt: "This week's focus was developing a working demo for the Story Builder feature using Streamlit and gathering mentor feedback for further improvements." -category: "DEVELOPER NEWS" -date: "2025-06-21" -slug: "2025-06-21-dmp-25-AmanNaik-week03" -author: "@/constants/MarkdownFiles/authors/amannaik247.md" -tags: "dmp25,writeactivity,write,sugarlabs,week03,amannaik247" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 3 Progress Report by Aman Naik - -**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) -**Reporting Period:** 2025-06-16 – 2025-06-21 - ---- - -## Goals for This Week - -- **Goal 1:** Develop a working demo of the Story Builder feature -- **Goal 2:** Implement the demo using Streamlit -- **Goal 3:** Gather feedback from mentors and plan improvements - ---- - -## This Week’s Achievements - -1. **Developed a Demo of the Story Builder Feature** - - Created a functional web application using Streamlit to demonstrate how the story builder AI guides students through storytelling. The demo mimics the question-and-answer-based flow and simulates an AI companion. - - Find the demo [here](https://story-builder-ai.streamlit.app/) - -  - -  - -2. **Presented the Demo to Mentors** - - Shared the working version with my mentors. I received positive feedback and valuable suggestions on what could be improved and how the feature can be enhanced with new ideas. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Designing a feedback loop where the AI accumulates all context from the student’s responses - **Solution:** After repeated iterations and research, I realized that assigning a distinct personality to the LLM helps it collect and remember context more naturally. This personality-driven approach ensures a more engaging and coherent interaction throughout the story-building process. - ---- - -## Key Learnings - -**Built and Deployed a Streamlit Demo to Simulate Story Interaction** - - Gained practical experience in using Streamlit to build and deploy web apps that demonstrate AI interaction flow for educational use cases. - -**Learned the Importance of AI Personality in Context Retention** - - Discovered that crafting an AI assistant with a personality improves its ability to retain context and makes the storytelling experience more relatable and fun for children. - ---- - -## Next Week’s Roadmap - -- Begin fine-tuning a language model using AWS -- Build a system where the AI recommends books similar to the student's story at the end of the conversation - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for their continuous guidance and valuable feedback! - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-Elwin-Li-week03.md b/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-Elwin-Li-week03.md deleted file mode 100644 index 23aec81c..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-Elwin-Li-week03.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: "GSoC '25 Week 3 Update by Elwin Li" -excerpt: "Weekly progress report for JSEditor updates" -category: "DEVELOPER NEWS" -date: "2025-06-21" -slug: "2025-06-21-gsoc-25-Elwin-Li-week03" -author: "@/constants/MarkdownFiles/authors/elwin-li.md" -tags: "gsoc25,sugarlabs,week3,javaScript editor" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 3 Progress Report by Elwin Li - -**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/config_driven_conversion/elwin) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) - -**Reporting Period:** 2025-06-14 - 2025-06-21 - ---- - -## Goals for This Week - -- **Goal:** Start on debugger for musicblocks and JS editor. - ---- - -## This Week’s Achievements - -**Made Working Debugger** - -This week, I made a working debugger tool for Music Blocks JS editor. I added a button in the JS editor that is a toggle for the debug mode. On debug mode, users are able to add a breakpoint in any line of the code using buttons on the side of the line numbers. When the user then converts the code back to blocks, there are new debugger statement blocks that shows up. - -Then, when the user runs their code, execution will be paused at every debugger statement, and a status block with all the user defined and musicblocks defined variables up till that point will appear, showing the user those values, making it easy to debug. The user can then choose which variables they want to keep, and continue execution. This tool works perfectly with the run slowly and run step by step buttons, in order for more careful debugging. - -Also, I made block highlights contrast much more from original block colors, for easier tracking of which block is being executed. - -[youtube: jEJuXpyQbS8] - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Status blocks default to a set macro of variables - - **Solution:** Was able to go through the blocklist and single out needed variables to put in the status block instead - ---- - -## Key Learnings - -- Deepened understanding of how music blocks execution works -- Improved skills in **debugging**, **code design**, and **collaboration workflows**. - ---- - -## Next Week’s Roadmap - -- Finish debugger project (fix bugs) -- Add syntax highlighting to JSeditor code - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-MebinThattil-week03.md b/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-MebinThattil-week03.md deleted file mode 100644 index 2e7d0a35..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-MebinThattil-week03.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: "GSoC ’25 Week 03 Update by Mebin J Thattil" -excerpt: "Re-thinking training dataset structure" -category: "DEVELOPER NEWS" -date: "2025-06-21" -slug: "2025-06-21-gsoc-25-mebinthattil-week3" -author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" -tags: "gsoc25,sugarlabs,week03,mebinthattil,speak_activity" -image: "assets/Images/GSOCxSpeak.png" ---- - -<!-- markdownlint-disable --> - -# Week 03 Progress Report by Mebin J Thattil - -**Project:** [Speak Activity](https://github.com/sugarlabs/speak) -**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-14 - 2025-06-21 - ---- - -## Goals for This Week - -- **Goal 1:** Fix the issue for continious generation of chain of responses from model - ---- - -## This Week’s Achievements - -Note: _I'm officially on leave for this week and the next week, but I have however been taking calls and attending meetings, and did some light work in the background._ - -1. **Re-formatted the dataset to avoid generating chain of responses** - - Before the dataset had a records of conversations between a student and a teacher. Each record would have around 5-10 back-and-forth questions and interactions between the student and teacher. - - Since we were training on this dataset format, the model would also try to replicate this format - ie. it would start generating a chain of question-answer back and forths between the student and teacher. This is obviously something that we don't want. - - I initially kept it this way to teach the model better conversational flow, but this approach does more harm than help. - - So I have broken up the conversations and re-structured the conversations. - - I will now fine-tune it again on a subset of the dataset and deploy just to test it (_this is yet to be done_) - - ---- - -## Key Learnings - -- Structure of dataset needs to be changed, in order to make it more conversational and understand the nuances of a chain of conversations. - ---- - -## Next Week’s Roadmap - -- Train the model and evaluate it -- Also try to run [my model](https://huggingface.co/MebinThattil/FT-Llama3.2-1B/tree/main) that is on HF via Sugar-AI. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - diff --git a/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-mostlyk-week03.md b/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-mostlyk-week03.md deleted file mode 100644 index d46efab4..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-21-gsoc-25-mostlyk-week03.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: "GSoC '25 Week 3 Update by Krish Pandya" -excerpt: "From initial GTK4 porting to building a solid foundation with separate C and Python libraries" -category: "DEVELOPER NEWS" -date: "2025-06-21" -slug: "2025-06-21-gsoc-25-mostlyk-week03" -author: "@/constants/MarkdownFiles/authors/krish-pandya.md" -tags: "gsoc25,sugarlabs,week03,mostlyk" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 3: Development on the C estabhlishment - -**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky), [Juan Pablo Ugarte](https://github.com/xjuan) -**Reporting Period:** June 14, 2025 till June 21, 2025 - ---- - - -## Following the meet of big change - -> On last to last Friday(06-06-2025), we had a pivotal video call with Juan Pablo Ugarte and Ibiam Chihurumnaya that completely reshaped the porting approach. -What started as a discussion about my initial porting work evolved into something much more strategic and forward-thinking. - -As discussed about these changes in the past week's blog, I have been continuing to update the C library. I have ported - -### Commited: - -- Sugar File Attributes ( in discussion of do we need to modernize or no) -- Event Controllers for Sugar ( handles clicks, movement etc. ) -- Long Press Controllers - -### Local: - -- Sugar Touch Controllers -- Building on top of them, zoom, swipe and rotate. - - -## Demonstration of the Controllers: - -<iframe width="560" height="315" src="https://www.youtube.com/embed/m0gwwo_0ZDE?si=M0ljKFFGuwAqAzrf" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> - -This video shows working example of Event Controller and Long Press controller. - ---- - -## PR Deep Dive - -### Review & Iteration - -The review process was thorough and collaborative, with mentors providing feedback on: - -- API and Versioning: Ensuring symbol and identifier prefixes followed conventions, and clarifying versioning strategy to align with Sugar’s release cycle. -- Code Structure: Moving away from including XO Colors in the C library (to be handled in Python). -- Licensing: Correctly attributing copyright and following LGPL-2.1. ( As discussed in last week's blog for the versioning ). -- Formatting: Retaining original code formatting for readability, and avoiding unnecessary changes from auto-formatters. -- Build System: Making examples optional in the build, and keeping the project modular. - -### Modernization Decisions - -A key discussion was around modernizing the file attributes utility using GLib APIs. My rationale was to unify the codebase under a modern standard, leveraging GLib for better error handling and maintainability. However, Ibiam and James highlighted the importance of compatibility with filesystems like FAT32, and the need to test on real hardware. I will be formatting my USB to test this soon. I will keep it as a TODO for now. - -### Testing - -Every ported module includes comprehensive tests. Just do the following to test: - -```bash -meson test -C builddir -``` - -The tests cover attribute creation, setting/getting values, and simulating real-world activity workflows. I plan to continue this rigorous testing approach for all future modules as always , yours truly Krish. - -### Lessons Learned - -- Consistency matters - Unifying the codebase under GLib/GTK4 improves maintainability, but must be balanced with legacy compatibility. -- Testing is critical - Automated and example-based tests are essential for safe modernization. -- Documentation and commit messages - Clear explanations of why changes are made (not just what) are crucial for future maintainers. - - _I am still learning on how to improve all of these , especially commit messages_ - ---- - -# Apart from Porting - -Outside of the core Sugar porting work, I also spent some time tinkering (_I love music_) some side projects for MusicBlocks and SL: - -- AWS & SoundScape: I continued working on [SoundScape](https://soundscape.streamlit.app/), the audio processing web app. -This week, I wanted to update the platform to include an SheetMusic-To-MusicXML model in addition to existing Audio-to-Sheet-Music model and Audio-to-MIDI functionality. -I sadly was using Oemer and my own system rqreuiement were not capable enough to run it . - -- Machine Learning Experiments: I tried running [Oemer](https://github.com/BreezeWhite/oemer), an open-source Optical Music Recognition tool.So I’m planning to set up a dedicated AWS instance for further testing and integration. And if that works out I can deploy by dockerizing SoundScape. - -Overall, I like tinkering with these kinds of projects and learn more about foundational models. - -To someone who is interested in research and wants a tool to have beside reading papers you can check [Dread-Rising](https://dread-rising.streamlit.app/). It can also be used for someone who just wants to read a book , or an article, you can get highlighted version of the PDF, multiple understanding and can do in-depth. - -These small problems that I tackle using my pre-existing knowledge on LLMs and Python help me in porting as well, even though it's a completely different side of project which is writing a C library right now, the skills and thinking translate a lot and I have fun! - -## Resources & References - -- Project Page – [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) -- New C Library - [sugar-ext repository](https://github.com/sugarlabs/sugar-ext) -- Active PR - [Establish C library base template with Meson for GTK4](https://github.com/sugarlabs/sugar-ext/pull/1) -- Sugar Toolkit Repository(original) – [sugar-toolkit-gtk3](https://github.com/sugarlabs/sugar-toolkit-gtk3) -- GTK4 Migration Guide – [docs.gtk.org/gtk4/migrating-3to4.html](https://docs.gtk.org/gtk4/migrating-3to4.html) - - ---- - -## Acknowledgments - -Huge thanks to Juan Pablo Ugarte first of all for being the official mentor and Ibiam Chihurumnaya for the guidance that that changed this project's direction. Their architectural vision has transformed porting into a comprehensive modernization effort. Thanks also to Walter Bender for mentorship. diff --git a/src/constants/MarkdownFiles/posts/2025-06-22-DMP-25-justin212407-week3.md b/src/constants/MarkdownFiles/posts/2025-06-22-DMP-25-justin212407-week3.md deleted file mode 100644 index 3ac7829d..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-22-DMP-25-justin212407-week3.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "DMP’25 Week 03 Update by Justin Charles" -excerpt: "Completed SVG path logic for all brick types and documented props and rendering states" -category: "DEVELOPER NEWS" -date: "2025-06-22" -slug: "2025-06-22-dmp-25-justin212407-week03" -author: "@/constants/MarkdownFiles/authors/justin-charles.md" -tags: "dmp25,sugarlabs,week3,justin212407" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 3 Progress Report by Justin Charles - -**Project:** Music Blocks 4 Maosonry -**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-06-15 - 2025-06-22 - ---- - - -## Goals for This Week - -- Design an algorithm for parsing and rendering the brick tree via React components -- Expose bounding box and connection point data from the model layer -- Create a prop interface for passing this spatial data into the rendering layer - ---- - -## This Week’s Highlights - -### 1. **Visual Tree Parsing and Rendering Algorithm** - -Developed a clean, maintainable algorithm to traverse and render the brick tree structure: -- Each tree node is transformed into a React component, preserving parent-child and neighbor relationships -- Recursive traversal ensures dynamic rendering of nested bricks -- Designed to integrate seamlessly with `BrickTreeManager` and individual brick models - -### 2. **Exposed Geometric Metadata in Brick Models** - -Implemented structured public getters and setters to handle: -- **Bounding Box (bbox)**: x, y, width, and height of each rendered brick -- **Connection Point Coordinates**: Vary based on brick type (Simple, Expression, Compound) -- Enables precise layout, collision detection, and advanced interaction logic downstream - -### 3. **Visual Data Propagation via React Props** - -Added a new prop to the core brick rendering components: -- Accepts a callback function -- Receives `bbox` and connection point data as arguments after render -- Supports future enhancements like: - - Overlay-based debugging - - Adaptive layout reflows - - External visualization tools - -📄 Reference for parsing algorithm: [Tab 5](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.99d6uc7vheda) - ---- - -## Challenges & Solutions - -**Challenge: Finding the right parsing algorithm for parsing the tree** -**Solution:** Implemented stack based traversal with visited node tracking and component key management - -**Challenge: The tree parsing algorithm struggled to correctly identify and maintain parent-child relationships when bricks had multiple connection points or nested expressions** - -**Solution:** Implemented a two-pass algorithm - first pass builds the node structure, second pass establishes parent-child references and validates connection integrity - ---- - -## Key Learnings - -- Algorithm Design - -Recursive Patterns: Learned how to structure recursive algorithms for tree traversal that map cleanly to React component hierarchies -Data Structure Mapping: Understanding how to translate tree data structures into renderable React components - ---- - -## Next Week’s Roadmap - -- Render the tree upon the storybook given any configuration of bricks. -- List down all the bricks and their configurations. -- Create the pallete UI with all types of bricks present in it. - ---- - -## Resources & References - -- [musicblocks-v4 Repository](https://github.com/sugarlabs/musicblocks-v4) -- [musicblocks-v4 Tech Spec Document](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.0#heading=h.gtbrgbbwfht3) ---- - -## Acknowledgments - -Thanks to my mentors for helping review the algorithm logic for rendering the tree. Their early feedback made the path code significantly more robust and maintainable. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-22-dmp-25-AnvitaPrasad-week03.md b/src/constants/MarkdownFiles/posts/2025-06-22-dmp-25-AnvitaPrasad-week03.md deleted file mode 100644 index 2d644d84..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-22-dmp-25-AnvitaPrasad-week03.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "DMP '25 Week 03 Update by Anvita Prasad" -excerpt: "Implementation of tuner visualization system and dual-mode interface" -category: "DEVELOPER NEWS" -date: "2025-06-22" -slug: "2025-06-22-DMP-25-AnvitaPrasad-week03" -author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" -tags: "dmp25,sugarlabs,week03,AnvitaPrasad" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 03 Progress Report by Anvita Prasad - -**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) -**Mentors:** [Walter Bender](https://github.com/walterbender) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-16 - 2025-06-22 - ---- - -## Goals for This Week -- **Goal 1:** Implement dual-mode tuner interface -- **Goal 2:** Complete basic cents adjustment UI implementation -- **Goal 3:** Enhance tuner visualization system -- **Goal 4:** Test with various audio sources and instruments - ---- - -## This Week's Achievements - -1. **Dual-Mode Tuner Implementation** - - Successfully implemented a toggle button interface for switching between two tuner modes - - Developed chromatic mode where target pitch moves based on input pitch - - Implemented logic for finding closest chromatic pitch within +/- 50 cents - - Added cent deviation value display under the tuner - - Started work on specific target pitch mode implementation - - Gathered feedback for further refinements - -2. **Cents Adjustment UI Development** - - Implemented basic cents adjustment interface - -3. **Tuner Visualization Enhancements** - - Made refinements to last week's visualization system - - Added clear visual feedback for cent deviation - - Enhanced visual clarity for pitch detection feedback - -4. **Testing Progress** - - Conducted initial testing with various audio sources - - Identified areas for improvement in pitch detection - - Created a test suite for tuner accuracy verification - -5. **Audio Processing Improvements** - - Implemented low-pass filtering to handle high-frequency noise - - Enhanced pitch detection accuracy using parabolic interpolation - - Optimized signal processing for better performance - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Creating an intuitive UI for mode switching - **Solution:** Implemented a clear toggle interface with visual indicators for current mode - -- **Challenge:** Dealing with high-frequency noise in audio signal - **Solution:** Implemented low-pass filtering to improve signal quality and enhance pitch detection accuracy - ---- - -## Key Learnings - -- Learned about signal processing techniques like low-pass filtering and its impact on audio quality -- Gained insights into sub-cent accuracy through parabolic interpolation in pitch detection - ---- - -## Next Week's Roadmap - -- Complete and refine target pitch mode implementation -- Implement manual cent adjustment functionality -- Finalize design for cent adjustment interface -- Conduct comprehensive testing with various audio sources and instruments -- Deliverable: Fully functional tuner with cents adjustment - ---- - -## Resources & References - -- [Web Audio API Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) -- [Audio Filters Guide](https://blog.native-instruments.com/audio-filters-guide/) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-BishoyWadea-week03.md b/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-BishoyWadea-week03.md deleted file mode 100644 index 643df6aa..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-BishoyWadea-week03.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "GSoC ’25 Week 03 Update by Bishoy Wadea" -excerpt: "Broken Calculator" -category: "DEVELOPER NEWS" -date: "2025-06-22" -slug: "gsoc-25-BishoyWadea-week03" -author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" -tags: "gsoc25,sugarlabs,week03,BishoyWadea" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 03 Progress Report by Bishoy Wadea - -**Project:** [Broken Calculator](https://github.com/Bishoywadea/Broken-Calculator) -**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) -**Reporting Period:** 2025-06-22 - 2025-06-28 - ---- - -## Goals for This Week - -- **Goal 1:** Fix issues in Four Color Map game opened by ibiam [Move buttons from canvas to tool bar](https://github.com/Bishoywadea/Four-Color-Map/issues/1), [Sugarize activity icon](https://github.com/Bishoywadea/Four-Color-Map/issues/2), [adding lisence to activity](https://github.com/Bishoywadea/Four-Color-Map/issues/3). - - - -- **Goal 2:** Fix issues in Broken Calculator game opened by ibiam [change UI to be more focused](https://github.com/Bishoywadea/Broken-Calculator/issues/2). - - ---- - -## This Week’s Achievements - -### *Goal 1: Fix Issues in Four Color Map Activity* - -1. **Moved Control Buttons to Toolbar** - - Relocated in-canvas buttons (Undo, Help, Menu) to a proper activity toolbar for a more intuitive UI layout. - - PR: [Move Buttons to Toolbar](https://github.com/Bishoywadea/Four-Color-Map/pull/5) - -2. **Sugarized the Activity Icon** - - Designed and applied a new icon that follows Sugar activity standards in shape, color, and transparency. - - PR: [Sugarized Icon](https://github.com/Bishoywadea/Four-Color-Map/pull/6) - -3. **Added License File** - - Included a standard open-source license file in the repo, ensuring compliance with FOSS guidelines. - - PR: [Add License](https://github.com/Bishoywadea/Four-Color-Map/pull/7) - ---- - -### *Goal 2: Improve Broken Calculator UI & UX* - -1. **Redesigned UI for Focused Gameplay** - - Refactored layout to fill the canvas with the calculator interface and decluttered extra elements. - - commit: [Canvas Layout Update](https://github.com/Bishoywadea/Broken-Calculator/commit/7ec076475ae1c7e77c96a6ae155b151681fa724a) - ---- - -## Challenges & Solutions - -- **Challenge:** Migrating control elements from canvas to toolbar in Four Color Map. - **Solution:** Familiarized myself with the Sugar toolbar API and successfully relocated buttons, improving UI consistency. - -- **Challenge:** Making the interface engaging for children. - **Solution:** Added animations, character images, and accessible visual elements. - ---- - -## Key Learnings - -- Deepened experience working with **Sugar activity design standards**, including toolbars and icon sugarization. -- Gained hands-on experience applying **open-source contribution practices**—issue tracking, commit hygiene, licensing, and documentation. -- Practiced creating UI/UX for young learners, focusing on minimalism, feedback clarity, and visual accessibility. - ---- - -## Next Week’s Roadmap - -### Soma Cubes Game: Initial Insights & Exploration -- Begin designing core mechanics and gameplay flow for a Soma Cubes puzzle activity. -- Prototype user interactions: piece manipulation, rotation, and snapping into place. -- Investigate how to integrate puzzle constraints and feedback for users. -- Sketch out UI layout and controls tailored for children. - ---- - -### Fix Open Issues - -#### Four-Color Map Activity -- **[#4 Make activity pep8 compliant](https://github.com/Bishoywadea/Four-Color-Map/issues/4)** - The activity isn't pep8 compliant. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-Nikhil-Bhatt-week03.md b/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-Nikhil-Bhatt-week03.md deleted file mode 100644 index 3d6e0695..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-Nikhil-Bhatt-week03.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "GSoC '25 Week 03 Update by Nikhil Bhatt" -excerpt: "Set up backend routes for creating and viewing pull requests on MusicBlocks project repositories." -category: "DEVELOPER NEWS" -date: "2025-06-17" -slug: "2025-06-17-gsoc-25-nikhilbhatt-week03" -author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" -tags: "gsoc25,sugarlabs,week03,nikhilbhatt" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 03 Progress Report by Nikhil Bhatt - -**Project:** [Git backend for MusicBlocks](https://github.com/benikk/musicblocks-backend) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Reporting Period:** 2025-06-15 – 2025-06-21 - ---- - -## Goals for This Week - -- Add backend support for creating pull requests when someone edits a forked project. -- Allow project maintainers to view all incoming pull requests to their original project repo. ---- - -## This Week's Achievements - -1. **Created Pull Request Route** - - Built a route where students who forked a project can submit updates. - - The backend automatically creates a **new branch on the original repository**, updates the `projectData.json`, and creates a pull request from that branch to the main branch. - - We use the original repository info stored in `metaData.json` of the forked project. - - Only two values are required from the frontend: the name of the fork repo and the updated `projectData`. - -2. **View All Pull Requests Route** - - Added another route that **lists all open pull requests** for a given repository. - - Maintainers can use this to preview incoming contributions. - - In the future, clicking “merge” on the frontend will trigger the same `edit` route we already have, safely updating the project. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** GitHub’s API does not allow opening pull requests between two repos in the **same organization** (which is our setup for MusicBlocks). - **Solution:** Instead of trying to PR from a forked repo to the original, we create a **new branch directly in the original repo** and update content from the backend. Then we make a PR from that new branch to `main`. - -- **Challenge:** Figuring out the cleanest flow with the least frontend involvement. - **Solution:** Used the backend to handle metadata extraction, branch creation, commit, and PR creation automatically, so the frontend only needs to pass minimal data. - ---- - -## Key Learnings - -- Understood GitHub's limitations when working with forks in the same organization. -- Learned how to manage pull request creation with custom branches and automated commits. -- Improved backend architecture by centralizing logic and reducing frontend responsibility. - ---- - -### An interesting problem to solve - -Currently, since all project repositories (original and forks) are created under the same GitHub organization using a central GitHub App, all commits and pull requests appear to be made by the original repo,and since our setup is such that we create Pull request through a branch in the original repository (We cannot do that from a repo in the same org account) we cannot keep a track of which fork's commit was merged. - -Workaround - -As a workaround, fork project's details can now be stored in the `metaData.json` of each forked project. When viewing pull requests via the custom route, this data can be used to show who contributed what. - - -## Next Week's Roadmap - -- **Start frontend development**: Add interfaces for users to view, submit, and merge pull requests. -- Add UI indicators for forked projects and pull request status. -- Improve display of `projectData` in pull request previews. - ---- - -## Resources & References - -- **GitHub PR API Docs:** [docs.github.com/rest/pulls](https://docs.github.com/en/rest/pulls/pulls) -- **Octokit REST Library:** [github.com/octokit/rest.js](https://github.com/octokit/rest.js) -- **Backend Repo:** [musicblocks-backend](https://github.com/benikk/musicblocks-backend) - ---- - -## Acknowledgments - -Big thanks to my mentors and the Sugar Labs community for their guidance and patience. Also grateful to GitHub’s documentation which helped solve tricky API issues. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-SafwanSayeed-week03.md b/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-SafwanSayeed-week03.md deleted file mode 100644 index 9fed5a97..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-SafwanSayeed-week03.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: "GSoC '25 Week 3 Update by Safwan Sayeed" -excerpt: "AST to IR Compilation Logic and Pseudocode Implementation" -category: "DEVELOPER NEWS" -date: "2025-06-22" -slug: "2025-06-22-gsoc-25-sa-fw-an-week3" -author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" -tags: "gsoc25,sugarlabs,week3,sa-fw-an" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 3 Progress Report by Safwan Sayeed - -**Project:** Music Blocks 4 Program Engine -**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-06-16 - 2025-06-22 - ---- - -## A Blog-style Retrospective - -This week marked a significant milestone in our Music Blocks program engine development as we transitioned from the foundational memory architecture to the core compilation logic. The focus shifted to implementing the AST-to-IR (Intermediate Representation) translation layer - the crucial bridge between our abstract syntax tree representation and executable code. - -The challenge was designing a static compilation system that converts AST nodes into a linear sequence of IR instructions, following the three-address code format. Working with complex expression hierarchies and statement blocks required careful consideration of instruction ordering and variable management. - -Our mentors provided invaluable guidance on maintaining the static nature of the compilation process, emphasizing that we're translating program structure rather than executing runtime calculations. This distinction was crucial for keeping our implementation focused and efficient. - ---- - -## Goals for This Week - -- Complete the AST-to-IR compilation logic technical specification with detailed pseudocode patterns. -- Implement evaluate() methods for all expression classes returning instruction lists. -- Develop pseudocode for simple statements following the established IR generation patterns. -- Design the instruction chaining mechanism for complex nested expressions. - ---- - -## This Week's Highlights - -1. **IR Compilation Logic Specification** - - Expanded the tech spec with comprehensive AST-to-IR translation documentation covering expression and statement compilation patterns. - - Detailed instruction list generation requirements and variable management strategies. - - Link: [IR Compilation Logic](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.i655udul8zuq) - -2. **AST-to-IR Pseudocode Implementation** - - Implemented evaluate() methods for all expression classes (Literal, Binary/Unary Operators, Arrays, Dictionaries, etc.) - - Developed instruction list generation patterns following three-address code format - - Created symbol table integration using sym_query, sym_declare, and sym_assign operations - - Link: [Tech Spec Document - AST to IR Methods](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.87123fra3s4#heading=h.gqjcwrtkdgvq) - -3. **Simple Statements Compilation Logic** - - Implemented pseudocode for VariableDeclarationStatement, VariableAssignmentStatement, FunctionCallStatement, and JumpStatement - - Established parameter passing patterns for evaluate() methods ensuring proper instruction dependency chains - ---- - -## Challenges & Solutions - -- **Understanding Static vs Runtime Compilation:** - Initially confused about whether we were performing runtime calculations or static code translation. - *Solution:* Mentors clarified that this is purely static AST-to-IR conversion with no runtime execution, helping focus the implementation approach. - - ---- - -## Key Learnings - -- Mastered the distinction between static compilation and runtime execution in compiler design. -- Gained deep understanding of three-address code generation and instruction dependency management. -- Enhanced skills in designing clean pseudocode patterns that can be translated to actual implementation. -- Learned the importance of maintaining consistent parameter passing patterns across class hierarchies. - ---- - -## Next Week's Roadmap - -- Implement pseudocode for compound statements. -- Design basic block generation logic for control flow structures. ---- - -## Resources & References - -- **Tech Spec:** [IR Compilation Logic](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.i655udul8zuq) -- **Tech Spec:** [AST to IR Methods](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.87123fra3s4#heading=h.gqjcwrtkdgvq) -- **Repository:** [musicblocks-v4](https://github.com/sugarlabs/musicblocks-v4) - ---- - -## Acknowledgments - -Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their crucial guidance on compiler design principles and static compilation concepts. Their clarification on the AST-to-IR translation approach and emphasis on maintaining clean instruction generation patterns was essential for this week's successful progress. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-diwangshu-week03.md b/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-diwangshu-week03.md deleted file mode 100644 index 6edb0edf..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-diwangshu-week03.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: "GSoC ’25 Week 03 Update by Diwangshu Kakoty" -excerpt: "AI with Reasoning Capabilities" -category: "DEVELOPER NEWS" -date: "2025-06-22" -slug: "2025-06-22-gsoc-25-diwangshu-week03" -author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" -tags: "gsoc25,sugarlabs,week03,AI" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 03 Progress Report by Diwangshu Kakoty - -**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) -**Reporting Period:** 2025-06-15 - 2025-06-21 - ---- - -## Goals for This Week - -- **Goal 1:** Implement streaming response by LLM. -- **Goal 2:** Improve context passing for project code. -- **Goal 3:** Experiment and test different Gemini models and their capabilities. -- **Goal 4:** Fix bugs occured by these changes. -- **Goal 5:** Test the multi-agent chat model. - ---- - -## This Week’s Achievements - -1. **Implemented streaming response by LLM** - - I have implemented streaming responses from the LLM. This allows the model to send partial responses as they are generated, which is particularly useful for long responses. The implementation is straightforward and works well with the current setup. - -2. **Improved context passing for project code** - - As mentioned in the last report, the retrieved context was not particularly useful when passing project code. - - - I have improved this by scanning all keywords (like block names) first and passing their information to the LLM. This data is stored in a dictionary, which allows the LLM to understand the block structure and their meanings better. - -3. **Experiment and test different Gemini models and their capabilities** - - I have experimented with various Gemini models, including `gemini-1.5-flash`, `gemini-2.0-flash`, `gemini-2.0-flash-lite` and `gemini-2.5-flash`. - - - The most interesting one is `gemini-2.5-flash`, because of its 'thinking' capability. I did not know that Gemini models had this feature. The 'thinking' capability provides quality responses by breaking down complex queries into smaller, manageable parts. This could be very useful for the LLM to understand the project code or any other complex queries. - - - The RPM (Requests per minute) of `gemini-2.5-flash` is 10 and TPM (Tokens per minute) is 250,000. When 'thinking` is enabled a different token is used called 'thinking token'. We can specify the number of thinking tokens to be used or it can be set to auto. Threrefore, the thinking capability should be used for complex queries only, as it consumes more tokens and is slower than the regular response. - ---- - -## Challenges & How I Overcame Them - -- **Challenge :** I am trying to implement the 'thinking' capability of the Gemini model, but I am facing some issues with the response format. The model is not returning the expected structured response when 'thinking' is enabled. Their are not many resources on this topic. - - **Solution:** I found that the official Gemini documentation is the best resource for understanding how to implement this feature. I am currently working on it and hope to resolve the issue soon. - ---- - -## Key Learnings - -- I have realised one thing for sure, that a developer has to rely on the official documentation of any technology or library they are owrking on. As a student I often tend to look for tutorials or blog posts, but they are not always reliable or up-to-date. The official documentation is the most accurate and comprehensive resource. - ---- - -## Next Week’s Roadmap - -- Work on things suggested by mentors. This could include: - - Improving the multi-agent chat model. - - Testing the multi-agent chat model with different Gemini models. -- Discuss with mentors about the 'thinking' capability of the Gemini model. On what kind of queries it can be used. -- Implement the 'thinking' capability in the multi-agent chat model. - ---- - -## Resources & References - -- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-omsuneri-week03.md b/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-omsuneri-week03.md deleted file mode 100644 index cb26f207..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-omsuneri-week03.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "GSoC’25 Week 03 Update by Om Santosh Suneri" -excerpt: "To Develop a Basic RAG Debugger for Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-06-22" -slug: "2025-06-22-gsoc-25-omsuneri-week03" -author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" -tags: "gsoc25,sugarlabs,week03,Debugger,AI,Music Blocks" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 03 Progress Report by Om Santosh Suneri - -**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) -**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) -**Reporting Period:** 2025-06-15 - 2025-06-21 - ---- - -## Goals for This Week - -- **Goal 1:** Deploy the AI-Powered Debugger App to a Cloud Hosting Platform -- **Goal 2:** Create Embeddings from Music Blocks Project Text Representations -- **Goal 3:** Improve LLM Response Language for Kids and Junior Learners - ---- - -## This Week’s Achievements - -1. **Deploy the AI-Powered Debugger App to a Cloud Hosting Platform** - - This week, I successfully deployed the AI-Powered Debugger application on Streamlit Cloud, making it publicly accessible to anyone interested in testing it. The deployment process included optimizing the app structure for cloud compatibility, setting up environmental variables securely, and ensuring a smooth user experience. The live deployment now allows users—especially educators, learners, and developers—to interact with the debugger without needing to set up anything locally. - - Making the debugger accessible via the web marks a major step in making AI tools more usable and available to the community. It enables initial-stage testing by real users, which is essential for collecting feedback and observing how the debugger performs across different user behaviors. This helps build a feedback loop that will guide future improvements and robustness of the tool, making it more valuable in the long term. - -2. **Create Embeddings from Music Blocks Project Text Representations** - - After performing some minor improvements to the Music Blocks JSON-to-text converter, I selected 14 representative projects from the Music Blocks examples directory. These projects span across a range of tags and categories—such as music composition, transcription, games, utilities, and miscellaneous projects. I then generated vector embeddings for the textual representations of these projects and stored them in a Qdrant vector database cluster. - - These embeddings serve as the foundation for teaching the LLM about the structure and semantics of real-world Music Blocks projects. By creating a searchable knowledge base of real examples, we are equipping the LLM with contextual understanding of how blocks are logically connected and used in different domains. This will significantly improve the LLM’s ability to understand, explain, and debug Music Blocks code based on actual use cases, making it more intelligent and helpful in practice. - -3. **Improve LLM Response Language for Kids and Junior Learners** - - To make the debugger more inclusive and approachable for younger audiences, I updated the LLM prompt with additional guidance that instructs the model to assume the user is a child or junior learner. This involved reworking how queries are framed when sent to the LLM, prompting it to respond in a simpler, clearer, and more encouraging language style suitable for kids. - - Music Blocks is widely used in educational environments, especially among school-age children learning to code. By making the language of AI responses more kid-friendly, we ensure that young learners can better understand and learn from the debugger’s suggestions. This step plays a key role in increasing the educational value, accessibility, and inclusivity of the project, ultimately making learning more fun and effective for our target audience. - ---- - - -## Challenges & How I Overcame Them - -- **Challenge:** Improving ingest.py to Create Embeddings Efficiently - **Solution:** I enhanced the ingest.py script to process the improved text representations generated from various Music Blocks projects. I created and configured a Qdrant cluster to store the generated embeddings. This allowed me to index 14 representative projects across different categories. The modified script now supports smoother ingestion of data into Qdrant, and the embeddings are successfully retrievable for use by the LLM. This improvement lays the foundation for more intelligent, context-aware search and reasoning by the debugger. - -- **Challenge:** Handling Environment Variables in Streamlit Cloud - **Solution:** After some thorough research and trial-and-error, I realized that Streamlit Cloud requires environment variables to be set via their Secrets Manager, not directly via .env files or code. I restructured the way the debugger reads sensitive values like API keys, moving everything into Streamlit's secure secrets.toml configuration. Once set properly, the application worked as expected in the cloud environment. This not only solved the deployment issue but also ensured better security practices moving forward. - ---- - -## Key Learnings - -- Deploying the AI debugger to Streamlit Cloud taught me the importance of environment-specific configurations, especially handling environment variables securely using platform-specific methods like Streamlit’s Secrets Manager. It highlighted how even small deployment details can significantly impact the usability and accessibility of an application. -- Creating embeddings from Music Blocks project representations and integrating them into a Qdrant vector database deepened my understanding of how LLMs can be enhanced with contextual knowledge. I also learned how to structure data ingestion pipelines effectively for scalable and meaningful semantic search. -- Tweaking the LLM prompt to generate child-friendly responses helped me appreciate the importance of audience-aware design in educational tools. It reinforced the idea that technology should be not just functional, but also inclusive, approachable, and aligned with the learning level of its users. - ---- - -## Next Week’s Roadmap - -- Integrate the JSON convertor directly into the Debugger Streamlit app -- Testing the Debugger with Intensive Prompting -- Improving the Quality of LLM Responses - ---- - -## Resources & References - -- **Repository:** [JSON to Text representation](https://github.com/omsuneri/JSON-to-Text-representation) -- **Repository:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) -- **Debugger Streamlit App:** [Music Blocks Debugger](https://debuggmb.streamlit.app/) -- **Directory for Projects:** [Embedding Project Set](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks/tree/main/data/docs) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-saumya-week03.md b/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-saumya-week03.md deleted file mode 100644 index 1086b0ba..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-22-gsoc-25-saumya-week03.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -title: "GSoC '25 Week 03 Update by Saumya Shahi" -excerpt: "This week focused on implementing a comprehensive brick tree model with hierarchical connections, graph-like notch connections, and robust tree management for the Masonry module." -category: "DEVELOPER NEWS" -date: "2025-06-21" -slug: "2025-06-21-gsoc-25-saumya-shahi-week03" -author: "@/constants/MarkdownFiles/authors/saumya-shahi.md" -tags: "gsoc25,sugarlabs,week03,saumya-shahi" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 03 Progress Report by Saumya Shahi - -**Project:** [Masonry Module - Music Blocks v4](https://github.com/sugarlabs/musicblocks-v4) -**Mentors:** [Anindya Kundu](https://github.com/meganindya/) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-15 – 2025-06-21 - ---- - -## Goals for This Week - -- Design and implement a comprehensive brick tree model for managing hierarchical connections -- Implement connection validation based on brick types and notch availability -- Create robust tree management with proper merging and splitting behavior -- Develop comprehensive test coverage for all tree operations - ---- - -## This Week's Achievements - -### 1. **Comprehensive Brick Tree Model Implementation** - -Developed a `BrickTreeManager` class that handles: -- **Tree Structure Management**: Each tree has a unique ID that changes when connections/disconnections occur -- **Hierarchical Connections**: Parent-child relationships where disconnecting a parent keeps children connected -- **Connection Validation**: Ensures bricks can only connect if their notches are compatible and available - -### 2. **Advanced Connection System** - -Implemented a dual connection approach: -- **Top-Bottom Connections**: Hierarchical parent-child relationships -- **Left-Right Notch Connections**: Graph-like where bricks connect only if their right and left notches are free -- **Nested Notch Support**: Support for complex nested brick structures -- **Connection State Tracking**: Real-time tracking of which notches are occupied or available - -### 3. **Tree Management** - -Created tree operations: -- **Tree Merging**: When bricks connect, their respective trees merge into a single tree -- **Tree Splitting**: When bricks disconnect, new trees are formed preserving child relationships -- **Hierarchical Disconnection**: Disconnecting a parent preserves child connections and forms new trees -- **UUID Management**: Each brick has a unique UUID, and trees have dynamic IDs that change with connections - -### 4. **Comprehensive Test Suite** - -Developed extensive test coverage including: -- **Connection Tests**: Validating proper tree merging when bricks connect -- **Disconnection Tests**: Ensuring correct tree splitting behavior -- **Hierarchical Tests**: Testing parent-child relationship preservation -- **Notch Validation Tests**: Verifying connection rules based on notch availability -- **Edge Case Tests**: Handling complex scenarios with multiple connections - -### 5. **Type Safety and Validation** - -Enhanced the type system with: -- **Brick Type Definitions**: Clear interfaces for Simple, Expression, and Compound bricks -- **Connection Validation**: Type-safe connection checking based on brick types -- **Notch Compatibility**: Validation ensuring only compatible notches can connect -- **Error Handling**: Comprehensive error handling for invalid operations - ---- - -## Technical Implementation Details - -### Brick Tree Structure -```typescript -interface BrickTree { - id: string; - bricks: Map<string, Brick>; - connections: Map<string, Connection>; - rootBricks: Set<string>; -} -``` - -### Connection Types -- **Hierarchical Connections**: Top-bottom parent-child relationships -- **Notch Connections**: Left-right graph-like connections -- **Nested Connections**: Complex nested brick structures - -### Key Features -- **Automatic Tree ID Generation**: Trees get new IDs when connections change -- **Connection Validation**: Ensures only valid connections are allowed -- **Hierarchical Preservation**: Child relationships are maintained during disconnections - ---- - -## Challenges & How I Overcame Them - -### Challenge 1: Hierarchical vs Graph-like Connections -**Problem**: Balancing hierarchical parent-child relationships with graph-like notch connections was complex. -**Solution**: Implemented a dual connection system where hierarchical connections manage the tree structure, while notch connections provide the visual puzzle-like behavior. - -### Challenge 2: Tree Splitting Logic -**Problem**: Ensuring that disconnecting a parent brick correctly preserves child relationships and forms new trees. -**Solution**: Developed a algorithm that traverses the tree structure, identifies connected components, and creates new trees while maintaining all valid connections. - -### Challenge 3: Connection Validation -**Problem**: Ensuring that bricks can only connect when their notches are compatible and available. -**Solution**: Created a comprehensive validation system that checks notch types, availability, and compatibility before allowing connections. - -### Challenge 4: Test Coverage -**Problem**: Creating comprehensive tests for complex tree operations and edge cases. -**Solution**: Developed a systematic testing approach covering all major operations, edge cases, and error conditions with clear test descriptions. - ---- - -## Key Learnings - -- **Tree Data Structures**: Deep understanding of tree management, merging, and splitting operations -- **Graph Theory**: Applied graph concepts for notch-based connections -- **Type Safety**: Enhanced TypeScript skills with complex type definitions and validation -- **Testing Strategies**: Learned systematic approaches to testing complex data structures -- **Algorithm Design**: Developed algorithms for tree traversal and component identification - ---- - -## Code Quality Improvements - -- **Comprehensive Documentation**: Added detailed JSDoc comments for all public methods -- **Type Safety**: Enhanced TypeScript interfaces and type checking -- **Test Coverage**: Achieved high test coverage with edge case testing - ---- - -## Next Week's Roadmap - -- **Visual Tree Rendering**: Implement visual representation of the brick tree structure -- **Palette Creation UI**: Create palette interface for rendering list of all bricks -- **Performance Optimization**: Optimize tree operations for large brick structures -- **Integration Testing**: Test the tree model with the existing brick rendering system - ---- - -## Resources & References - -- **Tree Data Structures**: [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects) -- **TypeScript Advanced Types**: [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/advanced-types.html) -- **Testing Complex Data Structures**: [Jest Documentation](https://jestjs.io/docs/getting-started) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for their guidance and support. Special thanks to the community for providing valuable feedback on the tree model design and implementation. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-22-ssoc-2025-MuhammadHaroon-week03.md b/src/constants/MarkdownFiles/posts/2025-06-22-ssoc-2025-MuhammadHaroon-week03.md deleted file mode 100644 index f76a9165..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-22-ssoc-2025-MuhammadHaroon-week03.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: "SSoC ’25 Week 03 Update by Muhammad Haroon" -excerpt: "Experimenting with temperature and top_p parameters in AudioGen model." -category: "DEVELOPER NEWS" -date: "2025-06-22" -slug: "2025-06-22-ssoc-25-MuhammadHaroon-week03" -author: "@/constants/MarkdownFiles/authors/muhammad-haroon.md" -tags: "ssoc25,sugarlabs,week03,GenAI,MusicBlocks,Music" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 03 Progress Report by Muhammad Haroon - -**Project:** [Generative AI Instrument Sample Generation for Music Blocks](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md#Generative-AI-Instrument-Sample-Generation-for-Music-Blocks) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-16 - 2025-06-22 - ---- - -## Goals for This Week - -- **Goal 1:** Generate more samples using AudioGen and save them in Google Drive. -- **Goal 2:** Experiment with temperature and top_p parameters in AudioGen. - ---- - -## This Week's Achievements - -1. **Generated more samples using AudioGen model** - - I was able to generate more samples from AudioGen model and saved them in [Google Drive](https://drive.google.com/drive/folders/10UZzts_AuIe1AypJm9v4ll0NQ0tdkHEI?usp=drive_link). - -2. **Experimented with different values of temperature and top_p** - - I created a [Google Sheet](https://docs.google.com/spreadsheets/d/1tFjL4bXAyB-Z7Fxj4cqiS4_pRkAGo3gKgs-CZVmkFYk/edit?gid=0#gid=0) where I experimented with generating sound samples using different temperature and top_p values. By recording the results, I was able to determine which parameter settings produce more meaningful sound samples. - ---- - -## Key Learnings - -- I gained an understanding of the key parameters temperature and top_p, which are used to tune the output for specific use cases. This [article](https://medium.com/@1511425435311/understanding-openais-temperature-and-top-p-parameters-in-language-models-d2066504684f) was helpful in understanding these concepts. - ---- - -## Next Week's Roadmap - -- To further explore the effects of the temperature and top_p parameters. -- To find an effective method for removing silence and noise from the audio. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-23-dmp-25-therealharshit-week03.md b/src/constants/MarkdownFiles/posts/2025-06-23-dmp-25-therealharshit-week03.md deleted file mode 100644 index 71b6253a..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-23-dmp-25-therealharshit-week03.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: "DMP ’25 Week 03 Update by Harshit Verma" -excerpt: "Week 3 focused on refining the AI prompt for better debugging suggestions, exploring UI ideas for displaying tips, and testing Sugar AI integration with Pippy." -category: "DEVELOPER NEWS" -date: "2025-06-23" -slug: "2025-06-23-dmp-25-therealharshit-week02" -author: "@/constants/MarkdownFiles/authors/harshit-verma.md" -tags: "dmp25,sugarlabs,week03,therealharshit" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 02 Progress Report by Harshit Verma - -**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-16 - 2025-06-22 - ---- - -## Goals for This Week - -- **Goal 1:** Refine the base prompt for debugging tips. -- **Goal 2:** Explore multiple UX approaches for displaying debug output. -- **Goal 3:** Test Sugar AI integration with Pippy. - ---- - -## This Week’s Achievements - -1. **Refine the base prompt for debugging tips** - - Refine the base prompt sent to the AI model to make debugging suggestions clearer and more relevant. - - Iterated by testing different wording styles and instruction formats, which led to noticeably better model output. - -2. **Explore multiple UX approaches for displaying debug output** - - Considered multiple UX designs for displaying debug tips, such as: - * **Inline** messages near code lines. - * A **side panel** exclusively for displaying suggestions.. - * A **Dedicated Debugging Terminal** for interactive debugging. - - Evaluated each method in terms of ease of integration, readability, and user experience. - - Concluded that a dedicated debugging terminal offers the best balance of usability and flexibility. - - Plan to design a UI mockup for this approach in the upcoming week. - -3. **Test Sugar AI integration with Pippy** - - Successfully tested the connection between Pippy and Sugar-AI. - - Verified that the Python code written in Pippy is extracted correctly, sent to the /ask-llm endpoint, and the response is generated. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Crafting prompts that consistently lead to relevant and useful debugging suggestions. - **Solution:** Studied prompt engineering best practices and experimented with structure, examples, and explicit instructions to guide the model better. - -- **Challenge:** Deciding how to present debug output in a child-friendly and non-intrusive way. - **Solution:** Brainstorm some UI ideas, reviewed how other tools display feedback, and consulted with mentors on what would best align with the Sugar UX philosophy. - ---- - -## Key Learnings - -- Gained deeper insight into prompt engineering and its impact on LLM output quality. -- Developed a design-focused mindset for user-centric debugging tools. - ---- - -## Next Week’s Roadmap - -- Plan to design a UI mockup for debugging terminal. -- Implement a first version of the debug output inside Pippy. -- Collect feedback from mentors on debug message placement and design. - ---- - -**Note:** This week, I was mostly away from the keyboard, so I couldn’t dedicate as much time to coding as usual. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-25-gsoc25-firepheonix-week03.md b/src/constants/MarkdownFiles/posts/2025-06-25-gsoc25-firepheonix-week03.md deleted file mode 100644 index 82288044..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-25-gsoc25-firepheonix-week03.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: "GSoC '25 Week 03 Update by Shubham Singh" -excerpt: "Mapped Music from Synthutils to LegoBricks. Completed LegoBricks Wdiget UIs" -category: "DEVELOPER NEWS" -date: "2025-06-25" -slug: "2025-06-25-gsoc-25-firepheonix-week03" -author: "@/constants/MarkdownFiles/authors/shubham-singh.md" -tags: - - gsoc25 - - sugarlabs - - week02 - - firepheonix -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 3 Progress Report by Shubham Singh - -**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) -**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-06-16 – 2025-06-22 - ---- - -## Goals for This Week - -- Complete UIs for image upload, webcam integration to Music Blocks. -- Integrating audios from Synth Sampler to LegoBricks widget. -- Researching existing audio integration patterns in the phrase maker and note blocks. - ---- - -## This Week's Achievements - -1. **Complete Image upload facility into Lego Bricks Widget.** - - Integrated image upload support within the LegoBricks widget, enabling external image input directly on the Music Blocks canvas. - - Created a new block type by modifying six core files across the codebase. - - The codebase proved beautifully encapsulated and thoroughly documented, making the learning curve smoother. -  - -  - -2. **Real-time Video Integration** - - Implemented real-time video functionality through webcam integration. - - Enabled real-time video streaming, with support for dynamic canvas manipulation and block interaction. - - Made grided interface for addition of both image and webcam. Made changes for adjusting. - - <iframe width="800" height="400" src="https://www.youtube.com/embed/HG6C0ZX7QRA?si=OIGvtD4qpwxMmb8W" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> - -3. **Addition of music notations to Lego Bricks widget** - - Researched about where audio samples lie. - - Deep-dived into Phrase Maker, Synth Sampler widget documentation and codebase. - - Applied music samples to Music Blocks. - - <iframe width="800" height="400" src="https://www.youtube.com/embed/PwuPtACP8WM?si=NpfkLI-4SUVkVeU7" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Music Blocks didn't have any code for integrating webcam video on to the Music Blocks interface. -**Solution:** Researched some stack overflow resources and added the webcam video on to the legobricks widget canvas. -- **Challenge:** Finding out where the SVGs and existing phrase maker and synthsampler audio files lie. -**Solution:** Asked my mentor, Walter Bender in Wednesday's meet. Saw some previous PRs inside of music blocks itself, related to phrase maker, related to synth sampler. - ---- - -## Key Learnings - -- Gained comprehensive understanding of **synth utils** and how **music samples are being exported to other blocks** -- Deepened appreciation for **code architecture** including inheritance patterns, code modularity, and custom return types within the Music Blocks ecosystem. -- Improved skills in **development workflow** including exports, imports, code reusability, documentation practices, and collaborative development workflows. - ---- - -## Next Week's Roadmap - -- Implement complete Core Implementation of Scanning the Lego Blocks image on the X-axis. -- Next to Next week -> Test for shadow handling -- Focus on algorithmic challenges for note-to-color mapping system. - ---- - -## Resources & References - -- **Project Issue:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) -- **Music Blocks Repository:** [sugarlabs/musicblocks](https://github.com/sugarlabs/musicblocks) -- **Documentation:** Music Blocks Developer Guide - ---- - -## Acknowledgments - -Thank you to my mentors [Walter Bender](https://github.com/walterbender) and [Devin Ulibarri](https://github.com/pikurasa) for invaluable guidance throughout this development phase. Special thanks to Walter. A lot of code of Music Blocks was written by Walter, he has a very good knowledge of this code base. Can completely rely on him for help. He also helped this week as well. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-28-dmp-25-AmanNaik-week04.md b/src/constants/MarkdownFiles/posts/2025-06-28-dmp-25-AmanNaik-week04.md deleted file mode 100644 index 8493987a..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-28-dmp-25-AmanNaik-week04.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: "DMP ’25 Week 4 Update by Aman Naik" -excerpt: "This week focused on building a basic UI for the chatbot within Sugar and implementing a book recommendation system using the Google Books API." -category: "DEVELOPER NEWS" -date: "2025-06-29" -slug: "2025-06-22-dmp-25-AmanNaik-week04" -author: "@/constants/MarkdownFiles/authors/amannaik247.md" -tags: "dmp25,writeactivity,write,sugarlabs,week04,amannaik247" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 4 Progress Report by Aman Naik - -**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) -**Reporting Period:** 2025-06-22 – 2025-06-28 - ---- - -## Goals for This Week - -- **Goal 1:** Create some UI to test the demo chatbot inside Sugar -- **Goal 2:** Develop a book recommendation feature for the demo application - ---- - -## This Week’s Achievements - -1. **Built a Basic Chatbot UI Inside Sugar** - - Created an initial UI within Sugar using the demo logic from the Streamlit version as reference. - - Implemented a basic sidebar within the activity that allows students to converse with the chatbot while simultaneously viewing the story context. - - The framework generated from the conversation is currently being saved as a JSON file. UI for displaying the framework is still under development and will be added later. - -  - -2. **Implemented Book Recommendation Feature** - - Integrated the Google Books API to recommend the top 3 similar books based on the conversation with the AI assistant. - - The goal is to inspire children by connecting their creative stories with real-world books. - - Based on mentor feedback, I will prioritize refining the chatbot and story framework builder before expanding the recommendation feature. - -  - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Integrating the chatbot into Sugar and dealing with GTK - **Solution:** As I had limited experience with GTK, I faced difficulties while setting up the interface. Additionally, the initial setup used Groq's SDK, which wasn’t compatible with Sugar. I refactored the code to use the `requests` module for calling Groq’s API instead, which made integration possible without extra dependencies. - -- **Challenge:** Displaying the final story framework after clicking the "Create Framework" button - **Solution:** I’m currently working on UI design ideas to present the story structure in a child-friendly and intuitive way. I’ll be discussing different visual layouts with my mentors in the upcoming meeting to finalize a clear and engaging format. - ---- - -## Key Learnings - -**Integrated AI Chatbot Into Sugar's UI Framework** - - Learned how to work with GTK and adapt web-based chatbot logic into a desktop environment suitable for Sugar. - -**Designed Book Recommendation Feature Using Google Books API** - - Built a feature that enriches the student’s experience by recommending related books based on the story they are writing. - -**Improved Problem-Solving Skills While Debugging API and GTK Issues** - - Encountered real-world software integration issues and learned how to handle dependency mismatches and platform limitations effectively. - ---- - -## Next Week’s Roadmap - -- Finalize the UI for the story framework display -- Focus on polishing the conversational flow of the AI assistant -- Exploring LLM's to be used instead of Groq API for AWS integration - ---- - -## Acknowledgments - -Grateful to my mentors, the Sugar Labs community, and fellow contributors for their continuous support and insightful suggestions throughout the week! - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-BishoyWadea-week04.md b/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-BishoyWadea-week04.md deleted file mode 100644 index 9a15bda7..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-BishoyWadea-week04.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "GSoC ’25 Week 04 Update by Bishoy Wadea" -excerpt: "Soma Cube" -category: "DEVELOPER NEWS" -date: "2025-06-28" -slug: "gsoc-25-BishoyWadea-week04" -author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" -tags: "gsoc25,sugarlabs,week04,BishoyWadea" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Bishoy Wadea - -**Project:** [Soma Cube](https://github.com/Bishoywadea/Soma-Cube) -**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) -**Reporting Period:** 2025-06-22 - 2025-06-28 - ---- - -## Goals for This Week - -- **Goal 1:** Make Four Color map game pep8 compliant [#4 Make activity pep8 compliant](https://github.com/Bishoywadea/Four-Color-Map/issues/4) - -- **Goal 2:** Start implementing Soma Cube game ---- - -## This Week’s Achievements - -### *Goal 1: Fix Issues in Four Color Map Activity* - -1. **Make Four Color map game pep8 compliant** - - commit: [Make main.py, activity.py PEP 8 compliant](https://github.com/Bishoywadea/Four-Color-Map/commit/45b2dd77e39a6d822d9d4ba0a12fbf1c31e1f04b) - ---- - -### *Goal 2: Start implementing Soma Cube game* -1. **3D Environment & Controls** - - Set up a 3D scene with movement and camera control. - - commit: [add 3d space with cube](https://github.com/Bishoywadea/Soma-Cube/commit/c917f9d2af509cc4f405f9b72fe8d479e1f3f56f) - - commit: [add wasd controls](https://github.com/Bishoywadea/Soma-Cube/commit/7dc779dbecd693794a2ae96f25ef3aa3dd174c83) - - - -2. **Soma Pieces & Core Mechanics** - - Added the 7 pieces and enabled, rotation, and collision. - - commit: [add the 7 basic pieces](https://github.com/Bishoywadea/Soma-Cube/commit/5ace6710608720ba05bad05df3dac26bbd1907e9) - - commit: [add collision support](https://github.com/Bishoywadea/Soma-Cube/commit/9e1f60943b64718c4efc6deca1a0a077f1e94475) - - - -3. **Interaction & UI Elements** - - Implemented help system, completion message, and on-screen controls. - - commit: [add help button](https://github.com/Bishoywadea/Soma-Cube/commit/f00c1661fc94a9c29e3325c83c916d215a2b1c32) - - commit: [add controls map on screen](https://github.com/Bishoywadea/Soma-Cube/commit/325d9197cedc5dfa6643382fcaf246b681201806) - -4. **Texturing & Visuals** - - Added textures for floor, sky, and Soma pieces with improved lighting. - - commit: [add sky texture](https://github.com/Bishoywadea/Soma-Cube/commit/be08b1c314dccc7f0c984585a1ee19e27664ce89) - - commit: [add texture for the 7 objects](https://github.com/Bishoywadea/Soma-Cube/commit/8b69f60a615037266dc2ae8e89d8ed09a231c1ea) - - - ---- - -## Challenges & Solutions - -- **Challenge:** Implementing precise snapping and collision for 3D puzzle pieces. - **Solution:** Designed a snapping algorithm with bounding box checks and added a collision detection system to prevent overlaps. - -- **Challenge:** Enhancing the visual quality of the 3D scene. - **Solution:** Introduced floor, sky, and object textures; adjusted lighting and shadows for a more polished and immersive look. - -- **Challenge:** Allowing intuitive piece manipulation with both keyboard and mouse. - **Solution:** Integrated context-aware WASD controls and mouse-based dragging/rotating mechanisms for smooth interaction. - -- **Challenge:** Guiding users through gameplay without overwhelming them. - **Solution:** Added an on-screen control map, a help button, and a success message to support the player experience. - -- **Challenge:** Maintaining code readability during rapid feature additions. - **Solution:** Regularly removed redundant code, followed PEP8 guidelines, and modularized logic for easier updates. - ---- - -## Key Learnings - -- Strengthened understanding of **3D graphics programming** using transformations, lighting, textures, and real-time rendering. -- Gained practical experience in **interactive puzzle game design**, including snapping mechanics, collision handling, and visual feedback. -- Improved skills in **UI/UX design for educational tools**, balancing usability, clarity, and visual appeal. -- Practiced clean coding habits with **modular design**, PEP8 compliance, and ongoing refactoring. -- Learned to integrate **multi-modal controls** (keyboard + mouse) for intuitive 3D manipulation. - - ---- - -## Next Week’s Roadmap - -- Fix any feedback provided by members of the organization. -- Start implementing the 16-puzzle game. ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-Elwin-Li-week04.md b/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-Elwin-Li-week04.md deleted file mode 100644 index 87a8955a..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-Elwin-Li-week04.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: "GSoC '25 Week 4 Update by Elwin Li" -excerpt: "Weekly progress report for JSEditor updates" -category: "DEVELOPER NEWS" -date: "2025-06-28" -slug: "2025-06-28-gsoc-25-Elwin-Li-week04" -author: "@/constants/MarkdownFiles/authors/elwin-li.md" -tags: "gsoc25,sugarlabs,week4,javaScript editor" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 4 Progress Report by Elwin Li - -**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/config_driven_conversion/elwin) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) - -**Reporting Period:** 2025-06-21 - 2025-06-28 - ---- - -## Goals for This Week - -- **Goal:** Complete the debugger project - ---- - -## This Week’s Achievements - -**Reworked Status Block for Debugger Tool** - -The main goal of this week was to work out difficulties with the status block and status matrix in regards to the debugger tool. There has been many pivots in terms of the UX design, and it is now going in a cleaner direction. - -How the debugger tool currently works: -- The user can set debugger statements either through the debugger block itself, or adding breakpoints in the JSeditor and converting to blocks. -- The user can now begin debugging through one of three methods: - - Run slowly button - - Run step by step button - - Clicking on a block itself (e.g. an action block) -- This will run the blocks and pause at the debugger block(s) -- The user can then choose to inspect variables by dragging out a status block - - The status block will be automatically prepopulated by all the custom variables that are used in the users code - - The status window will also automatically pop up and show the user their variables - -**Small UI fixes** -- I made it so that block highlighting only highlights the current block being executed, for easier code tracing when using run slowly or run by step. -- I made debugger blocks have no effect when using the normal play button, since that's for a finished product, but it will pause execution when ran slowly, by step, or a user manually runs a stack of blocks -- Changed behavior of manually clicking on blocks to run it default to run slowly, as it is for debugging purposes. -- Fixed bug where execution will continue even if you change/delete blocks - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Having a "debug mode" was not a clean solution - - **Solution:** Instead of having a "debug mode", we now distinguish in terms of the play buttons, with the run slowly and run by step buttons being meant for debugging - -- **Challenge:** Status block doesn't work as intended, and dragging a status block manually behaves differently from the one triggered by the debugger block. There could also be multiple status blocks at the same time, which messed up the status window. - - **Solution:** Constrained the maximum number of status blocks to one, and updated the logic for all status blocks to automatically include the custom variables in the blocklist. - ---- - -## Key Learnings - -- Improved skills in UX design and keeping tools simple for the user -- Deepened understanding of how music blocks execution works -- Deepened understanding of how the blocks are designed and the whole flow of a block -- Improved skills in **debugging**, **code design**, and **collaboration workflows**. - ---- - -## Next Week’s Roadmap - -- Complete and deploy debugger project -- Add syntax highlighting to JSeditor code - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-mostlyk-week04.md b/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-mostlyk-week04.md deleted file mode 100644 index ec64af5e..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-28-gsoc-25-mostlyk-week04.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "GSoC '25 Week 4 Update by Krish Pandya" -excerpt: "Python Library Graphics " -category: "DEVELOPER NEWS" -date: "2025-06-28" -slug: "2025-06-28-gsoc-25-mostlyk-week04" -author: "@/constants/MarkdownFiles/authors/krish-pandya.md" -tags: "gsoc25,sugarlabs,week04,mostlyk" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 4: Development on the Python Library - -**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) - -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky), [Juan Pablo Ugarte](https://github.com/xjuan) - -**Reporting Period:** June 21, 2025 till June 28, 2025 - ---- - - -## Style , MenuItem and Changes - -I seem to have missed updating about the Python start on the last week's blog. -This week has 2 videos and less of text! Sorry about that , I will try to summarize the video trascripts for my beloved reading enthusiasts. - -<iframe width="560" height="315" src="https://www.youtube.com/embed/OD1PBOK3g94?si=NT8wfgk7UkQt6gxl" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> - -This short video covers the initial Python layout and CI pipeline. I’ve structured the repo cleanly: - -- `make ci-test` now runs a clean, install, test and build. -- Removed the linting stage since we're not enforcing strict import ordering (consistent with GTK3’s sugar-toolkit style). So it is always going to fail on the top import, but I have kept the formatting check!. -- Wheel gets built automatically , and is stored inside `dist/`. Following this we can also build tar using `make tarbell`, also stored inside `dist/`. - -On the graphics front, I wired up a base activity with `XOColors`, and a simple close button. This will expand soon as more components are added. -I'm planning to move forward with alert icons, styled windows, and the tool bar to give our activities the "sugary" look. - -> So that was written on Sunday (22nd) and while at the time of writing some more things are added mentioned and demoed in the next video!. - - -I urge you to go to [sugar-toolkit-gtk4-py](https://github.com/MostlyKIGuess/sugar-toolkit-gtk4-py)'s README as it also has a quick start activity which you can directly bump up. Cheers! - -And the next video which is a bit long (_6 mins_) where I talk about what I did this week is: - -<iframe width="560" height="315" src="https://www.youtube.com/embed/-WTojjHpQLs?si=m0msTtsXOvzDTTP-" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> - -This longer video goes into the real dev work of the week. - -- Fixed deprecated API usage in styles by warning users when they try to use old GTK3-style methods, and re-routing to the newer alternatives. I have shown this in video specifically. -- Built a `MenuItem` wrapper that supports icons, keyboard accelerators, as used `Gtk.Button` rather than `GtkImageMenuItem` which is deprecated. -- On styles, I added something more like `primary`, `success`, etc. The last section in style example shows this. -- Demonstrated accelerators (`Ctrl+O`, `Ctrl+S`, `Ctrl+Q`). these are now working using the newer GTK4 shortcut handling instead of relying on `GtkImageMenuItem` and it's older signal. - - -## Sneak Peek & Road Ahead - -Near around 3-4 min mark I started giving the sneak peeks haha, and take this as for the work of week 5-6, and let's see how fast it can be pushed. A bit rough, but fun stuff: - -- Vertical tray widgets with clickable icons and buttons. -- Fullscreen and window information tools. -- Sugar artwork preview with randomized XO colors. ( sanity check if colors are working again v2) -- First version of the window and tray abstraction layers (some bugs but foundational). -- Starting experiments with `Palette`, `Tray`, and `Toolbar`. - -This is the first time I'm actively trying to integrate things built in Week 3 and 4 into full activity flows. -The idea is to not just build features in isolation but make sure they cooperate. - -Ideally I want to have some sort of more quick start activity which uses bunch of these Palettable, Toolbar, Style etc. to see everything in action. - -## Resources & References - -- Project Page – [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) -- New C Library - [sugar-ext repository](https://github.com/sugarlabs/sugar-ext) -- New Python Library - [sugar-toolkit-gtk4-py ](https://github.com/MostlyKIGuess/sugar-toolkit-gtk4-py) -- Active PR - [Establish C library base template with Meson for GTK4](https://github.com/sugarlabs/sugar-ext/pull/1) -- Sugar Toolkit Repository(original) – [sugar-toolkit-gtk3](https://github.com/sugarlabs/sugar-toolkit-gtk3) -- GTK4 Migration Guide – [docs.gtk.org/gtk4/migrating-3to4.html](https://docs.gtk.org/gtk4/migrating-3to4.html) - - ---- - -## Acknowledgments - -Thanks to all the mentors whose guidance and support have been strong in helping me navigate the Port. diff --git a/src/constants/MarkdownFiles/posts/2025-06-29-dmp-24-justin212407-week04.md b/src/constants/MarkdownFiles/posts/2025-06-29-dmp-24-justin212407-week04.md deleted file mode 100644 index 3dd6cc09..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-29-dmp-24-justin212407-week04.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: "DMP’25 Week 04 Update by Justin Charles" -excerpt: "Completed SVG path logic for all brick types and documented props and rendering states" -category: "DEVELOPER NEWS" -date: "2025-06-29" -slug: "2025-06-29-dmp-25-justin212407-week04" -author: "@/constants/MarkdownFiles/authors/justin-charles.md" -tags: "dmp25,sugarlabs,week4,justin212407" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 4 Progress Report by Justin Charles - -**Project:** Music Blocks 4 Masonry -**Mentors:** [Anindya Kundu](https://github.com/meganindya/) -**Assisting Mentors:** [Devin Ulibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Reporting Period:** 2025-06-22 - 2025-06-29 - ---- - - -## Goals for This Week - -- Finalize SVG path logic for all three types of bricks -- Categorize and document all props passed into bricks -- Identify all visual states a brick can be rendered in -- Differentiate props and states across brick types -- Write comprehensive tests to verify correctness - ---- - -## This Week’s Highlights - -### 1. Brick Inventory Compilation - -- Catalogued different distinct bricks across categories such as Rhythm, Tone, Flow, Graphics etc. -- Created a centralized metadata list including notches, label types, and slot counts for each. - -### 2. JSON Schema for Brick Types - -- Authored a strict `bricks-schema.json` enforcing required fields like `type`, `label`, `notches`. -- Validated all brick entries programmatically and corrected inconsistencies (e.g. naming errors and missing defaults). - -### 3. Palette UI Implementation - -- Built a dynamic React Palette UI that maps categories and bricks from the schema directly. -- Enabled hover previews showing live-rendered brick paths and labels. -- Schema-driven architecture allows zero-maintenance scalability. - -📄 Reference: [Palette – Tab 6](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.2dd4jqek61qh#heading=h.nicqc6ugqkyy) - ---- - -## Challenges & Solutions - -**Challenge: Handling Bricks with Special Properties** -Some bricks (e.g., compound or expression bricks) required special handling due to nested structures, variable slots, or dynamic notches. -**Solution:** Added metadata flags to the brick definitions (e.g., `hasNotchTop`) and incorporated them into both the schema and UI logic. - - -**Challenge: Bricks with Ambiguous Labels or Duplicate Names** -A few bricks had similar or identical display labels, which caused confusion in UI previews and JSON definitions. -**Solution:** Assigned internal id fields distinct from display labels. The id ensures uniqueness in JSON and tests, while label stays user-friendly in the UI. - ---- - -## Key Learnings - -- Source-code scraping can outperform manual documentation in accuracy and speed. -- JSON Schema offers powerful safeguards when used with validation tooling. -- UI scalability improves drastically when tied to a schema-first approach. - ---- - -## Resources & References - -- [Palette](https://docs.google.com/document/d/1C0t4iSze2eDEv6lWbloK3MnvJgAa6HvmXmk2sQ0lCZs/edit?tab=t.2dd4jqek61qh#heading=h.nicqc6ugqkyy) -- [musicblocks-v4 Repository](https://github.com/sugarlabs/musicblocks-v4) - ---- - -## Acknowledgments - -Thanks to my mentors for helping review the UI and desgin for the palette. Their early feedback made the path code significantly more robust and maintainable. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-29-dmp-25-AnvitaPrasad-week04.md b/src/constants/MarkdownFiles/posts/2025-06-29-dmp-25-AnvitaPrasad-week04.md deleted file mode 100644 index 2bc32a55..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-29-dmp-25-AnvitaPrasad-week04.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: "DMP '25 Week 04 Update by Anvita Prasad" -excerpt: "Completion of target pitch mode and implementation of manual cent adjustments pie menu" -category: "DEVELOPER NEWS" -date: "2025-06-29" -slug: "2025-06-29-DMP-25-AnvitaPrasad-week04" -author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" -tags: "dmp25,sugarlabs,week04,AnvitaPrasad" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Anvita Prasad - -**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) -**Mentors:** [Walter Bender](https://github.com/walterbender) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-23 - 2025-06-29 - ---- - -## Goals for This Week -- Complete and refine target pitch mode implementation -- Implement manual cent adjustment functionality and interface -- Research icons for chromatic and target pitch mode -- Conduct comprehensive testing with various audio sources and instruments -- Research different tuning systems - ---- - -## This Week's Achievements - -1. **Dual-Mode Tuner Implementation** - - Completed target pitch mode implementation with enhanced functionality - - Integrated target pitch selector with pie menu interface - - Implemented logic for precise pitch matching and deviation calculation - - Added comprehensive display for octave, semitone, and cent deviations - - Gathered and incorporated feedback for interface refinements - - - -2. **Manual Cents Adjustment Development** - - Designed and implemented an intuitive pie menu for cent adjustments with: - - Center Area (Controls): - * Grey circular area with three buttons - * "+" button for positive values - * "-" button for negative values - * "×" button for menu exit - - Inner Wheel (Fine Adjustments): Numbers 1-10 - - Middle Wheel (Medium Adjustments): Numbers 20-50 - - Outer Wheel (Large Adjustments): Numbers 60-100 - -3. **Testing Progress** - - Conducted initial testing with various audio sources - - Identified areas for improvement in pitch detection - - Created a test suite for tuner accuracy verification - ---- - -## Challenges & How I Overcame Them - -- **Challenge 1: Event Bubbling in Pie Menu** - The pie menu's nested event listeners for note, accidental, and octave selection were triggering multiple unintended actions due to incorrect event propagation. - **Solution 1:** - Added event.stopPropagation() at the appropriate event handlers and restructured the event listener hierarchy to ensure events were captured at the correct level only. - -- **Challenge 2: State Management Complexity** - Managing three interdependent states (note, accidental, octave) in the tuner widget led to synchronization issues and undefined states during updates. - **Solution 2:** - Implemented a centralized state update method that handles all three components atomically and validates the complete state before triggering any dependent calculations. - ---- - -## Key Learnings - -- Gained deep understanding of Music Blocks' pitch pie menu interface and its implementation patterns -- Learned about various tuning systems including Equal Temperament, Pythagorean, and Just Intonation - ---- - -## Next Week's Roadmap - -- Implement fully functional tuner with comprehensive features -- Complete and refine manual cent adjustment functionality -- Conduct extensive testing with various audio sources and instruments -- Consider implementation of different tuning systems -- Make fine refinements to tuner interface and functionality -- Write blog post for Week 05 - ---- - -## Resources & References - -- [Web Audio API Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) -- [Different Tuning Systems](https://www.musiccrashcourses.com/lessons/tuning_systems.html) -- [Tuning Systems and Equal Temperament](https://www.earmaster.com/music-theory-online/ch06/chapter-6-2.html) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support and valuable feedback on the new features. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-29-dmp-25-therealharshit-week04.md b/src/constants/MarkdownFiles/posts/2025-06-29-dmp-25-therealharshit-week04.md deleted file mode 100644 index 5b8d3ec4..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-29-dmp-25-therealharshit-week04.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "DMP ’25 Week 04 Update by Harshit Verma" -excerpt: "Developed a working prototype." -category: "DEVELOPER NEWS" -date: "2025-06-29" -slug: "2025-06-29-dmp-25-therealharshit-week04" -author: "@/constants/MarkdownFiles/authors/harshit-verma.md" -tags: "dmp25,sugarlabs,week04,therealharshit" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Harshit Verma - -**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-23 - 2025-06-29 - ---- - -## Goals for This Week - -- **Goal 1:** Design a UI mockup for the debugging terminal. -- **Goal 2:** Develop the debugging terminal in Pippy. -- **Goal 3:** Connected the debugger LLM server with Pippy. -- **Goal 4:** Feed LLM responses into the debugging terminal. - ---- - -## This Week’s Achievements - -1. **Design a UI mockup for the debugging terminal** - - Plan the layout and user experience for how debug tips should appear inside Pippy. - - Design the UI of the debugging terminal, prioritized clarity and accessibility, especially for children. - -2. **Develop the debugging terminal in Pippy** - - Added a new Virtual Terminal Emulator (VTE) widget to Pippy using GTK. - - Integrated the terminal into the existing layout with proper toggling between output and debug views. -  -  - -3. **Connected the debugger LLM server with Pippy** - - Wired up Pippy to make API calls to the FastAPI server. - - Verified complete flow: `code is extracted → sent to /debug → response displayed in the debug terminal`. - -4. **Feed LLM responses into the debugging terminal** - - Successfully passed LLM-generated debug suggestions into the terminal. - - Added simple formatting: newline, spacing, removed markdown syntax elements. ---- - -### Complete Demo: [Watch here](https://drive.google.com/file/d/1Dzomam9dc3U4tHjHhYFGjRbs7-cwJHmM/view?usp=drive_link) - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** GTK app crashing on API call. - **Solution:** The crash was due to API response handling on the main GTK thread. I fixed it by offloading the network request to a separate thread using Python’s `threading` module and updating the UI safely with `GLib.idle_add()` to avoid blocking or GTK context violations. - -- **Challenge:** Rendering formatted output inside the terminal widget. - **Solution:** GTK doesn’t support Markdown, so I simulated structure using spacing, and removed marksown syntax elements to enhance readability. - ---- - -## Key Learnings - -- Gained hands-on experience with Python threading to perform non-blocking API calls and prevent UI freezes or crashes. -- Learned how to work with GTK widgets and using CSS in GTK, especially Gtk.Stack, Gtk.Box, and VTE terminal building responsive interfaces. - ---- - -## Next Week’s Roadmap - -- Format the LLM response to be more child friendly. -- Develop a custom mardown parser for GTK. -- Begin working on model selection logic and performance optimization. - ---- - -## Resources & References - -**Repository** -- [Pippy](https://github.com/therealharshit/Pippy/tree/DMP2025/Pippy-Debugger) : I have pushed my code for Pippy here. -- [pippy-debugger-server](https://github.com/therealharshit/pippy-debugger-server) : The FastAPI server which I am using as of now. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-MebinThattil-week03.md b/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-MebinThattil-week03.md deleted file mode 100644 index d63c414c..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-MebinThattil-week03.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: "GSoC ’25 Week 04 Update by Mebin J Thattil" -excerpt: "A new voice for Speak & laying down pipelines" -category: "DEVELOPER NEWS" -date: "2025-06-29" -slug: "2025-06-29-gsoc-25-mebinthattil-week4" -author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" -tags: "gsoc25,sugarlabs,week04,mebinthattil,speak_activity" -image: "assets/Images/GSOCxSpeak.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Mebin J Thattil - -**Project:** [Speak Activity](https://github.com/sugarlabs/speak) -**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-22 - 2025-06-29 - ---- - -## Goals for This Week - -- **Goal 1:** Integrate Kokoro into Speak -- **Goal 2:** Create a pipeline to quickly quantize and run a model hosted on 🤗 - ---- - -## This Week’s Achievements - -_Note: I was on leave this week till the 26th due to my final exams. But I still managed to do a bunch of cool stuff after that._ - -1. **Kokoro meets Speak - A new chapter** - - One of the three major parts of my proposal was to integrate a more modern, natural-sounding TTS model into Speak. - - I used Kokoro and integrated it with the activity. - - We now have access to the entire catalog of voices that Kokoro comes with. This will be helpful for our idea of having different personas—each persona could have a different voice. - - The current implementation of the code is a _rather hacky_ way of integrating Kokoro. I say this because the audio pipeline currently looks like this: - > Text → Kokoro → Outputs a temporary WAV file → Read by GStreamer → Audio output can be heard - - This is not ideal for obvious reasons. We don't want Kokoro to save an audio file every time and then read from it again. This is slow because Kokoro has to process the entire text, convert it to a WAV, and then GStreamer has to read and output it. For smaller text inputs it's still fine, but it’s not optimal. - - The better approach would be to have Kokoro stream the audio directly, which GStreamer can then stream and output. This would reduce perceived latency significantly. Kokoro currently does not have a function / API that works like this. I would have to make one. - - But for now, this is just an initial implementation to get feedback from mentors and peers, optimization can come later. - - Kokoro also uses the espeak-ng engine as a fallback. Since Speak already uses espeak, I’ll try to go under the hood and tweak Kokoro to use espeak instead. This would reduce additional dependencies. - - Currently, I was able to get this working with just 125KB of additional dependencies. - -Video demo: -<iframe src="https://drive.google.com/file/d/19oUe3oIlMIO_pFUHVZatR6uWP1u23oU7/preview" width="740" height="480" allow="autoplay"></iframe> - -_Note that the recording has a slight echo, but that's the recordings issue, it sounds perfectly fine inside of speak._ - -2. **Quantization Pipeline** - - This is fairly simple. I created a script that: - > pulls a model hosted on 🤗 → sets up all local dependencies → quantizes the model → exports it as a GGUF → and uses a plugin script (model dependent) to run it in chat mode. - - Currently, this works only for chat-styled models. - - This was essential because we are fine-tuning foundational models, and after fine-tuning we get unquantized models. It doesn't make sense to benchmark these unquantized versions. We need to evaluate their performance post-quantization to truly understand their behavior. - - This script could also be useful for other contributors training models intended to run locally. - - The config for the script is shown below and can adjusted to match whichever model you intend to use: - ```bash - # Model Config - - MODEL_REPO="hfusername/modelname" - GGUF_OUT="output_model_name.gguf" - GGUF_QUANT="output_model_name-q4.gguf" - N_CTX=2048 - BUILD_DIR="build" - SAVED_DIR_NAME_HF="output_dir_name" - ``` - - Another thing to note is the URL to the plugin inference script: - ```bash - RAW_URL="https://raw.githubusercontent.com/mebinthattil/template_llama_chat_python/main/chatapp.py" - ``` - - This script tries to be OS agnostic, and attempts to detect which OS you're on to run commands accordingly. It’s not fully comprehensive yet, but it works well on macOS, as that’s the only platform I’ve tested it on. - ---- - -## Next Week’s Roadmap - -- Integrate the SLM into Speak -- Test out different Kokoro voices -- Lay the foundations for different personas and automatic voice selection - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for their ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-Nikhil-Bhatt-week04.md b/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-Nikhil-Bhatt-week04.md deleted file mode 100644 index c918b644..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-Nikhil-Bhatt-week04.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: "GSoC '25 Week 04 Update by Nikhil Bhatt" -excerpt: "Integrated the frontend with the Git backend and enabled project creation, editing, and forking via the UI in MusicBlocks." -category: "DEVELOPER NEWS" -date: "2025-06-29" -slug: "2025-06-29-gsoc-25-nikhilbhatt-week04" -author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" -tags: "gsoc25,sugarlabs,week04,nikhilbhatt" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Nikhil Bhatt - -**Project:** [Git backend for MusicBlocks](https://github.com/benikk/musicblocks-backend) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Reporting Period:** 2025-06-22 – 2025-06-28 - ---- - -## Goals for This Week - -- Integrate the frontend with the backend Git routes. -- Enable project creation and editing via UI. -- Build a dashboard to list and manage all projects. - ---- - -## This Week's Achievements - -### Frontend-Backend Integration - -I created a dedicated branch in the MusicBlocks repo to begin integrating the Git backend routes. - -- Created API calls to interact with the backend for: - - Creating a new project. - - Editing an existing one. - - Forking a project. - - -### Create & Edit Projects from UI - -Users can now: - -- Create new projects from the frontend. -- Edit and update existing ones. - -This is made possible by sending project name and data to the backend, which handles Git commit and push operations. - ---- - -### Project Dashboard - -Built a new page to display **all projects** (original and forked) in a list format. - -Features include: - -- “Open in MusicBlocks” to edit any project. -- “Fork” to create a copy with the current user as owner. -- Display of metadata like project name, fork status, and last updated time. - -**All Projects Dashboard** - - ---- - -## Challenges & How I Solved Them - -- **Challenge:** Avoiding Git complexity on the frontend. - **Solution:** All operations like branch creation, commits, and metadata updates are handled server-side. Frontend only triggers them. - -- **Challenge:** Keeping fork lineage visible. - **Solution:** Stored original repo metadata inside `metaData.json` of each fork. - ---- - -## Key Learnings - -- How to bridge frontend interfaces with a Git-based backend. -- Improved UI/UX by keeping it simple, made it similar to existing planet page for students to learn. - ---- - -### Fun Debug Moment - -Accidentally forked a fork of a fork and ended up with a hilarious recursive repo tree. -But it confirmed my fork metadata system worked perfectly across multiple levels! - ---- - -## Next Week's Roadmap - -- Build UI to submit pull requests from forks. -- Display list of pull requests and metadata. - ---- - -## Resources & References - -- [MusicBlocks Frontend Repo](https://github.com/sugarlabs/musicblocks) -- [musicblocks-backend](https://github.com/benikk/musicblocks-backend) -- [GitHub REST API for PRs](https://docs.github.com/en/rest/pulls/pulls) -- [Octokit REST.js Library](https://github.com/octokit/rest.js) - ---- - -## Acknowledgments - -Thanks again to my mentors and the Sugar Labs community for feedback and support! -Looking forward to next week’s frontend PR features. - diff --git a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-SafwanSayeed-week04.md b/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-SafwanSayeed-week04.md deleted file mode 100644 index 58338dd6..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-SafwanSayeed-week04.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: "GSoC '25 Week 4 Update by Safwan Sayeed" -excerpt: "AST to IR Implementation" -category: "DEVELOPER NEWS" -date: "2025-06-29" -slug: "2025-06-29-gsoc-25-sa-fw-an-week4" -author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" -tags: "gsoc25,sugarlabs,week4,sa-fw-an" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 4 Progress Report by Safwan Sayeed - -**Project:** Music Blocks 4 Program Engine -**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-06-23 - 2025-06-29 - ---- - -## A Blog-style Retrospective - -This week marked a significant milestone in our Music Blocks program engine development as we transitioned from the foundational memory architecture to the core compilation logic. The focus shifted to implementing the AST-to-IR (Intermediate Representation) translation layer - the crucial bridge between our abstract syntax tree representation and executable code. - ---- - -## Goals for This Week - -- Complete the AST-to-IR compilation logic technical specification with detailed pseudocode patterns. -- Implement the AST Parsing logic for all expression classes returning instruction lists. ---- - -## This Week's Highlights - -1. **AST-to-IR Compilation Logic Specification** - - Expanded the tech spec with comprehensive AST-to-IR translation documentation covering expression and statement compilation patterns. - - Detailed instruction list generation requirements and variable management strategies. - - Link: [IR Compilation Logic](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.i655udul8zuq) - -2. **Implemented AST Parsing Logic** - - Developed parsing logic for all expression classes, ensuring they return the correct instruction lists. - ---- - -## Challenges & Solutions - -- **Understanding Static vs Runtime Compilation:** - Initially confused about whether we were performing runtime calculations or static code translation. - *Solution:* Mentors clarified that this is purely static AST-to-IR conversion with no runtime execution, helping focus the implementation approach. - - ---- - -## Key Learnings - -- Gained a deeper understanding of static compilation principles and the importance of maintaining clean instruction generation patterns. -- Learned how to effectively manage variable scopes and dependencies during the AST-to-IR translation process. - ---- - -## Next Week's Roadmap - -- Finalize the AST-to-IR compilation logic implementation for all expression and statement classes. -- Begin integrating the IR generation with the memory management system to ensure proper variable resolution. -- Start working on the execution engine that will interpret the generated IR instructions. ---- - -## Resources & References - -- **Tech Spec:** [AST to IR Methods](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.87123fra3s4#heading=h.gqjcwrtkdgvq) -- **Repository:** [musicblocks-v4](https://github.com/sugarlabs/musicblocks-v4) - ---- - -## Acknowledgments - -Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their crucial guidance on compiler design principles and static compilation concepts. Their clarification on the AST-to-IR translation approach and emphasis on maintaining clean instruction generation patterns was essential for this week's successful progress. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-diwangshu-week04.md b/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-diwangshu-week04.md deleted file mode 100644 index 3a9c4626..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-diwangshu-week04.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: "GSoC ’25 Week 04 Update by Diwangshu Kakoty" -excerpt: "Implementing a Reasoning-Enabled AI Model" -category: "DEVELOPER NEWS" -date: "2025-06-29" -slug: "2025-06-29-gsoc-25-diwangshu-week04" -author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" -tags: "gsoc25,sugarlabs,week04,AI" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Diwangshu Kakoty - -**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) -**Reporting Period:** 2025-06-22 - 2025-06-28 - ---- - -## Goals for This Week - -- **Goal 1:** Leveraging Gemini's Thinking Feature. -- **Goal 2:** Code Migration: LangChain → Gemini SDK. -- **Goal 3:** Clean up the codebase. -- **Goal 4:** Make sample summaries to test the 'Analyis' feature. -- **Goal 5:** Fix bugs occured by these changes. - ---- - -## This Week’s Achievements - -1. **Using Gemini's 'Think' Capability for Enhanced Responses** - - I have implemented the 'thinking' capability of the Gemini model in the multi-agent chat model. This allows the LLM to break down complex queries into smaller, manageable parts, leading to more accurate and relevant responses. - - - But it came with a challenge, as LangChain's Gemini module does not support the 'thinking' capability directly (more on this in the challenges section). - -2. **Code Migration: LangChain → Gen AI SDK** - - As mentioned in the last point, LangChain's Gemini module does not support the 'thinking' capability. Therefore, I have started migrating the 'generation' code from LangChain to the official Gen AI SDK. This migration allows us to use the 'thinking' capability and other features of the Gemini model dynamically. - - - The official Gen AI SDK allows us to use the 'think' dynamically, which means the LLM can decide when to use the 'thinking' capability based on the complexity of the query. It also allows us to specify the number of thinking tokens aka 'thinkingBudget' to be used or set it to auto. This flexibility is crucial for optimizing the performance and cost of using the Gemini model. - -3. **Cleaning Up the Codebase** - - I have cleaned up the codebase by structuring the code into separate files, functions and modules. This makes the code more organized and easier to maintain. - ---- - -## Challenges & How I Overcame Them - -- **Challenge :** LangChain's Gemini module does not support the 'thinking' capability directly. This project uses RAG (Retrieval-Augmented Generation) with LangChain, which is a popular framework for building LLM applications. While the retrieval part works well, the generation part needs to be changed. But it is not that simple. The Gen AI SDK uses its own library for storing conversations, which is different from LangChain. - - **Solution:** There's no doubt that leveraging the reasoning capabilities of the Gemini model can significantly enhance response quality. However, as this is still an evolving technology, full support in LangChain is likely to emerge soon. For testing purposes, a complete migration isn't necessary at this stage. Therefore, I've implemented two separate classes: `llm` and `reasoning_llm`, which initialize `Gemini-1.5-flash` and `Gemini-2.5-flash`, respectively. The `llm` class handles general queries, while `reasoning_llm` is dedicated to writing algorithms for the project code when passed as a query. The `Gemini-2.5-flash` is the model that supports and uses the 'thinking' capability by default. - - This is a temporary arrangement. If I get positive feedback from the mentors, I will proceed with the complete migration of the 'generation' code to the official Gemini SDK. - ---- - -## Key Learnings - -- While working on this project, I explored extensive documentation for both Gemini and LangChain. This deep dive significantly enhanced my understanding of LLMs, including concepts like structured output, function calling, code execution, reasoning capabilities, and various prompting techniques. - ---- - -## Next Week’s Roadmap - -- Build a developer settings in the sidebar to allow testers to choose between the 'llm' and 'reasoning_llm' classes for each query. -- Work on things suggested by mentors. This could include: - - Full migration of the 'generation' code to the official Gen AI SDK. -- Developing sample summaries to test the 'Analysis' feature. - ---- - -## Resources & References - -- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-omsuneri-week04.md b/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-omsuneri-week04.md deleted file mode 100644 index 2a38a11d..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-omsuneri-week04.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: "GSoC’25 Week 04 Update by Om Santosh Suneri" -excerpt: "AI-powered Debugger for Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-06-29" -slug: "2025-06-29-gsoc-25-omsuneri-week04" -author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" -tags: "gsoc25,sugarlabs,week04,Debugger,AI,Music Blocks" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Om Santosh Suneri - -**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) -**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) -**Reporting Period:** 2025-06-22 - 2025-06-28 - ---- - -## Goals for This Week - -- **Goal 1:** Testing the Debugger with Intensive Prompting -- **Goal 2:** Improving the Quality of LLM Responses -- **Goal 3:** Making the Debugger Interactive and Kid-Friendly - ---- - -## This Week’s Achievements - -1. **Testing the Debugger with Intensive Prompting** - - I carried out extensive testing of the debugger by feeding it a wide range of Music Blocks projects and crafting diverse prompts to simulate how real users — especially children — might ask questions or seek help. This allowed me to observe how the LLM interprets different project structures and how effectively it can guide users toward understanding and improving their project. - - Debugging is not just about fixing errors — it’s also about discovering new possibilities. Through this intensive testing, I was able to identify how the debugger could become a more intuitive assistant. Ensuring it understands various project contexts means kids can explore their creativity more freely, knowing they have a tool that helps them understand what’s happening and what more they can do. It moves the debugger from being reactive to being proactively supportive. - -2. **Improving the Quality of LLM Responses** - - I focused on tuning the LLM prompts to ensure that the responses it generates are not only accurate but also clear, structured, and easy to understand for children. I experimented with different prompt formats, simplified technical jargon, and shaped the tone to be more friendly and encouraging. The goal was to make every response feel like it’s coming from a helpful companion, not a complicated machine. - - For many young learners, especially those just starting their journey into coding and music, complex feedback can be discouraging. By improving the quality of responses, I’ve made the debugger more approachable and effective as an educational tool. This change ensures that kids receive feedback they can truly learn from. - -3. **Making the Debugger Interactive and Kid-Friendly** - - One of my main goals this week was to make the debugger feel more alive and responsive. I improved the system prompts to encourage a more interactive and friendly tone. Additionally, I introduced a feature where the debugger can automatically detect key elements of a project right after it is loaded — such as the instruments used, patterns in sequences, or loops — and immediately offer feedback or suggestions. This turns the debugger into more of a conversational partner than just a tool. - - Young minds learn best when they feel engaged and supported. By making the debugger more interactive and giving it the ability to respond to a project from the moment it is initialized, the experience becomes more seamless and enjoyable. Kids no longer have to wait or guess what to do next — they’re gently guided and encouraged to explore, learn, and improve. It transforms the debugger into a playful mentor that supports learning through interaction, discovery, and fun. - ---- - -## Deployed Project -- **Music Blocks Debugger:** [Live Demo](https://debuggmb.streamlit.app/) - -<a href=""><img src="https://i.ibb.co/p6H5y3Bw/Screenshot-2025-06-28-at-10-41-28-AM.png" alt="Music Blocks Debugger"></a> - -- **JSON to Text Converter:** [Live Demo](https://omsuneri.github.io/JSON-to-Text-representation/) - -<a href=""><img src= "https://i.ibb.co/ycNPrKVs/Screenshot-2025-06-28-at-10-42-38-AM.png" alt="JSON to Text Converter"></a> - -## Challenges & How I Overcame Them - -- **Challenge:** Refining System Instructions for Better LLM Responses - **Solution:** One key challenge I encountered was fine-tuning the system instructions to consistently get high-quality, relevant responses from the LLM. The solution was to conduct extensive testing using a variety of prompts and project types. This helped me understand how the model interprets different contexts and allowed me to iteratively improve the instructions for more accurate, helpful, and kid-friendly outputs. - ---- - -## Next Week’s Roadmap - -- Integrate real-time response improvement based on project complexity. -- Enhance system prompts further through prompt-chaining and context tuning. -- Improving the Quality of LLM Responses - ---- - -## Resources & References - -- **Repository:** [JSON to Text representation](https://github.com/omsuneri/JSON-to-Text-representation) -- **Repository:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) -- **Debugger Streamlit App:** [Music Blocks Debugger](https://debuggmb.streamlit.app/) -- **Directory for Projects:** [Embedding Project Set](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks/tree/main/data/docs) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-saumya-week04.md b/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-saumya-week04.md deleted file mode 100644 index 3fde225a..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-29-gsoc-25-saumya-week04.md +++ /dev/null @@ -1,188 +0,0 @@ ---- - -title: "GSoC '25 Week 04 Update by Saumya Shahi" -excerpt: "This week focused on implementing advanced tree rendering with nested, stacked, and argument brick support, dynamic sizing for the masonry module." -category: "DEVELOPER NEWS" -date: "2025-06-29" -slug: "2025-06-29-gsoc-25-saumya-shahi-week04" -author: "@/constants/MarkdownFiles/authors/saumya-shahi.md" -tags: "gsoc25,sugarlabs,week04,saumya-shahi" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Saumya Shahi - -**Project:** [Masonry Module - Music Blocks v4](https://github.com/sugarlabs/musicblocks-v4) -**Mentors:** [Anindya Kundu](https://github.com/meganindya/) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-22 – 2025-06-29 - ---- - -## Goals for This Week - -- Implement advanced tree rendering with nested, stacked, and argument brick support -- Develop dynamic brick sizing based on content and children -- Create comprehensive validation systems for brick connections -- Establish robust rendering algorithms with proper traversal strategies -- Integrate the complete tree rendering system into the storybook - ---- - -## This Week's Achievements - -### 1. **Advanced Tree Rendering System Implementation** - -Developed a brick tree rendering system that handles three distinct connection types: - -#### **Stacked Tree Rendering** -- **Vertical Stacking**: Bricks can be connected vertically in sequence below their parent -- **Cumulative Height Calculation**: Total height of stacked trees is calculated by summing individual brick heights -- **Width Optimization**: Stacked trees maintain optimal width by taking the maximum width of all stacked bricks - - -#### **Argument Brick Rendering** -- **Expression-Only Validation**: Implemented validation ensuring only Expression bricks can be used as arguments -- **Slot-Based Positioning**: Argument bricks are positioned at specific argument slots on their parent bricks -- **Dynamic Slot Management**: Parent bricks automatically adjust their argument slots based on the number of arguments - - -#### **Nested Tree Rendering** -- **Multi-Level Nesting**: Implemented support for bricks nested inside compound bricks, which can themselves contain nested bricks -- **Dynamic Sizing**: Parent bricks automatically resize based on their nested children's bounding boxes -- **Proper Positioning**: Nested bricks are positioned at calculated connection points within their parent containers - - -### 2. **Dynamic Brick Sizing and Layout System** - -#### **Label Width Adjustment** -- **Dynamic Text Measurement**: Implemented canvas-based text measurement for accurate label width calculation -- **Real-Time Updates**: Brick dimensions update automatically when labels change -- **Fallback System**: Robust fallback for server-side rendering when canvas is unavailable - - -#### **Child-Based Resizing** -- **Bounding Box Calculation**: Parent bricks recalculate their bounding boxes based on their children's dimensions -- **Compound Brick Layout**: Compound bricks expand their nested regions to accommodate all nested children -- **Automatic Geometry Updates**: Brick geometry updates trigger re-rendering with new dimensions - - -### 3. **Advanced Rendering Algorithms** - -#### **Two-Phase Rendering Strategy** -- **Phase 1 - Preorder Traversal**: Calculate all bounding boxes and dimensions from root to leaves -- **Phase 2 - Postorder Traversal**: Render from leaves to root, ensuring children appear on top of parents -- **Z-Index Management**: Proper layering prevents visual conflicts between nested elements - -#### **Bounding Box Computation** -```typescript -function computeBoundingBoxes(allNodes: Map<string, ExtendedTreeNode>) { - // Preorder traversal for dimension calculation - // Handles nested, argument, and stacked children - // Updates compound brick layouts with nested content - // Returns comprehensive bounding box map -} -``` - -### 4. **Comprehensive Validation Systems** - -#### **Brick Type Validation** -- **Nesting Validation**: Only Compound and Simple bricks can be nested inside other bricks -- **Argument Validation**: Only Expression bricks can be used as arguments -- **Connection Validation**: Ensures compatible brick types for different connection types - -#### **Connection Point Validation** -- **Notch Compatibility**: Validates that connecting bricks have compatible notch types -- **Slot Availability**: Ensures argument slots are available before allowing connections -- **Nested Space Validation**: Verifies sufficient space in compound bricks for nested children - -### 5. **Brick Model System** - -Refined the brick model architecture with advanced features: -- **SimpleBrick**: Basic statement bricks with configurable notches and argument support -- **ExpressionBrick**: Value-holding bricks with expression support and argument-only usage -- **CompoundBrick**: Container bricks with nested children support and dynamic sizing - ---- - -## Technical Implementation Details - -### Advanced Tree Structure -```typescript -interface ExtendedTreeNode extends TTreeNode { - isNested?: boolean; // Indicates nested brick - argIndex?: number; // Argument slot index - children?: { - nested: ExtendedTreeNode[]; - args: ExtendedTreeNode[]; - stacked: ExtendedTreeNode[]; - }; -} -``` - -### Dynamic Sizing Algorithm -```typescript -function updateCompoundBrickLayouts(nodes: Map<string, ExtendedTreeNode>) { - // Calculate total nested content dimensions - // Update compound brick's bboxNest array - // Trigger geometry recalculation - // Update connection points -} -``` - -### Validation System -```typescript -function validateBrickConnection(parent: BrickModel, child: BrickModel, type: ConnectionType) { - switch(type) { - case 'nested': - return parent.type === 'Compound' || parent.type === 'Simple'; - case 'argument': - return child.type === 'Expression'; - case 'stacked': - return child.type !== 'Expression'; // expression brick can't be stacked - } -} -``` - ---- - -## Challenges & How I Overcame Them - - -### Challenge 1: Compound Brick Layout with Multiple Nested Children -**Problem**: Compound bricks needed to accommodate multiple nested children with varying sizes and positions. -**Solution**: Implemented a two-phase approach: first calculate all child dimensions, then update parent bounding boxes and trigger geometry recalculation. Developed a recursive algorithm that calculates bounding boxes bottom-up, then renders top-down with proper z-indexing to ensure children appear above parents. - -### Challenge 2: Label Width Calculation and Dynamic Updates -**Problem**: Bricks needed to resize based on their label text, requiring accurate text measurement and real-time updates. -**Solution**: Implemented canvas-based text measurement with fallback for server-side rendering, and integrated it into the brick geometry update system. - - - ---- - -## Key Learnings - -- **Advanced Tree Algorithms**: Deep understanding of preorder/postorder traversal for different rendering phases -- **Dynamic Layout Systems**: Learned how to implement responsive layouts that adapt to content changes -- **Canvas Text Measurement**: Mastered techniques for accurate text measurement in web environments -- **Z-Index Management**: Gained expertise in managing visual layering in complex nested structures -- **Type-Safe Validation**: Enhanced skills in creating comprehensive validation systems with TypeScript - ---- - -## Resources & References - -- **Tree Traversal Algorithms**: [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects) -- **Canvas Text Measurement**: [MDN Canvas Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) -- **TypeScript Validation Patterns**: [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/advanced-types.html) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for their guidance and support. Special thanks to the community for providing valuable feedback on the tree model design and implementation. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-30-gsoc-25-AdityaKrSingh26-week07.md b/src/constants/MarkdownFiles/posts/2025-06-30-gsoc-25-AdityaKrSingh26-week07.md deleted file mode 100644 index 32cba0a9..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-30-gsoc-25-AdityaKrSingh26-week07.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -title: "GSoC ’25 Week 07 Update by Aditya Kumar Singh" -excerpt: "Enhanced shared mode synchronization for Tour and Doctor activities, improved scoring visualization, and camera state persistence in the 3D Human Activity." -category: "DEVELOPER NEWS" -date: "2025-06-30" -slug: "2025-06-30-gsoc-25-AdityaKrSingh26-week07" -author: "@/constants/MarkdownFiles/authors/aditya-singh.md" -tags: "gsoc25,sugarlabs,week07,AdityaKrSingh26" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 07 Progress Report by Aditya Kumar Singh - -**Project:** [Sugarizer](https://github.com/llaske/sugarizer) -**Mentors:** [Lionel Laské](https://github.com/llaske) -**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) -**Reporting Period:** 2025-06-19 - 2025-06-25 - ---- - -## Goals for This Week - -- **Goal 1:** Implement shared mode synchronization for Tour activity -- **Goal 2:** Enhance Doctor mode to show XO Icons and name with real-time scoring visualization -- **Goal 3:** Persist camera zoom and orientation across sessions -- **Goal 4:** Add support for side and back view positioning in Tour - ---- - -## This Week’s Achievements - -1. **Shared Tour Mode** - - Implemented broadcast message `tourStep` carrying the part index & name; the host fires it and peers replay it to keep camera position and mesh highlight in lock-step. - - Added graceful join-in-progress sync: newcomers receive the current step and camera pose on `syncAllPaintData`, so nobody is “mid-tour-lost”. -  - ```javascript - // Broadcast tour step to other users - presence.sendMessage(presence.getSharedInfo().id, { - user: presence.getUserInfo(), - action: "tourStep", - content: { - index: tourIndex, - partName: part.name - } - }); - - // Sync handler - function syncTourStep(index, partName) { - const part = bodyParts[index]; - const currentMesh = currentModel.getObjectByName(part.mesh); - - // Highlight mesh - currentMesh.material = new THREE.MeshStandardMaterial({ - color: new THREE.Color("#ffff00"), - emissive: "#ffff00", - emissiveIntensity: 0.2 - }); - - // Position camera - camera.position.set( - part.position[0], - part.position[1], - part.position[2] + 5 - ); - camera.lookAt(part.position[0], part.position[1], part.position[2]); - } - -2. **Shared Doctor Mode** - - Re-used the Presence layer from Paint mode to emit nextQuestion / answer / scoreUpdate events. - - First-correct-gets-the-point logic now lives entirely on the host - - Peer-to-peer visual feedback: *correct click flashes the mesh green, wrong click red*; scores float next to each user’s XO badge -  -  -  - - -3. **Camera & Zoom Persistence** - - Stored `cameraPosition`, `cameraTarget`, and `cameraFov` in the Journal JSON when the Stop icon is pressed. - - On activity resume we restore both orbit target and FOV, giving users continuity—especially useful after deep-dive zooms into organs. - ```javascript - // Saving camera state - function saveCameraState() { - return { - position: { - x: camera.position.x, - y: camera.position.y, - z: camera.position.z - }, - target: { - x: orbit.target.x, - y: orbit.target.y, - z: orbit.target.z - }, - fov: camera.fov - }; - } - // Restoring camera state - function restoreCameraState(state) { - camera.position.set(state.position.x, state.position.y, state.position.z); - orbit.target.set(state.target.x, state.target.y, state.target.z); - camera.fov = state.fov; - camera.updateProjectionMatrix(); - orbit.update(); - } - -4. Side and Back View Support for Tour -- Extended body part data (`organParts.json`) to include `sideView` and `frontView` flags. -- Tour camera now automatically adjusts orientation: - - **Side view** → +X - - **Back view** → −Z - - **Front view** → +Z (default) -- Created adaptive camera logic in `activity.js` to interpret these flags. -  -  - - ---- - -## Key Learnings - -- Three.js Camera Control: Mastered advanced camera manipulation techniques -- Real-time Sync Patterns: Developed robust synchronization for 3D interactions -- Educational UX: Learned principles for effective learning feedback systems - ---- - -## Next Week’s Roadmap - -- Write Weekly Blog Post summarizing progress, screenshots, and key learnings. -- Fix remaining issues for Human body mentioned in PR -- Start to implement the dashboard features of the stickman activity: draw, move -- Start with implementing the Frame part of the stickman activity, add a frame, remove a frame, - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-06-30-ssoc-2025-MuhammadHaroon-week04.md b/src/constants/MarkdownFiles/posts/2025-06-30-ssoc-2025-MuhammadHaroon-week04.md deleted file mode 100644 index 3a5d599d..00000000 --- a/src/constants/MarkdownFiles/posts/2025-06-30-ssoc-2025-MuhammadHaroon-week04.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "SSoC ’25 Week 04 Update by Muhammad Haroon" -excerpt: "Experimenting with prompts parameter in AudioGen model." -category: "DEVELOPER NEWS" -date: "2025-06-30" -slug: "2025-06-30-ssoc-25-MuhammadHaroon-week04" -author: "@/constants/MarkdownFiles/authors/muhammad-haroon.md" -tags: "ssoc25,sugarlabs,week04,GenAI,MusicBlocks,Music" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Muhammad Haroon - -**Project:** [Generative AI Instrument Sample Generation for Music Blocks](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md#Generative-AI-Instrument-Sample-Generation-for-Music-Blocks) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-23 - 2025-06-30 - ---- - -## Goals for This Week - -- **Goal 1:** To further explore the effects of the temperature and top_p parameters. -- **Goal 2:** To find an effective method for removing silence and noise from audio. - ---- - -## This Week's Achievements - -1. **Explored the effects of the temperature and top_p parameters** - - After experimenting with different temperature and top_p values, I found that AudioGen performs well with temperature = 1 and top_p = 1 values, generating audio that closely matches the prompt. - -2. **Found effective method for removing silence and nosie form audio** - - I found python libraries for removing silence (pydub) and noise (noisereduce) from the audio and it gave good results. - ---- - -## Next Week's Roadmap - -- Generate more samples using different prompts. -- Explore how to connect backend with the frontend using FastAPI. -- Explore how to deploy the backend on AWS. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-01-gsoc-25-firepheonix-week04.md b/src/constants/MarkdownFiles/posts/2025-07-01-gsoc-25-firepheonix-week04.md deleted file mode 100644 index cbd12952..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-01-gsoc-25-firepheonix-week04.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "GSoC '25 Week 04 Update by Shubham Singh" -excerpt: "Pivoted from Point Scanner to Line Scanner, got some real results." -category: "DEVELOPER NEWS" -date: "2025-07-01" -slug: "2025-07-01-gsoc-25-firepheonix-week04" -author: "@/constants/MarkdownFiles/authors/shubham-singh.md" -tags: - - gsoc25 - - sugarlabs - - week02 - - firepheonix -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 4 Progress Report by Shubham Singh - -**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) -**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-06-23 – 2025-06-30 - ---- - -## Goals for This Week - -- Implement complete Core Implementation of Scanning the Lego Blocks image on the X-axis. -- Focus on algorithmic challenges for note-to-color mapping system. - ---- - -## This Week's Achievements - -1. **Tested out the scanning errors. Realized the scanning single pixels isnt' gonna work.** - - So after testing out multiple errors, I realized that the DOT scanning method just isn't working that accurately(only ~40% accuracy). It's completely because of the core functionality of how the method itself works. - - So, I realized there has to be a better method than this. Scanning have been taking place for a long time. There had to be a better method than this. - - Began reverse engineer everything. Questioning every decision I've made for this project. Going to the very core of how the entire process, storage, time complexity is going on with the dot method. -  - -2. **Tested out spherical method. Failed.** - - Implemented the spherical method. It basically takes an AVERAGE of all the pixels underneath it rather than a scanning a single pixel. I did this keeping in mind more and more accuracy, - - Little did I know, I ran into more errors and worse accuracy than before. - -  - -3. **Finally reached an optimal, LINE scanner. Highly balanced. Got to a VERY good accuracy level.** - - Learned it the hard way why all bar code scanners are line type scanners. Why all machines (like, even your local printer machine/ or laser scan) follow the line scanning method. Got the best results and very a good accuracy. - -  - - - Now, this doesn't mean that the line scanner doesn't have it's cons. It has cons like the texture-confusion in a place where the block's edge is there, and the green background. But, such a confusion edge is only for a VERY small time. I predict it to be < 0 ms, hence automatically being ignored by the algorithm. And there are some issues still left to be fixed. - -4. **Made an output system for TESTING the accuracy of algorithm.** - - I ofc was not able to see how my output is through a mere array{{}} type console.log(). - - So, I developed this method of outputting of the colors on .png type image. To make it visually seem like the image itself for a DIRECT comparision. - -  - -  - - - Now I am rather thinking of making use of THIS .png output instead, it's simply good. Should I? Or should I not? Gonna have to ask from my mentors and do some research on this. - - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Was getting stressed about why am I not able to get the accuracy I need. -**Solution:** Reverse engineered stuff. Thought on my own. Research on youtube- how do scanning algorithms actually work? -- **Challenge:** Not being to see if my algorithm is accurate or not. -**Solution:** Made it output the array in the format of a .png format instead of a simple console.log(array). - ---- - -## Key Learnings - -- Reverse engineering always works. Dive in the BASICS. See the core of how everything is working. Make your human brain work more than asking AI for suggestions. It's possible that you're making things complicated with AI when the answer is really simple and lies in basic thinking. -- Figuring out what will work <<<< Figuring out what DOES NOT WORK. - ---- - -## Next Week's Roadmap - -- Implement the exisiting music blocks number to color mapping system that already exists (as suggested by my mentor, Walter) -- Implementing the dynamic input of NOTES like in the phrase maker. -- Figure out how the phrase maker has many different instuments with different audio files and LOADING them into legobricks.js -- Fix some more issues in the scanning that are visible to me. -- Once the above is done, we can move to mapping the lengths to corresponding notation lengths and production of musical notations. Initial weeks will be mostly figuring out the method for figuring out length of each block for each notation, am I going to use grid? Or will I use The lengths? Or will it be the time? - ---- - -## Resources & References - -- **Some youtube videos related to arduino color detection** - ---- - -## Acknowledgments - -Thank you to my mentors [Walter Bender](https://github.com/walterbender) and [Devin Ulibarri](https://github.com/pikurasa) for invaluable guidance throughout this development phase. Special thanks to Devin. I had typhoid last week due which I had a week of backlog in my work. He didn't mind at all. Happy have such cooperative mentors :p . -P.S.: I've finally caught up to the work I missed. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-05-dmp-25-AmanNaik-week05.md b/src/constants/MarkdownFiles/posts/2025-07-05-dmp-25-AmanNaik-week05.md deleted file mode 100644 index caf87e6c..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-05-dmp-25-AmanNaik-week05.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: "DMP ’25 Week 5 Update by Aman Naik" -excerpt: "This week focused on improving the story framework display UI and attempting to deploy an LLM model on AWS." -category: "DEVELOPER NEWS" -date: "2025-07-05" -slug: "2025-06-05-dmp-25-AmanNaik-week05" -author: "@/constants/MarkdownFiles/authors/amannaik247.md" -tags: "dmp25,writeactivity,write,sugarlabs,week05,amannaik247" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 5 Progress Report by Aman Naik - -**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) -**Reporting Period:** 2025-06-29 – 2025-07-05 - ---- - -## Goals for This Week - -- **Goal 1:** Finalize the UI to display the generated story framework -- **Goal 2:** Create an API endpoint to host an LLM model on AWS - ---- - -## This Week’s Achievements - -1. **Worked on Story Framework Display UI** - - Designed and implemented a widget within Sugar to display the generated story framework. - - Although the basic version is functional, it still needs design improvements to make it more engaging and intuitive for children. - -  - -  - - -2. **Attempted AWS LLM Deployment** - - Made an initial attempt to deploy an LLM model on AWS. - - Faced permission issues during the process, which blocked progress. I plan to resolve this in discussion with mentors and continue deployment next week. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Creating a child-friendly UI for the framework display - **Solution:** Designing a UI that clearly represents story elements while remaining easy to understand for young learners was tricky. Through trial and error, and repeated testing, I managed to connect the output with the UI successfully. - -- **Challenge:** AWS deployment blocked by permission issues - **Solution:** Will consult with mentors to resolve the issue and resume progress on hosting the LLM next week. - ---- - -## Key Learnings - -**Learned the Complexity of Designing Educational UIs** - - UI for children must be both simple and informative. Building the framework display taught me how to balance functionality with visual clarity. - -**Encountered and Tackled Real-World Deployment Hurdles** - - Faced permission-related roadblocks during AWS deployment. This helped me understand the practical challenges of managing cloud-based services. - -**Learned the Importance of LLM Selection and Hosting Before Testing Flow** - - Since I am working with a Groq API using llama-versatile-70b model for testing. But due to license issues this wont be the final API used for deployment. - - Realized that choosing and hosting the right LLM model is critical before properly testing the conversation flow. The AI’s behavior is tightly linked to the model used, making this step a top priority for the coming week. - ---- - -## Next Week’s Roadmap - -- Finalize the LLM model and deploy it on AWS -- Complete and finalize the story framework display UI - ---- - -## Acknowledgments - -Thank you to my mentors and the Sugar Labs community for their continued feedback, guidance, and patience as I work through these technical and design challenges. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-2025-mostlyk-week05.md b/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-2025-mostlyk-week05.md deleted file mode 100644 index e7e9b08e..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-2025-mostlyk-week05.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: "GSoC '25 Week 5 Update by Krish Pandya" -excerpt: "Animations, Toolbars, and a Playable Game" -category: "DEVELOPER NEWS" -date: "2025-07-05" -slug: "2025-07-05-gsoc-25-mostlyk-week05" -author: "@/constants/MarkdownFiles/authors/krish-pandya.md" -tags: "gsoc25,sugarlabs,week05,mostlyk" -image: "assets/Images/GSOC.png" ---- - -# Week 5: Animations, Toolbars, and a Playable Game - -**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) - -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky), [Juan Pablo Ugarte](https://github.com/xjuan) - -**Reporting Period:** June 22, 2025 – June 28, 2025 - ---- - -## Travel and Context - -This week started with an 8-hour flight from Hyderabad to Diu ( my hometown ) between Sunday and Monday. -And _YES_ , I am home, sweet home. It was fun working on animations , toolbars and the game. - - -## Animations and Toolbars - -So as discussed and sneak peeked in last week, first part was finishing the toolbar integration and that was done! I also added animations.py. -I have always been a big fan of animations, my first addition to my [PKMS Site](https://pkms.vercel.app/) ( Personal Knowledge Management System ) was a handcrafted and personal documentation of Manim which a python animation library. - -Now it has a lot of things but it started as a manim documentation. - -### Animations - -Added a few clean effects: - -- `fade-in` and `fade-out` -- `color` transitions -- `scale-down` - - -### Toolbars - -Features include and tested in example: - -- Full range of buttons: open, save, undo, redo, cut, copy, paste -- Multi-select toggles, zoom controls, view modes -- Toolbuttons ( This requires palette somehow so will be updated next week. Sorry for the wait! ) -- And because of that if someone wants to play the game, you would have to wait till next week for the palette finish and the ToolButton addition in library. - - -## Why Not HelloWorld Yet? - -The actual HelloWorld example has more dependencies than just graphics. It needs: - -- `widgets.py` -which further needs: - - `RadioButton`, `ToolButton`, `ToolBarButton`, `PaletteMenuBox` etc. - - A bunch of internal glue that isn't finalized yet - -A good HelloWorld will take a few more weeks to land, realistically. -It requires almost all graphics-related components working in unison. Instead of rushing a half-baked HelloWorld, I decided to make something fun using what I already have. - - -## The Game: Super Ball Dodge - -<iframe width="560" height="315" src="https://www.youtube.com/embed/B517C_LTCns?si=u4zGfRp0yEJca8_O" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> - -So I built a game. It's simple, but fully interactive, and it uses the toolkit as it currently exists ( well it uses ToolButton which is half baked, so you would be able to play it by next week, can watch the video to see what it is though! ). - -### Game Mechanics - -- Use `WASD`, arrow keys, or toolbar buttons to move -- Press `P` to pause, `R` to restart -- Touch the red ball and you lose -- Hitting walls increases your speed and randomizes your color -- Max speed is capped to keep it playable - -This game is both a stress test and a fun break. It's a good way to validate rendering, event handling, animation, and user interaction at once. -Also it kind of stands like a hello world alternative for now before everything is done in unison and final decisions are made. - - -## Summary of Progress - -- Built and finalized core animations -- Integrated and tested full-featured toolbar -- Added working event bindings and accelerators -- Created Super Ball Dodge as a game/activity testbed - ---- - -## Next Steps - -- Refactor window tests (they're not up to standard yet) -- Finalize and commit `widgets.py`, `ToolButton`, and all of `pallete` stuff. -- Start building the actual HelloWorld once widget infra is stable - ---- - -## Links - -- [Project Page](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) -- [Toolkit Repo (Python)](https://github.com/MostlyKIGuess/sugar-toolkit-gtk4-py) -- [sugar-ext (C bindings)](https://github.com/sugarlabs/sugar-ext) -- [Game Demo Video](https://youtu.be/B517C_LTCns) - - -## Closing Thoughts - -It's funny how animations were the thing that got me into this headspace of _I GOTTA DO SOMETHING DYNAMIC_ , and I have always loved geometry and maths. And I got to introduce and do something related to that this week and this game was the result of what came out this week and I am glad I got to do it. - -Until next week, -Krish! -(P.S. If you couldn’t tell already , I love hiding pop culture references and breaking the fourth wall in these posts. So yes, you, yup, you alright, the reader.... enjoy.) diff --git a/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-BishoyWadea-week05.md b/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-BishoyWadea-week05.md deleted file mode 100644 index dc6d8cf0..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-BishoyWadea-week05.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "GSoC ’25 Week 05 Update by Bishoy Wadea" -excerpt: "Fifteen Puzzle" -category: "DEVELOPER NEWS" -date: "2025-07-05" -slug: "gsoc-25-BishoyWadea-week05" -author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" -tags: "gsoc25,sugarlabs,week05,BishoyWadea" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Bishoy Wadea - -**Project:** [Fifteen Puzzle](https://github.com/Bishoywadea/FifteenPuzzle) -**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) -**Reporting Period:** 2025-06-29 - 2025-07-05 - ---- - -## Goals for This Week - -- **Goal 1:** Start implementing Fifteen Puzzle Game ---- - -## This Week’s Achievements - -### *Goal 1: add helpful video tutorial in Soma Cube Game* - -1. **add video in help button** - - commit: [modify code to handle help videos](https://github.com/Bishoywadea/Soma-Cube/commit/63a7daaa8009f5f54791cdf9081e765846135f70) - ---- - -### *Goal 2: Start implementing Fifteen Puzzle Game* -1. **UI Foundation & Game Board** - - Set up the game window with a functional 4x4 puzzle grid and animated tile movements. - - commit: [add basic board UI](https://github.com/Bishoywadea/FifteenPuzzle/commit/ee2a8ec0a87949a93f0093b558de5d760ef66d59) - - commit: [add animation for the board](https://github.com/Bishoywadea/FifteenPuzzle/commit/a09f407451cb0772eff80d605509854d76522d17) - - - -2. **Core Logic & Gameplay** - - Added full logic for tile shifting, move counting, and puzzle completion detection. - - commit: [add game logic](https://github.com/Bishoywadea/FifteenPuzzle/commit/28d835400fb80c32d0eebba7c08f83fcfe9f9c63) - -3. **Help System & UI Integration** - - Introduced help instructions and integrated the help button into the top toolbar for easier access. - - commit: [add help button](https://github.com/Bishoywadea/FifteenPuzzle/commit/494f212f83e469fe2f3c24dd54e398c903a77dcc) - - - - - ---- - -## Challenges & Solutions - -- **Challenge:** Creating a responsive and user-friendly tile movement system. - **Solution:** Implemented smooth tile animations and move validation logic to ensure accuracy and a satisfying user experience. - -- **Challenge:** Designing a clean UI that adapts to game states like playing, winning, or seeking help. - **Solution:** Built a modular UI with conditionally rendered elements such as move counters, help overlays, and success animations for clarity and flow. ---- - -## Key Learnings - -- Gained hands-on experience in building grid-based puzzle logic, including tile shifting, move tracking, and win condition detection. - ---- - -## Next Week’s Roadmap - -- Fix any feedback provided by members of the organization. -- Start implementing the Euclid’s Game. ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-Elwin-Li-week05.md b/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-Elwin-Li-week05.md deleted file mode 100644 index 5cece8f7..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-Elwin-Li-week05.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: "GSoC '25 Week 5 Update by Elwin Li" -excerpt: "Weekly progress report for JSEditor updates" -category: "DEVELOPER NEWS" -date: "2025-07-05" -slug: "2025-07-05-gsoc-25-Elwin-Li-week05" -author: "@/constants/MarkdownFiles/authors/elwin-li.md" -tags: "gsoc25,sugarlabs,week5,javaScript editor,debugger,syntax highlighting" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 5 Progress Report by Elwin Li - -**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/config_driven_conversion/elwin) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) - -**Reporting Period:** 2025-06-29 - 2025-07-05 - ---- - -## Goals for This Week - -- **Goal:** Complete the debugger project and add syntax highlighting - ---- - -## This Week’s Achievements - -**Made PR for Debugger Project** - -The debugger project has been complete and a [PR has been made](https://github.com/sugarlabs/musicblocks/pull/4717). The functionalities that have been described in the [previous weeks post](https://www.sugarlabs.org/news/developer-news/2025-06-28-gsoc-25-Elwin-Li-week04) are all included in this PR, and the demonstration video is below: - -[youtube: ZVqi7zIJ9kw] - -**Basic Syntax Highlighting** - -I've added basic syntax highlighting to the JS editor, making it more pleasing to the eye. - -<a href="https://ibb.co/23vbzVqq"><img src="https://i.ibb.co/RT35Xr22/Screenshot-2025-07-06-at-12-28-58-AM.png" alt="Syntax Highlight"></a> - ---- - -## Key Learnings - -- Improved skills in UX design and keeping tools simple for the user -- Deepened understanding of highlightjs -- Improved skills in **debugging**, **code design**, and **collaboration workflows**. - ---- - -## Next Week’s Roadmap - -- Complete syntax highlighting to JSeditor code (including error highlighting) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-MebinThattil-week05.md b/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-MebinThattil-week05.md deleted file mode 100644 index fdb4de9c..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-MebinThattil-week05.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: "GSoC ’25 Week 05 Update by Mebin J Thattil" -excerpt: "New brains and new voices for Speak!" -category: "DEVELOPER NEWS" -date: "2025-07-06" -slug: "2025-07-06-gsoc-25-mebinthattil-week5" -author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" -tags: "gsoc25,sugarlabs,week05,mebinthattil,speak_activity" -image: "assets/Images/GSOCxSpeak.png" ---- - -<!-- markdownlint-disable --> - -# Week 05 Progress Report by Mebin J Thattil - -**Project:** [Speak Activity](https://github.com/sugarlabs/speak) -**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-29 - 2025-07-06 - ---- - -## Goals for This Week - -- **Goal 1:** Test out different Kokoro voices -- **Goal 2:** Integrate the SLM into Speak - ---- - -## This Week’s Progress - -### **1. Hey Kokoro, you sound different today** - -This week, I tested out different voices of Kokoro in two different ways: - -1. I tested them inside Speak, within Sugar, and it worked. It still uses the _hacky_ way of creating a temporary WAV file and then playing it via GStreamer, but it works. Streaming will be introduced soon. - - **Under-the-hood changes:** - - Kokoro currently uses the following stack: - > Text → Kokoro → handle phonemes via G2P engine → Misaki (primary G2P) → fallback → Espeak-ng - - Speak already uses Espeak. - - So I swapped Misaki's fallback with Espeak (instead of Espeak-ng) to reduce dependencies. - - I’ve yet to encounter a case that triggers the fallback, as Misaki is already quite good. - -2. I deployed a web app that lets you generate and mix audio. You can try it out [here](https://newstreamlit-frontend.blackpond-9921706d.eastus.azurecontainerapps.io/). - - The primary reason this was built as a web app is so that we can get kids to test this out and having things as a web app makes it easier. It's cruical for us to get real world feedback before proceeding with the implementation. - - This web app allows you to try out a plethora of different voices and also mix and match different voices to create basically infinite combinations. It's truly amazing the kind of voices you can create with this. - -  - - - It's a container app, meaning both the frontend (Streamlit) and backend (Kokoro - FastAPI) run as separate Docker containers hosted on Azure. - - The [Kokoro - FastAPI](https://github.com/mebinthattil/Kokoro-FastAPI) exposes an OpenAI-compatible API to generate audio. - - This allows us to stream audio output to a client using OpenAI’s Python libraries, like so: - - ```python - from openai import OpenAI - - client = OpenAI( - base_url="http://my_kokoro_backend:8880/v1", api_key="not-needed" - ) - - with client.audio.speech.with_streaming_response.create( - model="kokoro", - voice="af_sky+af_bella", # single or multiple voicepack combo - input="Hello world!" - ) as response: - response.stream_to_file("output.mp3") - ``` - - - Another potential application of this setup (deploying as separate containers) is to bring Kokoro into pre-existing Speak with minimal dependency changes. - - This would work on low end machines with a stable internet connection, as audio is generated server-side and streamed to the client. - - While this wasn’t in the original plan, the current architecture makes it a _possibility_ worth exploring. - - The original plan was to have an offline only version of Kokoro that Speak uses for it's voice. - -#### _Understanding and playing with Kokoro:_ - -- **How voice names are read** - - Kokoro has a catalog of voices like `af_bella` or `af_sky`. - The first letter of the voice name indicates the language: - - `a` for American English - - `b` for British English - - `j` for Japanese - - `m` for Mandarin Chinese - - `s` for Spanish - - `f` for French - - `h` for Hindi - - `i` for Italian - - `p` for Brazilian Portuguese - - The second letter indicates gender: - - `m` for male - - `f` for female - - So `af_bella` would be American English, female. - -- **Different language options:** - - These do two things: - 1. Speak the text with an accent. - 2. Handle the language-specific text more effectively. - - Example: Using `hf_alpha` with both Hindi and English: - Input: - > नमस्ते, आप कैसे हैं? I can also speak in English as well! - - Output audio: - <iframe src="https://drive.google.com/file/d/1vd0V3hoZlEYQBhm9clSeeDz25qwtwXEE/preview" width="450" height="50" allow="autoplay"></iframe> - - I speak Hindi, and I can confirm it sounds correct. - This is a great example of how Kokoro can help kids learning new languages by combining accent and language aware pronunciation. - -- **Voice mixing:** - - - You can mix any of the available Kokoro voices. - - Mixing is done by assigning weights (between 0 and 1) to each voice. - - For example, mixing two voices with 0.5 weight each gives a 50-50 blend. - - Mixing three voices with weights 0.6, 0.3, and 0.1 gives a 60-30-10 blend. - - This allows for basically infinite voice combinations. - - This could be super useful for building *personas* in Speak, as each persona could have a unique voice! - -  - -**Links:** -- [Streamlit web app](https://newstreamlit-frontend.blackpond-9921706d.eastus.azurecontainerapps.io/) -- [Kokoro - Fast API](https://github.com/mebinthattil/Kokoro-FastAPI) -- [Streamlit Source Code](https://github.com/mebinthattil/Streamlit-Kokoro-Voice-Mixer-Demo) - ---- - -### **2. New brains for Speak** - -- I used the previously quantized Tiny Llama 1B GGUF model with llama-cpp-python inside Sugar, using it as the backend for Speak’s chatbot. -- Using llama-cpp gave great performance boosts, but there's a catch: - - Llama-cpp needs to be built for each OS and architecture. - - This complicates distribution and packaging. - - We can’t shift the build process to the client since most of them are using constrained hardware. - -- So I tried a different approach: fine-tune a smaller model that doesn't need such optimizations. -- I chose [Llama 135M](https://huggingface.co/amd/AMD-Llama-135m) (yes, *M*, not *B* 😄) and fine-tuned it on my [educational conversation dataset](https://github.com/mebinthattil/Education-Dialogue-Dataset). -- I cleaned and extended the dataset (cleanup scripts are in the repo). -- The model was fine-tuned on AWS Sagemaker. You can find the files [here](https://huggingface.co/MebinThattil/Llama-135M-FT/tree/main). -- The unquantized size is ~500MB, so post-quantization it should shrink further. - -But... - -- I didn’t proceed with quantization because the raw performance post finetuning wasn’t up to expectations. -- So next step: gather better data, retrain, and re-evaluate. -- Will also discuss next directions with mentors after the next fine-tune round. - ---- - -## Next Week’s Roadmap - -- Work on mechanics for voice switching and personas inside sugar. -- Improve dataset quality. -- Fine-tune the model again and evaluate performance. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for their ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-firepheonix-week05.md b/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-firepheonix-week05.md deleted file mode 100644 index 880e94a9..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-05-gsoc-25-firepheonix-week05.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: "GSoC '25 Week 05 Update by Shubham Singh" -excerpt: "Building and testing out the Image to video player" -category: "DEVELOPER NEWS" -date: "2025-07-05" -slug: "2025-07-05-gsoc-25-firepheonix-week05" -author: "@/constants/MarkdownFiles/authors/shubham-singh.md" -tags: - - gsoc25 - - sugarlabs - - week05 - - firepheonix -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 5 Progress Report by Shubham Singh - -**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) -**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-07-01 – 2025-07-07 - ---- - -## Goals for This Week - -- Fix some more issues in the scanning that are visible to me. -- Implementing the dynamic input of NOTES like in the phrase maker. - ---- - -## This Week's Achievements - -1. **Implemented dynamic input of Notes like in phrase maker.** - - So the very good thing about music blocks is, if you want to implement something, it's most LIKELY already there. Haha. So I scanned through the entire code of phrase maker's code and found out the code responsible for what type of input is taking place. Since I already extended the class LegoBricksBlock with StackClampBlock class, the input already worked, but for print block, since I used it as a dummy for future. - - Well turns out everything fell right into place and I figured out NOT only just the input, but the output of how phrase maker took place and I implemented it on to my own LegoBrick.js . I now completely understand how the output is working out. -  - - <iframe width="800" height="405" src="https://www.youtube.com/embed/ObNYq29QHZw?si=uoYPchoQUhbEnmY4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> - - -2. **Implemented the complete phrase maker pitch functionality by adding PitchBlocks.js.** - - I figured out how to configure the notes, yet struggled with hardcoded value on the octave, which is by default, 4. - - So I had to literally, manually go over the entire pitch-blocks.js and a few files. After making adjustments inside some of those files, I was finally able to get the octave as well. - -  - - <iframe width="800" height="405" src="https://www.youtube.com/embed/XpgFTjimPyc?si=fi9HxuN5o8BOP26J" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> - -3. **Finally - Testing out Devin's CMK'24 project.** - - I finally did what I've always wanted. It was Devin's experiments that inspired me to take up this ,project in core Javascript for music blocks. So, here's a quick summary, haha: - - - Devin led a project called “Lego Musical Notation for the Blind” during the CMK workshop, aiming to create a tactile music system using Lego bricks for visually impaired users. Working with Jamie Chelel from MIT’s K12 Maker Lab, they built a prototype where pitch was mapped vertically and time horizontally on a Lego baseplate. Different brick lengths represented note durations, and a special marker block acted like a clef to guide pitch reference. - -  - - - After building the basic physical model, Devin shifted focus toward digitizing the system. Devin, created a functional prototype of this scanning system, he encountered challenges when trying to assign precise, meaningful pitches within Scratch’s limitations. - - <iframe title="vimeo-player" src="https://player.vimeo.com/video/983707992?h=0b765ba25a" width="800" height="405" frameborder="0" allowfullscreen></iframe> - - - Now, as you can read in my previous, week04 blog, I was able to completely overcome the Technical Hurdle of not being able to detect colors with a very high accuracy from static images. - - - And, finally here's how the scanning result looks like. - -  - -  - - - I realize that the output is coming ONE ROW down. also, the print functionality, it's automatically adjusting the rows ONE down. Still left with some adjustments to make something to show across all the blocks. - - - This still won't cut it. It has to be more accurate than this. I'll continue to optimize further, but I'll move on to the next phase, which is music generation from next week. - -  - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Reading through multiple files - **Solution:** No solution, just did the old-fashioned, long way. Also read some documentation -- **Challenge:** Have a lot of college related in the upcoming week. - **Solution:** Woke up 2-3 sleepless nights to get more time?? Yeah that's what I did. - ---- - -## Key Learnings - -- If you're building something, for example, a full-stack frontend backend website, you shouldn't vibe code it with AI and THEN run into errors. Create a basic frontend -> Send post requests with some tool -> Then connect the backend. . And this applied here as well since I put the NOTES as input functionality first THEN the pitch. Build in steps. Plan it out better. Even better, use some LLM to plan it out for you step by step. -- I tried learning a LOT of stuff this week. I'm learning how CORE JAVASCRIPT in itself works and it's an amazing opportunity. I never knew any of the browser storage concepts, or for that matter, time complexity practical use case before hand. I'm just learning so in-depth. It's crazy good. - ---- - -## Next Week's Roadmap - -- Now we are getting on the main part, which is producing musical sounds with the printed output. I still have to figure out a way ALONG with that I also have my college related work I've got to do. -- Figuring out the when does music production START. This was mentioned by my mentor, Walter, that the music should start playing the moment the algorithm bumps into the FIRST color change from green. That's a START point. - ---- - -## Resources & References - -- **Nothing much, just Music Blocks documentation sufficed** - ---- - -## Acknowledgments - -Thank you to my mentors [Walter Bender](https://github.com/walterbender) and [Devin Ulibarri](https://github.com/pikurasa) for invaluable guidance throughout this development phase. I like how Devin actually reads everyone's blogs every single week. He's an inspiring person. -PS: If you're reading this blog Devin, I hope you're enjoying the details. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-Nikhil-Bhatt-week05.md b/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-Nikhil-Bhatt-week05.md deleted file mode 100644 index 2b1bea6c..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-Nikhil-Bhatt-week05.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "GSoC '25 Week 05 Update by Nikhil Bhatt" -excerpt: "Implemented historical forking using Git CLI to preserve commit history and securely update metadata for downstream workflows." -category: "DEVELOPER NEWS" -date: "2025-07-06" -slug: "2025-07-06-gsoc-25-nikhilbhatt-week05" -author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" -tags: "gsoc25,sugarlabs,week05,nikhilbhatt" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 05 Progress Report by Nikhil Bhatt - -**Project:** [Git backend for MusicBlocks](https://github.com/benikk/musicblocks-backend) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Reporting Period:** 2025-06-29 – 2025-07-06 - ---- - -## Goals for This Week - -- Investigate and solve the issue of missing commit history in forked repositories. -- Switch from GitHub API–based file copying to full repo cloning with Git CLI. -- Ensure `metaData.json` updates include a new hashed key and get committed to the fork. -- Maintain clean repo history and secure edit permissions for each forked project. - ---- - -## This Week's Achievements - -### Switched to `forkWithHistory` via Git CLI - -Previously, when users forked a project, only the latest files (`projectData.json` and `metaData.json`) were copied into a new repository via GitHub's REST API. This approach **did not preserve commit history**, making it impossible to trace past changes. - -To fix this: - -- I implemented a new backend function `forkWithHistory()` using `git clone`, `git remote`, and `git push` with a Personal Access Token (PAT). -- This ensured that **full commit history is retained** in forked repositories. -- Each fork gets its own hashed key securely stored in the updated `metaData.json`. - -- Commits now reflect actual history -- Forks maintain lineage via `forkedFrom` metadata -- All content and hashes are committed and pushed as part of the first commit - ---- - -### 🔐 MetaData Commit Confirmation - -- I ensured that after updating the hash and `forkedFrom` link, the file is committed and pushed using Git CLI commands (`git add`, `git commit`, `git push`). -- The Git identity is explicitly set for the commit using: - ---- - -## Challenges & How I Solved Them - -- **Challenge:** Missing commit history in GitHub API forks - **Solution:** Switched to using Git CLI and a service account PAT to clone and push the entire repository. - -- **Challenge:** Rate Limits with PATs - **Solution:** We're currently using a single org service account PAT. The rate limits (5,000 requests/hour) are more than enough for current needs, but we may consider switching to app-based or scoped PATs if traffic scales up. - ---- - -## Key Learnings - -- Learned how to automate git commands securely in Node.js (using child_process.execSync). -- Understood the limitations of GitHub’s REST API for repo-level history and collaboration. - ---- - -## Next Week's Roadmap - -- Discuss and analyse possible downsides of the current approach, ensuring good fallbacks -- Create a commit history feature students can see how their project evolved with time - -## Resources & References - -- [MusicBlocks Frontend Repo](https://github.com/sugarlabs/musicblocks) -- [musicblocks-backend](https://github.com/benikk/musicblocks-backend) -- [Octokit REST.js Library](https://github.com/octokit/rest.js) - ---- - -## Acknowledgments - -Thanks again to my mentors and the Sugar Labs community for feedback and support! -Looking forward to next week’s frontend PR features. diff --git a/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-SafwanSayeed-week05.md b/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-SafwanSayeed-week05.md deleted file mode 100644 index defc207a..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-SafwanSayeed-week05.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: "GSoC '25 Week 5 Update by Safwan Sayeed" -excerpt: "Implementing the Symbol Table and Memory Module Integration" -category: "DEVELOPER NEWS" -date: "2025-07-06" -slug: "2025-07-06-gsoc-25-sa-fw-an-week5" -author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" -tags: "gsoc25,sugarlabs,week5,sa-fw-an" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 5 Progress Report by Safwan Sayeed - -**Project:** Music Blocks 4 Program Engine -**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-06-30 - 2025-07-06 - ---- - -## A Blog-style Retrospective - -This week I implemented the Symbol Table and integrated it with the Memory Module to manage variable scopes and dependencies effectively. This was a crucial step in preparing for the Abstract Syntax Tree (AST)-to-Intermediate Representation (IR) compilation logic, ensuring that our program engine can handle variable resolution correctly during the translation process. - ---- - -## Goals for This Week - -- Design the Symbol Table. -- Implement the Symbol Table in the Memory Module. ---- - -## This Week's Highlights - -1. **Symbol Table Design and Implementation** - - Designed the Symbol Table to manage variable scopes and dependencies effectively. - - Integrated the Symbol Table with the Memory Module to ensure proper variable resolution during AST-to-IR translation. - - Documented the design and usage patterns for future reference. - ---- - -## Challenges & Solutions - -- **Managing Variable Scopes:** - Initially faced challenges in ensuring that variable scopes were correctly maintained across different blocks of code. - *Solution:* Implemented a robust Symbol Table that tracks variable declarations and their scopes, allowing for accurate resolution during the AST-to-IR translation. - - ---- - -## Key Learnings - -- Gained a deeper understanding of how to manage variable scopes and dependencies in a compiler context. -- Learned how to design and implement a Symbol Table that integrates with the Memory Module to facilitate variable resolution during the AST-to-IR translation process. - ---- - -## Next Week's Roadmap - -- Start working on the execution engine that will interpret the generated IR instructions. -- Begin implementing the first set of IR instructions. ---- - -## Resources & References - -- **Repository:** [musicblocks-v4](https://github.com/sugarlabs/musicblocks-v4) - ---- - -## Acknowledgments - -Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their crucial guidance on compiler design principles and static compilation concepts. Their clarification on the AST-to-IR translation approach and emphasis on maintaining clean instruction generation patterns was essential for this week's successful progress. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-diwangshu-week05.md b/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-diwangshu-week05.md deleted file mode 100644 index 35adfca8..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-diwangshu-week05.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "GSoC ’25 Week 05 Update by Diwangshu Kakoty" -excerpt: "Reflection Learning Widget in Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-07-06" -slug: "2025-07-06-gsoc-25-diwangshu-week05" -author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" -tags: "gsoc25,sugarlabs,week05,AI" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 05 Progress Report by Diwangshu Kakoty - -**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) -**Reporting Period:** 2025-06-29 - 2025-07-05 - ---- - -## Goals for This Week - -- **Goal 1:** Develop a 'reflection' widget in Music Blocks. -- **Goal 2:** Update Fast API server code. -- **Goal 3:** Fix bugs occured by these changes. - ---- - -## This Week’s Achievements - -1. **Develop a 'reflection' widget in Music Blocks** - - For this week, I have finally got the green light to work on the frontend of the project. I have started developing a 'reflection' widget in Music Blocks and it is almost comleted. It can be found in the Widget section. - - - The conversation history is stored in the client side. For every query, the widget sends a request to the FastAPI server with payloads like `query`, `messages` and `mentor`. The server then processes the request and returns a response. The response is then displayed in the widget. - - <a href="https://ibb.co/NdLhh6DX"><img src="https://i.ibb.co/21j227Vw/first-Reflection.jpg" alt="first-Reflection" border="0"></a> - -2. **Update Fast API server code** - - As mentioned in my first week's report that I made the Fast API endpoints `/chat` and `/summary`, I have now updated the code to handle the new 'reflection' widget. - - - The `/chat` endpoint now expects a payload with `query`, `messages`, and `mentor`. - - - The messages include only the conversation history between the user and the AI, excluding the system message. This is because each mentor has a unique system message, which is dynamically set by the server based on the mentor field in the payload. So, we can say that the client-side is not storing any kind of prompts or system message. - ---- - -## Challenges & How I Overcame Them - -- **Challenge 01:** I found difficulties in integrating the 'reflection' widget with the FastAPI server. The widget was not handling the response correctly. - - **Solution:** Although I was familiar with async/await and promises in JavaScript, I lacked sufficient hands-on experience. To ensure the widget properly awaited the server response before updating the UI, I revisited these concepts. I also implemented error handling to address any potential issues during API calls. - -- **Challenge 02:** The widget was not initializing the messages after re-opening it. - - **Solution:** This was a simple bug where I forgot to initialize the messages array in the widget's state. I fixed it by ensuring that the messages array is initialized when the widget is opened. ---- - -## Key Learnings - -- I gained hands-on experience with integrating a frontend widget with a backend server using FastAPI. -- I learned how to handle asynchronous operations in JavaScript, which is crucial for building responsive web applications. -- I improved my understanding of how to structure API requests and responses for a better user experience. - ---- - -## Next Week’s Roadmap - -- From the last meeting with my mentors, I have learned that saving a reflection session is very necessary. It will allow users to revisit their reflections later and also helps a lot in testing. Therefore, I will be implementing saving and loading reflection sessions in the Streamlit app. Infact, I have already made a download button that downloads a JSON file containing the conversation history. - -- I was also informed that the AI is asking too many follow-up questions, which is not ideal. I will be working on refining the prompts to reduce unnecessary follow-ups and give it a more natural conversation flow. - -- Implement other features like 'generate summary' and 'generate analysis' in the widget. - -- Store the conversation summaries in user's browser using localStorage, so that the user can revisit their reflections later. This will also help in testing the 'analysis' phase of the reflection learning cycle. - ---- - -## Resources & References - -- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) -- **Streamlit App:** [Reflection App](https://reflectionapp-2yoxtvn6sknvktme2zorvq.streamlit.app/) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-omsuneri-week05.md b/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-omsuneri-week05.md deleted file mode 100644 index 309f4a58..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-06-gsoc-25-omsuneri-week05.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: "GSoC’25 Week 05 Update by Om Santosh Suneri" -excerpt: "AI-powered Debugger for Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-07-06" -slug: "2025-07-06-gsoc-25-omsuneri-week05" -author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" -tags: "gsoc25,sugarlabs,week05,Debugger,AI,Music Blocks" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 05 Progress Report by Om Santosh Suneri - -**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) -**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) -**Reporting Period:** 2025-06-29 - 2025-07-05 - ---- - -## Goal for This Week - -**Migrating Music Blocks JSON-to-Text Converter to Streamlit App** - ---- - -## This Week’s Achievements - -### Introduction - -This week, I focused on one of the key deliverables of the project — **integrating the JSON-to-Text Representation Converter into a Streamlit application**. This marks a major step in our plan to create a seamless debugging experience for Music Blocks users. The converter, which was originally built using JavaScript, is now fully functional in Python via Streamlit and ready for integration with the AI-powered debugger. - -### What I Did - -#### Goal - -The previous tool was a **client-side JavaScript converter** that parsed JSON representations of Music Blocks projects and produced a structured, readable **tree-view text format**. The aim this week was to **translate this logic into Python** and build a **Streamlit interface** to make the tool backend-friendly and easily integrable with the AI Debugger app. - -#### Migration from JavaScript to Python - -Converting the JavaScript-based logic to Python wasn’t a simple one-to-one translation. It involved rethinking data structures, managing recursion differently, and carefully ensuring that **each Music Blocks "block" type was accurately represented** in the output. - -Key technical components of the migration included: - -* **Parsing the block structure**: - - * Each block in the JSON is structured like `[block_id, block_type, ..., connections]` - * The Python version uses dictionaries (`block_map`) and recursion to follow nested or sequential connections (`clamp` and `stack` logic). - -* **Handling specific block types**: - - * Each block type (like `start`, `setmasterbpm2`, `newnote`, `repeat`, etc.) has a distinct logic for representation. - * For example, the `setmasterbpm2` block may include a divider block to represent beat values (like `4/4 = 1.00`), which must be parsed recursively. - -* **Redacting base64-encoded content**: - - * Just like in the JS version, the Python converter checks for base64 strings (e.g., audio/image data) and replaces them with `"data"` to keep the output clean and safe. - -* **Maintaining tree formatting**: - - * I replicated the `├──` and `│` styled tree structure for visual clarity. - * Indentation is handled dynamically based on the depth of recursion. - -#### Enhancements Added - -While rewriting, I also took the opportunity to **extend the support to more block types** that weren’t handled earlier — for example: - -* `arc` -* `incrementOne` -* `pitch` -* `text` -* `settransposition` - -This ensures that even **newer or more complex Music Blocks projects** are parsed correctly and comprehensively. - -#### The Streamlit App - -Once the backend logic was ready, I integrated it with a user-friendly Streamlit interface. The app consists of: - -* A **text area** for JSON input. -* A **convert button** to trigger the parsing. -* A cleanly formatted **output section** with scrollable, monospaced text. -* Error handling for invalid or empty JSON. - ---- - -### Why It Matters - -Music Blocks is used in educational environments. One of the biggest challenges new users face is **understanding how blocks connect and function** under the hood. By converting the visual block code into a readable text format, this tool: - -* Makes debugging more accessible for students. -* Helps educators explain project logic in class. -* Provides an exportable, printable format of block logic. - -#### Foundational Component for the Debugger - -This converter will play a **crucial role** in the **AI-powered Music Blocks Debugger**. By giving a structured, simplified text representation of the project: - -* The LLM (Large Language Model) will better understand the project logic. -* It enables **embedding**, **chunk retrieval**, and **semantic search** for debugging. -* Users will be able to see both their visual project and a clean text summary on the same platform. - -#### Seamless Integration Ahead - -Now that the converter is in Streamlit (and Python), integrating it into the AI Debugger system becomes straightforward: - -* No need to mix JavaScript and Python — the backend stays unified. -* Users can input JSON and debug in the **same interface**. -* It aligns with the vector database and LLM pipeline we’re building. - -### 📸 Preview - -Here’s a quick preview of the app: - -<a href=""><img src="https://i.ibb.co/XZt6MF9k/Screenshot-2025-07-05-at-3-09-15-PM.png" alt="Convertor Streamlit interface"></a> - - -### Final Thoughts - -Rewriting an entire logic-heavy JavaScript app into Python was both challenging and rewarding. It made me deeply understand how each block works in Music Blocks and how a simple but well-structured parser can bring clarity to even the most complex visual projects. - ---- - -## Next Week’s Roadmap - -* Integrate the Streamlit-based converter directly into the AI Debugger interface. -* Improve the understanding of actions in the project by enhancing the LLM prompts. - -## Resources & References - -- **Repository:** [JSON to Text representation](https://github.com/omsuneri/JSON-to-Text-representation) -- **Repository:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) -- **Debugger Streamlit App:** [Music Blocks Debugger](https://debuggmb.streamlit.app/) -- **Directory for Projects:** [Embedding Project Set](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks/tree/main/data/docs) - - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-06-ssoc-2025-MuhammadHaroon-week05.md b/src/constants/MarkdownFiles/posts/2025-07-06-ssoc-2025-MuhammadHaroon-week05.md deleted file mode 100644 index 5f565ac2..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-06-ssoc-2025-MuhammadHaroon-week05.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "SSoC ’25 Week 05 Update by Muhammad Haroon" -excerpt: "Generated additional samples using various prompts, which were then evaluated by mentors." -category: "DEVELOPER NEWS" -date: "2025-07-06" -slug: "2025-07-06-ssoc-25-MuhammadHaroon-week05" -author: "@/constants/MarkdownFiles/authors/muhammad-haroon.md" -tags: "ssoc25,sugarlabs,week05,GenAI,MusicBlocks,Music" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 05 Progress Report by Muhammad Haroon - -**Project:** [Generative AI Instrument Sample Generation for Music Blocks](https://github.com/sugarlabs/GSoC/blob/master/Ideas-2025.md#Generative-AI-Instrument-Sample-Generation-for-Music-Blocks) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-30 - 2025-07-06 - ---- - -## Goals for This Week - -- **Goal 1:** Generated more samples using various prompts, which were then evaluated by mentors. -- **Goal 2:** Explored FastAPI and AWS. - ---- - -## This Week's Achievements - -1. **Generated more samples using various prompts** - - I generated more samples using [various prompts](https://docs.google.com/spreadsheets/d/1lxMHoiE-4YB5oDYlXfSP9TK5iXWkGYWC33ll8weJIO8/edit?usp=sharing). These samples were stored in [Google Drive](https://drive.google.com/drive/folders/1jee1MAmsyNddbh-pTIOX9K6Wctbd6Cf9?usp=drive_link) and shared with the mentors. The mentors scored the sounds using the following Google Sheets: [Walter's Score](https://docs.google.com/spreadsheets/d/1gzh7w2o8TeUUaePqOSlN2bt1T7fofFeRNoGzxq97PPM/edit?usp=sharing) and [Devin's Score](https://docs.google.com/spreadsheets/d/1ozwnBbXLQKZY_EQ-p7I4y0PRtzkqUauYOwstVnvjxFU/edit?usp=sharing). The scores that could be assigned were: bad (1), fair (2), and good (3). Both Devin and Walter gave an average score of 1.485, indicating that the overall output quality was closer to bad than fair. After reviewing the score, it became evident that a new model was needed. - -2. **Explored FastAPI and AWS** - - I explored FastAPI for connecting the backend with the frontend and AWS for deploying our backend. - ---- - -## Next Week's Roadmap - -- Find another open-source model to generate high quality sound samples. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-07-dmp-25-justin212407-week05.md b/src/constants/MarkdownFiles/posts/2025-07-07-dmp-25-justin212407-week05.md deleted file mode 100644 index f9f04a5b..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-07-dmp-25-justin212407-week05.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "DMP’25 Week 05 Update by Justin Charles" -excerpt: "Setup a visual playground with drag-and-drop brick placement from a palette UI" -category: "DEVELOPER NEWS" -date: "2025-07-06" -slug: "2025-07-06-dmp-25-justin212407-week05" -author: "@/constants/MarkdownFiles/authors/justin-charles.md" -tags: "dmp25,sugarlabs,week5,justin212407" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 5 Progress Report by Justin Charles - -**Project:** Music Blocks 4 Masonry -**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-06-29 - 2025-07-06 - ---- - -## Goals for This Week - -- Set up the core **Playground UI** to serve as the editable workspace -- Build a **Palette** with available brick types and integrate it visually into the Playground -- Enable **drag-and-drop interactions** from the palette into the workspace - ---- - -## This Week’s Highlights - -### 1. **Playground Workspace Setup** - -Created a dedicated layout component for the brick workspace: -- Positioned using CSS grid to support side-by-side palette and canvas -- Styled with scrollable overflow to allow panning and scaling in future updates -- Prepares the base for rendering brick instances using spatial coordinates - - -### 2. **Brick Palette UI** - -Added Palette UI to playground: -- Lists all brick types with color-coded icons and labels -- Styled for compact visibility, allowing quick scanning of available bricks -- Each brick is draggable and includes metadata for `type`, `defaultProps`, and visual ID - -🎨 Gives users clear visual feedback about available building blocks before use - -### 3. **Drag-and-Drop from Palette to Playground** - -Implemented full drag-and-drop pipeline: -- **OnDragStart**: Attaches metadata (`type`, `defaultProps`) to the drag event -- **OnDrop**: Computes drop position relative to workspace container -- **Dispatch**: Triggers creation of a new brick model at the drop location via Recoil - -Supports extensibility for: -- UUID generation -- Position snapping -- Drag preview overlays - ---- - -## Challenges & Solutions - -**Challenge:** Drop positioning was inaccurate due to nested containers and scroll -**Solution:** Used `getBoundingClientRect()` to normalize the offset and compute absolute drop coordinates - -**Challenge:** Drag behavior caused unwanted rerenders across unrelated components -**Solution:** Memoized drag metadata using `useRef` and lifted shared handlers to a centralized manager - ---- - -## Key Learnings - -- **Component Composition** - Learned how to break large UI logic into isolated playground, palette, and renderer components for clarity - -- **Event Normalization** - Understood how native drag events behave in nested layouts and how to calculate relative drop points robustly - -- **State Orchestration** - Tied together UI state (hover/drag) and business state (brick model updates) using Recoil and internal `BrickFactory` functions - ---- - -## Next Week’s Roadmap - -- Implement dragging of bricks in the playground. -- Implement Collision Maps for colliding objects. -- Create a reverse mapping utility file to fetch all connection points. ---- - -## Resources & References - -- [musicblocks-v4 Repository](https://github.com/sugarlabs/musicblocks-v4) -- [MDN Drag and Drop Guide](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) -- [RecoilJS Docs](https://recoiljs.org/) - ---- - -## Acknowledgments - -Thanks to the my mentor Anindya Kundu team for helping me align on visual structure of palette. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-07-dmp-25-therealharshit-week05.md b/src/constants/MarkdownFiles/posts/2025-07-07-dmp-25-therealharshit-week05.md deleted file mode 100644 index 30e947cd..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-07-dmp-25-therealharshit-week05.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: "DMP ’25 Week 05 Update by Harshit Verma" -excerpt: "This week, I built a custom Markdown parser for VTE (Virtual Terminal Emulator), began evaluating model performance, and discussed age appropriate debugging practices with mentors." -category: "DEVELOPER NEWS" -date: "2025-07-07" -slug: "2025-07-07-dmp-25-therealharshit-week05" -author: "@/constants/MarkdownFiles/authors/harshit-verma.md" -tags: "dmp25,sugarlabs,week05,therealharshit" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 05 Progress Report by Harshit Verma - -**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-30 - 2025-07-06 - ---- - -## Goals for This Week - -- **Goal 1:** Develop a custom Markdown parser for VTE (Virtual Terminal Emulator). -- **Goal 2:** Begin model selection and optimization. -- **Goal 3:** Discuss best debugging practices for children. - ---- - -## This Week’s Achievements - -1. **Built a Lightweight Markdown Parser for VTE** - - Created a simple parser to interpret basic Markdown (like `**bold**`, `- bullets`, `### headers`) and display it using ANSI-style formatting in the VTE terminal. - - Iterated by testing different wording styles and instruction formats, which led to noticeably better visual output. -  - -2. **Started Model Evaluation and Optimization** - - Compared several models (like Mistral, CodeLlama, and others from Hugging Face) to balance output quality with local performance. - - The response was good but it was taking a lot of time to generate the response. - -3. **Had a Discussion on Debugging Practices for Children** - - Talked with mentors about how to present debugging in a way that encourages curiosity rather than frustration. - - Key ideas included: focusing on helpful language, start with contextualization, and offering clear, step-by-step suggestions. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Parsing Markdown in a VTE terminal widget. - **Solution:** Since VTE doesn't support rich text natively, I built a custom parser to translate basic Markdown into stylized terminal output using spacing, symbols, and ANSI codes. - -- **Challenge:** Running the model locally on CPU. - **Solution:** Faced performance limitations due to lack of GPU support. To address this, I explored the option of offloading model inference to AWS. - ---- - -## Key Learnings - -- Gained experience in building a custom parser, handling string pattern detection and safe rendering within VTE. -- Practiced simplifying technical content for young learners, focusing on clarity over complexity. - ---- - -## Next Week’s Roadmap - -- Work on setting CSS for Debugging terminal, to style it. -- Finalize model selection and prepare integration with Sugar-AI. -- Start working on saving debug history to Sugar Journal. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-08-gsoc-25-AdityaKrSingh26-week08.md b/src/constants/MarkdownFiles/posts/2025-07-08-gsoc-25-AdityaKrSingh26-week08.md deleted file mode 100644 index 89827b6d..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-08-gsoc-25-AdityaKrSingh26-week08.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: "GSoC ’25 Week 08 Update by Aditya Kumar Singh" -excerpt: "Resolved key issues in shared Paint & Tour workflows, introduced a real-time XO-icon leaderboard in Doctor mode, and bootstrapped the Stickman activity scaffold." -category: "DEVELOPER NEWS" -date: "2025-07-09" -slug: "2025-07-08-gsoc-25-AdityaKrSingh26-week08" -author: "@/constants/MarkdownFiles/authors/aditya-singh.md" -tags: "gsoc25,sugarlabs,week08,AdityaKrSingh26" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 07 Progress Report by Aditya Kumar Singh - -**Project:** [Sugarizer](https://github.com/llaske/sugarizer) -**Mentors:** [Lionel Laské](https://github.com/llaske) -**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) -**Reporting Period:** 2025-07-03 – 2025-07-09 - ---- - -## Goals for This Week - -- **Goal 1:** Bug-hunt Shared Paint & Tour PR (Restore zoom-out capability when a session starts at a custom FOV, Guarantee that newcomers instantly receive every painted mesh, Ensure the palette reflects the host-selected mode (Paint / Tour / Doctor) on join.) -- **Goal 2:** Finish Doctor refactor – replace the legacy username-only leaderboard with XO icons tinted to each participant’s Sugar colour. -- **Goal 3:** Kick-off Stickman Activity – create a blank shell with full toolbar assets ready for upcoming features. - - ---- - -## This Week’s Achievements - -1. **Fixed Zoom-Out Limitation** - - **Issue:** When the Human Body activity was opened with a custom zoom level, users were unable to zoom out due to improper FOV (Field of View) limits. - - **Fix:** - - Implemented clamped zoom logic by calculating and bounding the `camera.fov` value between 5° and 75°. - - Both scroll wheel and toolbar zoom now honor the same constraints. - - This method ensures that camera zoom respects a realistic viewing range, preventing the camera from getting stuck in an unusable state. - ```javascript - function getFov(zoom) { - return Math.min(Math.max(zoom, 5), 75); // clamp zoom to valid FOV range - } -2. **Shared Paint Mode – Late Joiner Synchronization** - - **Issue:** When a new user joined an already shared Paint session, the previously painted parts weren’t visible to them. - - **Fix:** - - The host maintains a complete list of painted parts and their corresponding color mappings in paintedPartsList. - - When a new user joins, the host invokes: `sendFullPaintDataToNewUser(presenceId)` - - This sends all `meshName → hexColor` mappings via the `syncAllPaintData` action. - - Peers then replay this data and apply consistent material colors to each 3D mesh - - This method ensures that camera zoom respects a realistic viewing range, preventing the camera from getting stuck in an unusable state. - - -3. **Mode Palette Sync Across Clients** - - **Issue:** The palette mode (Paint, Tour, Doctor) would sometimes display inconsistently across users in a shared session. - - **Fix:** - - Centralized mode state and now rebroadcast on every mode change. - - When any user joins, their client listens to `syncCurrentMode` and updates icons accordingly: - - **Effect:** UI remains consistent regardless of when users join or switch modes. - - -4. **Redesigned Doctor Mode Leaderboard with XO Icons** - - **Objective:** Replace the old leaderboard (just usernames and scores) with a Sugar-style UI using XO icons and user colors. - - **Implementation Highlights:** - - `generateXOLogoWithColor(userColor)`: A dynamic SVG generator that outputs an XO icon with the user’s stroke and fill colors, derived from Sugar presence data. - - `showLeaderboard()`: Constructs a ranked visual layout showing each user’s XO icon, name, and score—updated in real time with every correct answer. - - **Algorithm Steps:** - - Maintain a scoreBoard object mapping presenceId → {score, userInfo}. - - Upon a correct answer: - - Host sends a `scoreUpdate` broadcast. - - All peers update their UI leaderboard. - - Leaderboard HTML is re-rendered using updated user data and SVG icons. -  - - -3. **Stickman Activity – Initial Scaffold** - - Created an initial version of the activity. - - Toolbar now displays all expected icons (draw, move, add frame, delete frame, play, stop). - - Currently, button clicks do nothing—but the structure is laid out to integrate drawing and animation logic next week. -  - - - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Simultaneous paint broadcasts leading to race conditions. - **Solution:** Ensured all paints are stored only on host, then synced post-join via a single action. - -- **Challenge:** Dynamic XO SVGs without image files. - **Solution:** Used inline SVG with JS string templates to create colored icons on-the-fly. - - ---- - -## Key Learnings - -- Gained in-depth understanding of Three.js camera manipulation and persistence. -- Built a robust synchronization pattern using presence broadcasts and authoritative state snapshots. -- Practiced UI/UX consistency across Sugarizer activities with reusable SVG elements and Sugar-specific color schemes. - ---- - -## Next Week’s Roadmap - -- Write Weekly Blog Post summarizing progress, screenshots, and key learnings. -- Fix Remaining Issues in Human Body Activity -- Stickman Dashboard – Draw & Move -- Stickman Frame Management - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-12-dmp-25-AmanNaik-week06.md b/src/constants/MarkdownFiles/posts/2025-07-12-dmp-25-AmanNaik-week06.md deleted file mode 100644 index 4ee1f733..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-12-dmp-25-AmanNaik-week06.md +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: "DMP ’25 Week 6 Update by Aman Naik" -excerpt: "This week involved integrating the LLM's story framework into the UI, user testing with school children, and successfully resolving AWS deployment issues." -category: "DEVELOPER NEWS" -date: "2025-07-12" -slug: "2025-07-12-dmp-25-AmanNaik-week06" -author: "@/constants/MarkdownFiles/authors/amannaik247.md" -tags: "dmp25,writeactivity,write,sugarlabs,week06,midterm,amannaik247" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 6 Progress Report by Aman Naik - -**Project:** [Add an AI-assistant to the Write Activity](https://github.com/sugarlabs/write-activity/issues/52) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky) -**Reporting Period:** 2025-07-06 – 2025-07-12 - ---- - -## Goals for This Week - -- Build a user interface for the generated story framework -- Integrate LLM-generated responses into the UI -- Get feedback from real students using the demo application -- Deploy an LLM model on AWS - ---- - -## This Week’s Achievements - -1. **Built the Story Framework UI** - - Designed and implemented the story framework display using GTK and GTK CSS. - - The UI now dynamically displays the story structure based on the JSON response received from the LLM. - - The framework was successfully demonstrated to mentors, who gave positive feedback on the overall integration and experience. - -2. **Integrated LLM Response Into the UI** - - Parsed the JSON response from the LLM and displayed each story element in dedicated sections within the app. - - Incorporated error handling for missing or blank story categories. - -  - -3. **Gathered Real-User Feedback Through a School Demo** - - Mentor [Devin Ulibarri](https://github.com/pikurasa) organized a hands-on testing session with 12 students across four different activity stations: - - LLM-Speak - - Story Builder - - Personas - - Students reflected on their experience via handouts. I’ll be analyzing their feedback to better understand their thoughts and identify areas of improvement. - -  - -4. **Resolved AWS Permissions Issue** - - Successfully resolved the permission issue that previously blocked AWS access. - - Now have access to SageMaker and am prepared to deploy the LLM model as planned in the upcoming week. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Handling incomplete or empty story categories in LLM responses - **Solution:** Added placeholders in the UI for missing categories. These placeholders guide the student with helpful questions (e.g., "What could be the turning point in your story?") to encourage further development. Future updates will include buttons for AI-generated suggestions. - -- **Challenge:** Gaining access to deploy on AWS - **Solution:** Through clear and timely communication with mentors, I was able to get the necessary permissions and understand more about how access control and user roles work in AWS. - ---- - -## Key Learnings - -**Learned How to Build and Parse Adaptive Story Frameworks in UI** - - Learned how to dynamically map LLM outputs into GTK UI components and ensure the experience remains useful even when some inputs are missing. - - Code of try and except block parsing the response given by the LLM to update story info: - - ```python - try: - start_idx = analysis.find('{') - end_idx = analysis.rfind('}') + 1 - if start_idx != -1 and end_idx != -1: - json_str = analysis[start_idx:end_idx] - story_data = json.loads(json_str) - return story_data - except Exception: - pass - # Return default structure if parsing fails - return { - "title": "", - "setting": "", - "character_main": "", - "character_side": "", - "goal": "", - "conflict": "", - "climax": "", - "helpers": "", - "villains": "", - "ending": "", - "theme": "" - } - ``` - -**Valuable Experience from Real User Testing** - - Understood how students react to the tool, what excites them, and what confuses them — essential insights to shape the next phase of development. - -**Improved My Understanding of AWS Deployment Workflows** - - Resolved previous blockers and now have a clearer picture of how cloud model hosting works and how access can be securely managed. - ---- - -## Next Week’s Roadmap - -- Finalize the deployment of the selected LLM model using AWS SageMaker -- Make the sidebar panel collapsable so it can be accessed when needed -- Understand feedback of the UI based on student and mentor feedback - ---- - -## References - -_Quote from Devin Ulibarri (Mentor):_ -> "Since these are experimental, I was mildly concerned that a student might find something inappropriate, but nothing of the sort happened. One student made a story about a "Blob of Poop", but it wasn't too bad." - -This has prompted me to think about on how to make LLM responses more child-friednly and create strict restrictions for inappropriate content. - ---- - -## Midterm Progress Summary - -Over the past six weeks, I’ve made significant progress toward building an AI-powered assistant for the Write Activity: - -- **Week 1–2:** Explored different approaches to creative writing and finalized a guided AI-assisted architecture for story building. -- **Week 3:** Built a working demo using Streamlit and received initial mentor feedback. -- **Week 4:** Began integrating the demo into the Sugar Activity and created the first UI prototype with a sidebar chatbot. -- **Week 5:** Designed a widget to display the story framework and attempted to deploy the LLM model on AWS (later resolved). -- **Week 6:** Fully integrated LLM JSON responses into the app's UI, tested the tool(using the demo application) with 12 students, and gathered real-world feedback. Also successfully resolved the AWS access issue for upcoming deployment. - -These weeks have been packed with learning—from UI design for young learners to API integration, cloud model deployment, and real-user testing. With foundational blocks in place, I’m now ready to polish the experience and begin iterative improvements with real feedback in mind. - ---- - -## Acknowledgments - -A huge thank you to my mentors, especially Devin Ulibarri for arranging the user testing session. I’m also grateful to Walter, Ibiam, and the Sugar Labs community for their continued support and constructive feedback every week. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-12-gsoc-25-Elwin-Li-week06.md b/src/constants/MarkdownFiles/posts/2025-07-12-gsoc-25-Elwin-Li-week06.md deleted file mode 100644 index c104cd4f..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-12-gsoc-25-Elwin-Li-week06.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: "GSoC '25 Week 6 Update by Elwin Li" -excerpt: "Weekly progress report for JSEditor updates" -category: "DEVELOPER NEWS" -date: "2025-07-12" -slug: "2025-07-12-gsoc-25-Elwin-Li-week06" -author: "@/constants/MarkdownFiles/authors/elwin-li.md" -tags: "gsoc25,sugarlabs,midterm,week6,javaScript editor,debugger,syntax highlighting" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 6 Progress Report by Elwin Li - -**Project:** [Advanced JavaScript Editor with MusicBlocks Interactions](https://github.com/sugarlabs/musicblocks/tree/config_driven_conversion/elwin) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) - -**Reporting Period:** 2025-07-05 - 2025-07-12 - ---- - -## Goals for This Week - -- **Goal:** Complete syntax/error highlighting, and conclude the project - ---- - -## This Week’s Achievements - -**Made PR for Syntax highlighting project** - -The syntax/error highlighting project has been complete and a [PR has been made](https://github.com/sugarlabs/musicblocks/pull/4723). This project adds syntax highlighting and error highlighting to the JS editor, making the editor easier to work with. The syntax highlighting was done using -the highlightjs library, and the error highlighting was done by using the acorn library to parse the JavaScript code, and marking down the location -of any errors, and doing some calculations to highlight the associating places red. - -Any syntax errors will not only cause the place of errors to be highlighted, but it will also print an error message in the console log. This will additionally make it easier for the user to understand when and where an error occurs. A demo of the highlighting is displayed below: - -<a href="https://ibb.co/VpVMyZFM"><img src="https://i.ibb.co/yB0gT1zg/Screenshot-2025-07-12-at-9-01-37-PM.png" alt="Syntax Highlight"></a> - -<a href="https://ibb.co/1YTRYQFx"><img src="https://i.ibb.co/Y4hf4QHG/Screenshot-2025-07-12-at-9-01-48-PM.png" alt="Error Highlight"></a> - -**Made prototype for prompt to valid JavaScript code that can convert to MusicBlocks AI** - -This week, I have also made a gemini wrapper that takes in a prompt such as "Play twinkle twinkle little star with the guitar" and outputs JavaScript code that specifically works with MusicBlocks, so the user can copy paste the result into the JSeditor, convert the code to blocks, and play the result. This was done with a Google gemini API call along with extensive prompt engineering making sure it knows exactly what kind of code works with MusicBlocks, and what kind of code will cause errors if attempted to convert to blocks. - -[youtube: BFY3Bbi8V2g] - -[youtube: TEGWOAf5iO4] - -## Midterm Progress Summary - -**Over the 6 weeks of GSoC, I have accomplished the following** - -### Community Bonding: Project Foundation -- **Planning and Research**: Defined project scope and educational goals -- **Initial Implementation**: Started with basic JavaScript-to-blocks conversion for rhythm, flow, number, and boolean palettes -- **Architecture Design**: Planned the overall system architecture and feature roadmap - -### Week 1: Architecture Breakthrough -- **Config-Driven Refactoring**: Developed JSON-based configuration system for block mappings -- **AST Integration**: Implemented Acorn parser for JavaScript code analysis -- **Pattern Matching**: Created flexible AST pattern matching for complex JavaScript constructs -- **Extensibility**: Made adding new blocks as simple as updating configuration files - -### Week 2: Complete Implementation -- **Full Block Support**: Extended system to support all compatible block types -- **Optimization**: Implemented JSON minification and config consolidation -- **Documentation**: Created comprehensive conversion guide and unit tests -- **Production Deployment**: Successfully deployed feature through merged PR - -### Week 3: Debugger Development -- **Interactive Debugger**: Built working debugger with breakpoint system -- **Variable Inspection**: Implemented real-time variable display and tracking -- **Visual Integration**: Connected debugger statements to visual blocks -- **Educational Features**: Added step-by-step execution and status block integration - -### Week 4: Debugger Refinement -- **UX Optimization**: Simplified debug mode and improved user interface -- **Status Block Enhancement**: Optimized variable management and display -- **Execution Control**: Enhanced integration with existing play controls -- **Bug Fixes**: Resolved execution flow and block behavior issues - -### Week 5: Final Integration -- **Debugger Completion**: Finalized debugger with comprehensive PR -- **Syntax Highlighting**: Added basic syntax highlighting to JavaScript editor -- **Production Ready**: Completed all planned features and deployed to production -- **Documentation**: Finalized user guides and technical documentation ---- - -## Key Learnings - -- Improved skills in UX design and keeping tools simple for the user -- Deepened understanding of highlightjs -- Learned Gemini API calls -- Improved skills in prompt engineering -- Improved skills in **debugging**, **code design**, and **collaboration workflows**. - ---- - -## Next Week’s Roadmap - -- Fine tune an LLM to work better with MusicBlocks specific requests - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-12-gsoc-25-saumya-week05-06.md b/src/constants/MarkdownFiles/posts/2025-07-12-gsoc-25-saumya-week05-06.md deleted file mode 100644 index f0f305af..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-12-gsoc-25-saumya-week05-06.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "GSoC '25 Week 05, 06 Update by Saumya Shahi" -excerpt: "This week, I focused on building drag-and-drop utilities for bricks, developed a reverse mapping utility for coordinate-to-brick/tower lookup, and integrated these with the new collision map. Next up: visual interactions and user feedback!" -category: "DEVELOPER NEWS" -date: "2025-07-06" -slug: "2025-07-06-gsoc-25-saumya-shahi-week05" -author: "@/constants/MarkdownFiles/authors/saumya-shahi.md" -tags: "gsoc25,sugarlabs,week05,saumya-shahi" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 05 & 06 Progress Report by Saumya Shahi - -**Project:** [Masonry Module - Music Blocks v4](https://github.com/sugarlabs/musicblocks-v4) -**Mentors:** [Anindya Kundu](https://github.com/meganindya/) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-30 – 2025-07-06 - ---- - -## Goals for Weeks 05 & 06 - -- Build robust drag-and-drop utilities for bricks and palette -- Develop a reverse mapping utility to map coordinates to bricks/towers -- Integrate collision detection logic for interactive feedback -- Prepare for next week’s focus on visual feedback and user interactions - ---- - -## This Week's Progress - -### 1. **Drag-and-Drop Utilities for Bricks** - -This week, I focused on refining the drag-and-drop experience across both the palette and the workspace. -- **Unified Drag Logic:** The drag-and-drop system now works seamlessly, whether you’re moving bricks from the palette or rearranging them in the workspace. -- **Component Integration:** Real brick components are now fully draggable and interactable, making the workspace more dynamic. -- **Consistent State Management:** Drag state is now shared and updates are reflected instantly, ensuring a smooth user experience. - - - - ---- - -### 2. **Reverse Mapping Utility** - -I developed a utility that allows us to map any (x, y) coordinate to the corresponding brick and tower. -- **Efficient Lookup:** The utility uses bounding box and layout data for fast, accurate results. -- **Foundation for Visual Interactions:** This mapping is essential for features like selection, highlighting, and collision detection post processing. - -```typescript -function getBrickAtCoordinate(x: number, y: number): { brickId: string, towerId: string } | null { - // Uses bounding box/layout data to find the brick and tower at (x, y) -} -``` - ---- - -### 3. **Collision Map Integration** - -- **Collaboration:** I worked closely with another contributor who implemented the core collision detection logic. -- **Utility Integration:** The drag-and-drop and reverse mapping utilities are now integrated with the new collision map, enabling real-time interaction and hit-testing. - - - -As a side project, I also built a visualizer for collision points on the workspace. While it’s not part of the final product, it was a valuable exercise in visualizing interactions. - - - ---- - -## Technical Details - -- **Component Reuse:** Brick components are reused across different parts of the app, reducing duplication. -- **Extensible Design:** The reverse mapping utility is designed to support future features like selection and tooltips. - ---- - -## Key Takeaways - -- **Component and State Reuse:** Reusing logic and state across the app improves maintainability and reliability. -- **Hit Testing:** Building efficient hit-testing utilities is crucial for interactive UIs. -- **Atomic Commits:** I continued to practice atomic commits for better codebase hygiene and easier reviews. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for your ongoing support and feedback. - ---- - -<!-- markdownlint-enable --> \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-12-mostlyk-week06.md b/src/constants/MarkdownFiles/posts/2025-07-12-mostlyk-week06.md deleted file mode 100644 index ca5c7ea0..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-12-mostlyk-week06.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: "GSoC '25 Week 6 Update by Krish Pandya" -excerpt: "Palettes, Groups, and GTK4 Decisions " -category: "DEVELOPER NEWS" -date: "2025-07-15" -slug: "2025-07-15-gsoc-25-mostlyk-week06" -author: "@/constants/MarkdownFiles/authors/krish-pandya.md" -tags: "gsoc25,sugarlabs,week06,mostlyk,midterm" -image: "assets/Images/GSOC.png" ---- - - -# Week 6: Palettes, Windows, and GTK4 Decisions - -**Project:** [GTK4 Exploration](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya Ibiam](https://github.com/chimosky), [Juan Pablo Ugarte](https://github.com/xjuan) -**Reporting Period:** July 7, 2025 – July 15, 2025 - ---- - -## Why This Blog is Two Days Late - -First off, a confession: this update is getting written on 15th instead of the usual Saturday, I was travelling back to my university and this week's work was plenty and important. -I wanted to make sure I gave the proper write-up it deserves, especially since it's also the time for **midterm** evaluations. So if you are reading this, thank you for patience. - - -## Midterm Evaluations: Reflections - -For this week we had to write about midterm evaluations and after 6 weeks we have the halfway point. To look back what's been done , what changed and why. This project has been as much about architectural decisinos and learning as it has been about code or just porting in itself. - -- Weeks 1–2: Laying the foundation, setting up the C and Python split, and getting the Meson build system working. -- Weeks 3–4: We move into event controllers, file attribute utilities, and the starting of python library. -- Weeks 5–6: Animations, toolbars, and a full rework of the palette system for GTK4 python library now. - -### What changed and why? - -- Modern GTK4 patterns: Embracing controllers, gestures, and popovers has improved both code quality and user experience. -- Testing and documentation: Every major change is now accompanied by example scripts and documentation, making it easier for others (and my future self) to pick up where I leave off. - -### Personal growth: -Beyond the code, the first half taught me a lot about communcation, documenting decisions and working with mentors across time zones. I'have learned to reason and think about changes, justify architectural decisions, think broad and wide and accept that sometimes the best solutions are just compromise! -I look forward for the next half where I can finalizing the widgets and graphics and get one or two activities ported. - -## The Palette Rewrite of '25 - -The palette system was one of the most challenging and complex rewrites till now, it wasn't a find and replace, original implementation was tied to our own gestures. And event model and widget hierarchy which has been changed significantly in GTK4. - - -### What's the update in the Palettes? - - -- Will be sharing the example videos on next week! But here's the technical gist that I remember is big: - -- `Gtk.Popover` is King: Instead of manually managing popup windows, the new `Palette` class now uses `Gtk.Popover` for the menu implementation. - -- Controllers over Signals: The tangled web of event signals is gone. All interaction is now handled by `Gtk.EventController` and `Gtk.Gesture` objects. -For example, hover detection in `WidgetInvoker` now uses `Gtk.EventControllerMotion`, and clicks are captured with `Gtk.GestureClick`. - -- Real Widgets for Menu Items: `PaletteMenuItem` is no longer a `Gtk.EventBox`. It is now a proper `Gtk.Button`, which gives us accessibility, theming, and correct behavior for free. CSS is used to style it to look like a menu item, removing the need for manual background color changes on hover. - - -- `ToolButton`: The GTK3 `Gtk.ToolButton` is deprecated. So as the replacement we have `Gtk.Button` subclass styled with CSS to be our toolbutton, integrated with the `ToolInvoker` and palette system. It handles the activate state drawing and accelerator setup using modern `Gtk.Application` actions. - -- Streamlined Invokers: All invoker classes (`WidgetInvoker`, `CursorInvoker`, `ToolInvoker`, `TreeViewInvoker`) have been refactored to use the new controller-based system. - -### Some Threads and Docs: - -- https://gitlab.gnome.org/GNOME/gimp/-/issues/7700 -- https://docs.gtk.org/gtk4/class.EventControllerMotion.html -- https://valadoc.org/gtk4/Gtk.Popover.html -- https://docs.gtk.org/gtk4/class.GestureClick.html - ---- - - -## Progress Snapshot - -- Palette System: Complete rewrite for GTK4, including `Palette`, `PaletteGroup`, `PaletteMenuItem`, and all `Invoker` types. -- ToolButton: A new, modern `ToolButton` widget from scratch. -- Examples: Added comprehensive demos (`palette_example.py`, `palettegroup_example.py`) to showcase every feature and edge case of the new system. - ---- - -## Looking Ahead - -With palettes and toolbuttons now on a solid GTK4 footing, the next weeks will focus on: - -- Finalizing the remaining widget infrastructure (`widgets.py`) and integrating it with the palettes. -- Porting an actual Sugar activity to use the new toolkit, putting our work to a real-world test. - ---- - -## Links - -- [Project Page](https://summerofcode.withgoogle.com/programs/2025/projects/rsHsYZKy) -- [New Python Library (sugar-toolkit-gtk4-py)](https://github.com/MostlyKIGuess/sugar-toolkit-gtk4-py) -- [New C Library (sugar-ext)](https://github.com/sugarlabs/sugar-ext) -- [Game Demo Video](https://youtu.be/B517C_LTCns) - ---- - -## Closing Thoughts - -Next half of this GSoC going to be fun! And also we merged Sugar-AI ( _yay!_ thanks to Ibiam for taking out time to sit on a meet and go through this ) now we can deploy and test our LLMs and try to have more fun that way as well. - -And YESS NOW YOU CAN PLAY THE GAME HEHE. - -Until next week (on time, I promise!), -Krish diff --git a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-MebinThattil-week06.md b/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-MebinThattil-week06.md deleted file mode 100644 index c26470f8..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-MebinThattil-week06.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: "GSoC ’25 Week 06 Update by Mebin J Thattil" -excerpt: "Optimizations and reading documentation" -category: "DEVELOPER NEWS" -date: "2025-07-13" -slug: "2025-07-13-gsoc-25-mebinthattil-week6" -author: "@/constants/MarkdownFiles/authors/mebin-thattil.md" -tags: "gsoc25,sugarlabs,week06,mebinthattil,speak_activity" -image: "assets/Images/GSOCxSpeak.png" ---- - -# Week 06 Progress Report by Mebin J Thattil - -**Project:** [Speak Activity](https://github.com/sugarlabs/speak) -**Mentors:** [Chihurumnaya Ibiam](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-07-07 - 2025-07-13 - ---- - -## Goals for This Week - -- **Goal 1:** Improve dataset quality -- **Goal 2:** Fine-tune the model again and evaluate performance -- **Goal 3:** Work on mechanics for voice switching and personas inside Sugar - ---- - -## This Week’s Progress - -### **1. Improving the dataset** - -I fine-tuned the model using the dataset I had before, but it didn’t meet expectations. The model's responses were often repetitive and lacked the nuanced, encouraging tone of a teacher. For instance, it would give correct but blunt answers without any of the supportive dialogue we were aiming for. At times it gave answers that were completely irrelevant to the question. - -To address this, the next logical step was to significantly improve the dataset. I expanded it with more diverse conversation types and a wider range of questions that children might ask. To better simulate a real learning environment, I added examples where the teacher corrects a child's factual mistakes or spelling errors. Finally, to make the interactions feel more natural, I included general conversational snippets like “I love pizza” or “I just woke up.” - -### **2. Fine-tune the model again and evaluate performance** - -I proceeded to fine-tune the [Llama 135M model](https://huggingface.co/amd/AMD-Llama-135m) again, this time on the [updated dataset](https://github.com/mebinthattil/AMD_Llama_135M). After testing its performance, the results were still disappointing. While the tone improved slightly, the model struggled to maintain context in longer conversations and sometimes produced irrelevant responses, likely due to the inherent limitations of such a small model. - -Wanting to give it one last shot, I generated an entirely new, higher-quality dataset using Gemini, focusing specifically on teacher-child conversational patterns(Next week I'll share a link to a repo where I aggregate all these different datasets and model outputs in different formats). After fine-tuning the model on this new dataset, it performed better than before but still fell short of my goals. The next step is to formally benchmark both fine-tuned versions against the 50 questions I used for [benchmarking earlier](https://llm-benchmarking-sugar.streamlit.app/) and add their results for a direct comparison. - -### **3. Work on mechanics for voice switching and personas inside Sugar** - -I began working on the mechanics for voice switching and persona selection within Sugar. Before diving into the UI, I decided to first optimize Kokoro's integration with the Speak activity. The current process, where Kokoro writes a WAV file that GStreamer then plays, introduces a delay of 2 - 4 seconds. My goal is to get Kokoro to stream audio data directly to GStreamer as a source, which can then be played out using dual sinks similar to Speak's current implementation. This part isn’t fully working yet, as it requires a deeper dive into GStreamer's internals. I've been studying the documentation and hope to have this optimization completed in a few days, after which I can resume implementing the voice switching and persona mechanics. - -### **4. Size Optimization** - -One of the hardest and most interesting parts of this project was to package the SLM, the TTS model, and all its required dependencies within very tight size constraints. Every single byte matters. - -These are the sizes of the components as of now: -- **TTS**: 0.7MB Base + 0.5MB for each additional voice -- **SLM**: 82.6MB -- **Llama.cpp**: - - if we choose to distribute binaries for llama-cpp that will be used for inference: 2MB - - else, I would need to look into optimization (not done yet) - -Main factors contributing to the small size of components were: -- **TTS**: Switching Kokoro's fallback to use espeak instead of espeak-ng, since espeak was already used by the Speak activity. It also helps that Kokoro is pretty lightweight with only 82M parameters. -- **SLM**: The biggest reason is the insanely small parameter count of the SLM. I'm using LLaMA-135M. Further quantization and converting to GGUF format helped. -- **llama-cpp** (local model inference): Compiling to binary helped reduce size. I did a specific compilation, so it did not build a binary for everything, only the inference binary for chat was built. - -So overall, including the TTS, SLM, and llama-cpp, the size of additional components would be ~85–110MB (85MB if we distribute the binaries, 110MB if we don't). Do note that the dependencies for the LLM have not been included, but those are pretty lightweight, since it's just calling an API endpoint. - ---- - -## Midterm Summary - -*It feels great to sit back and reflect on what I’ve done so far. I’ve learned a lot and had a lot of fun building things.* -- The first week started off with a lot of [benchmarking](https://llm-benchmarking-sugar.streamlit.app/). This was essential, as we needed to choose a model to fine-tune. -We tested various models on a standard set of questions, asking each model the same ones and comparing the responses. -I also ensured I had a clear understanding of the project constraints, especially the limited client-side hardware. This directly influenced many of the design decisions later on. - -- The second week was focused on setting up the AWS infrastructure. -AWS was configured, and the LLaMA3-1B foundation model was fine-tuned on the [education dataset](https://github.com/mebinthattil/Education-Dialogue-Dataset). -The dataset was cleaned and formatted for LLaMA, and after fine-tuning, it was deployed to AWS. -I then tested the API endpoint with a Python script. This gave us a solid base to move forward. - -- The third week was spent addressing a model behavior issue where it would generate long response chains instead of simple Q&A style outputs. -To fix this, I restructured the [dataset](https://github.com/mebinthattil/Education-Dialogue-Dataset). -That week also coincided with my exams, so progress was slower than usual. - -- In Week 4, I worked on [integrating Kokoro into Speak](https://drive.google.com/file/d/1Z-zQrnH56CDVFJnEMmm6DflwpajwrLmI/view?usp=sharing). -While I managed to integrate Kokoro TTS, it was a bit hacky. Kokoro saved WAV files, and GStreamer read from them. -I also built a [model quantization pipeline](https://github.com/mebinthattil/Model_Quantize_Pipeline) that allowed me to quickly quantize chat-style models from 🤗, convert them to GGUF, and run [inference with plugin](https://github.com/mebinthattil/template_llama_chat_python) support. -This significantly sped up testing and allowed me to observe the impact of quantization on output quality. - -- And finally, last week was spent building a [Streamlit app](https://newstreamlit-frontend.blackpond-9921706d.eastus.azurecontainerapps.io/) for experimenting with different Kokoro voices. The app let you try differnt voices in kokoro with different languages, and also had an option to blend and mix different voices to create a unique voice. -This app made it easier to demo the new TTS to kids and collect feedback. -I also integrated the SLM into Speak. I used `llama-cpp-python` during inference, which led to noticeable performance boosts. -The model used was a fine-tuned and quantized version of [Llama-135M](https://huggingface.co/MebinThattil/Llama-135M-FT/tree/main). -However, due to the model’s small size, the initial responses were underwhelming. Even with fine-tuning, the improvements were only slight. - ---- - -## Next Week’s Roadmap - -- Complete Kokoro streaming with GStreamer -- Work on UI enhancements and group Kokoro voices by language -- Add both variations of the SLM to the benchmark - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for their ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-Nikhil-Bhatt-week06.md b/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-Nikhil-Bhatt-week06.md deleted file mode 100644 index 07121437..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-Nikhil-Bhatt-week06.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "GSoC '25 Week 06 Update by Nikhil Bhatt" -excerpt: "Implemented commit history viewer and version loading system using Git CLI and new backend routes, enabling seamless time-travel across project states." -category: "DEVELOPER NEWS" -date: "2025-07-13" -slug: "2025-07-13-gsoc-25-nikhilbhatt-week06" -author: "@/constants/MarkdownFiles/authors/nikhil-bhatt.md" -tags: "gsoc25,sugarlabs,week06,nikhilbhatt,midterm" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 06 Progress Report by Nikhil Bhatt - -**Project:** [Git backend for MusicBlocks](https://github.com/benikk/musicblocks-backend) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Reporting Period:** 2025-07-07 – 2025-07-13 - ---- - -## Progress Summary - -The first 6 weeks of GSoC'25 have been a great learning experience. The project is progressing as planned with meaningful improvements every week. <br/> -Our primary focus during this phase was the backend, with some attention to enhancing the user experience. -- Repository Creation with Ownership Tracking (using a Github app) - ```Github apps``` are safer, and scalable way of dealing with github directly, students can now create repositories directly into a centralised account, with ownership using a key, note that we do not save any user related information. -- Secure Editing Mechanism - even after publishing a project, students are able to edit their projects. Only those having a valid key can now edit their projects, in absence of that key, the project becomes ```read only```. -- Forking with Metadata & History - Projects can be forked easily via the UI. Forked repositories retain original content and metadata,A later upgrade replaced basic copying with full Git CLI–based cloning, ensuring complete ```commit history is preserved```. -- Commit History & Version Time Travel - Users can now select a commit from a UI modal and load the project state at that point. This feature introduces ```reflective-learning``` in students. -- Pull Request Workflow - an interesting addition to our existing planet based system, students can now contribute back to original projects after forking. The backend logic for this is complete and tested. Frontend integration is currently underway and will allow students to ```submit PRs with minimal effort.``` - -## A flow chart about the architecture of the project - - - -## This Week's Achievements - -### Backend: Commit History & Version Retrieval - -To support loading older versions of projects, I implemented two key backend routes using the Git CLI: - -- `GET /api/github/commitHistory/?repoName` - → Returns a list of all commit SHAs and messages for a given repository. - -- `GET /api/github/getProjectDataAtCommit?repoName=""&sha=""` - → Accepts a repo name and commit SHA, checks out the commit, and returns the `projectData.json` at that point in history. - -Both routes use secure Git Rest API methods. - ---- - -### 💡 Frontend: Modal Interface for Commit Viewer - -- Added a modal component that displays when the user clicks **"Show Commits"** from the GitHub dropdown. -- Each commit is rendered as a card showing the commit message, SHA, and a **"Load this version"** button. -- On click, the selected commit is sent to the backend, and the returned `projectData` is loaded using: - ---- - -## Challenges & How I Solved Them - -- **Challenge:** GitHub API only returns the latest file in current branch - **Solution:** Used GET /repos/:owner/:repo/contents/:path?ref=sha to fetch files at a specific commit. - -- **Challenge:** Loading project data for specific commits - **Solution:** Created an end point which takes the commit `sha` and returns the project data for that commit - ---- - -## Key Learnings -- How to use GitHub's REST API to interact with historical commit data. -- How to extract blob data (projectData) from specific commits using SHA. -- Importance of UX when introducing power-user features like history viewing. - ---- - -## Next Week's Roadmap -- Begin work on pull request functionality from forked projects. -- Enable students to raise PRs with metadata describing their changes. -- Explore preview diffs before PR submission. - ---- - -## Resources & References - -- [MusicBlocks Frontend Repo](https://github.com/sugarlabs/musicblocks) -- [musicblocks-backend](https://github.com/benikk/musicblocks-backend) -- [Octokit REST.js Library](https://github.com/octokit/rest.js) - ---- - -## Acknowledgments - -Thanks again to my mentors and the Sugar Labs community for feedback and support! -Looking forward to next week’s frontend PR features. - diff --git a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-SafwanSayeed-week06.md b/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-SafwanSayeed-week06.md deleted file mode 100644 index 03cb6cf1..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-SafwanSayeed-week06.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: "GSoC '25 Week 6 Update by Safwan Sayeed" -excerpt: "Symbol Table Refinements, IR Instructions Design, and Interpreter Architecture" -category: "DEVELOPER NEWS" -date: "2025-07-13" -slug: "2025-07-13-gsoc-25-sa-fw-an-week6" -author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" -tags: "gsoc25,sugarlabs,week6,sa-fw-an,midterm" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 6 Progress Report by Safwan Sayeed - -**Project:** Music Blocks 4 Program Engine -**Mentors:** [Anindya Kundu](https://github.com/meganindya/), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ullibari](https://github.com/pikurasa/), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-07-07 - 2025-07-13 - ---- - -## A Blog-style Retrospective - -This week marked a significant refinement phase in our Music Blocks program engine development as we focused on optimizing the Symbol Table design and laying the groundwork for the execution phase. The primary focus was on identifying and cataloging the IR (Intermediate Representation) instructions that will be implemented, followed by beginning the technical specification for the Interpreter module - the component that will bring our compiled IR code to life. - -The Symbol Table modifications were crucial for improving variable resolution efficiency and ensuring proper scope management. Working through the IR instruction identification process helped clarify the execution model and provided a clear roadmap for the interpreter implementation. - ---- - -## Six-Week Progress Summary - -Over the past six weeks, we've built a comprehensive foundation for the Music Blocks 4 Program Engine: - -**Weeks 1-2:** Established the core architecture with AST (Abstract Syntax Tree) framework and memory management system, implementing a three-scope hierarchy (Global, Thread, Local) with full CRUD operations. - - - -**Weeks 3-4:** Developed the AST-to-IR compilation logic, creating the crucial translation layer between abstract syntax trees and executable instructions using three-address code format. - -**Week 5:** Implemented the Symbol Table and integrated it with the Memory Module for effective variable scope and dependency management. - - - -**Week 6:** Refined the Symbol Table design, identified comprehensive IR instruction sets, and initiated the Interpreter architecture specification. - - - -This progression has taken us from initial planning to having a complete compilation pipeline ready for execution engine implementation. - ---- - -## Goals for This Week - -- Refine the Symbol Table design to improve variable resolution efficiency. -- Identify and catalog all IR instructions that will be implemented in the execution engine. -- Begin writing the technical specification for the Interpreter module. -- Define the interpreter's execution model and core implementation patterns. - ---- - -## This Week's Highlights - -1. **Symbol Table Design Modifications** - - Refined the Symbol Table implementation to improve variable resolution performance and scope management. - -2. **IR Instructions Identification** - - Conducted comprehensive analysis to identify all IR instructions required for the execution engine. - -3. **Interpreter Technical Specification** - - Started writing the technical specification for the Interpreter module architecture. - ---- - -## Challenges & Solutions - -- **IR Instruction Completeness:** - Ensuring we identified all necessary IR instructions for complete program execution support. - *Solution:* Systematically analyzed the AST compilation patterns and execution requirements to create a comprehensive instruction catalog. - ---- - -## Key Learnings - -- Gained deeper understanding of IR instruction design and Interpreter architecture. - ---- - -## Next Week's Roadmap - -- Complete the Interpreter technical specification with detailed implementation patterns. -- Begin implementing the first set of IR instructions in the execution engine. - ---- - -## Resources & References - -- **Tech Spec:** [Interpreter Architecture](https://docs.google.com/document/d/1_MCCgl-RqiEQH0UQ4EX-2O6G4iRxgHAY1rZpw3QPXT0/edit?tab=t.vexvgnhpt90v) -- **Repository:** [musicblocks-v4](https://github.com/sugarlabs/musicblocks-v4) - ---- - -## Acknowledgments - -Special thanks to my mentors Anindya, Sumit, Devin, and Walter for their continued guidance on compiler design principles and execution engine architecture. Their emphasis on maintaining clean separation between compilation and execution phases was crucial for this week's successful progress. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-diwangshu-week06.md b/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-diwangshu-week06.md deleted file mode 100644 index ecb4a0fa..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-diwangshu-week06.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "GSoC ’25 Week 06 Update by Diwangshu Kakoty" -excerpt: "Reflection Learning Widget in Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-07-13" -slug: "2025-07-13-gsoc-25-diwangshu-week06" -author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" -tags: "gsoc25,sugarlabs,week06,AI,midterm" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 06 Progress Report by Diwangshu Kakoty - -**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) -**Reporting Period:** 2025-07-06 - 2025-07-13 - ---- - -## Progress Summary - -The first six weeks of GSoC'25 have been highly productive, with several key milestones already accomplished: - -- Developed a Retrieval-Augmented Generation (RAG) pipeline. -- Built a fully functional Streamlit application for testing. -- Implemented a multi-agent chat model. -- Experimented with reasoning models and explored their integration. -- Created API endpoints for backend functionality. -- Developed a "reflection" widget in Music Blocks. -- Added save and upload capabilities to the Streamlit app. - -## Goals for This Week - -- **Goal 1:** Add upload and download of session state in Streamlit app. -- **Goal 2:** Add code conversion function in Streamlit app. -- **Goal 3:** Implement periodic summary generation. -- **Goal 4:** Fix bugs occured by these changes. - ---- - -## This Week’s Achievements - -1. **Add upload and download of session state in Streamlit app** - - Users can now conveniently save their conversations by downloading them. If they wish to resume at a later time, they can simply upload the saved session to continue where they left off. - - <a href="https://ibb.co/XZB7HJMG"><img src="https://i.ibb.co/zhcXdfDt/image.png" alt="image" border="0"></a> - -2. **Add code conversion function in Streamlit app** - - Users can now copy their Music Blocks project code and paste it into the app. The app then uses a conversion algorithm developed by [Omsuneri](authors/om-santosh-suneri) to generate an equivalent flowchart, which is easier for the LLM to interpret. - - - This flowchart is sent to the reasoning_llm, which produces the algorithm, a summary, and the purpose of the code. These outputs are then utilized by lightweight models. - -3. **Implement periodic summary generation** - - Based on my mentor's suggestion, I am implementing automatic periodic summary generation instead of relying on a manual button. This approach keeps the conversation seamless and allows users to take notes as they go. - - - This feature is still a work in progress. - -4. **Fix bugs occured by these changes** - - This week's work focused primarily on debugging. There were issues with the download button and updating the session state after file uploads. Further details on these challenges will be covered in the next section. - ---- - -## Challenges & How I Overcame Them - -- **Challenge :** I encountered challenges in refreshing the session states upon file upload. The expected behavior includes updating the message history, selected mentor, and user interface, but these updates weren't occurring properly. - - **Solution :** Streamlit reruns the entire script each time a button is clicked — a core behavior of the framework. Many of the issues I faced were due to the improper ordering of session state declarations, which I have now resolved. Additionally, I enhanced the download functionality to include more comprehensive information in the saved file, such as the mentor's name, the message history, and the session title. - ---- - -## Key Learnings - -- I am becoming more experienced as a Streamlit developer. - ---- - -## Next Week’s Roadmap - -- Implement a widget with functionality to save conversations, session summaries, and analytical insights. -- Finalize the auto-summary generation feature. -- Deploy the FastAPI server on AWS. - ---- - -## Resources & References - -- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) -- **Streamlit App:** [Reflection App](https://reflectionapp-2yoxtvn6sknvktme2zorvq.streamlit.app/) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-firepheonix-week06.md b/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-firepheonix-week06.md deleted file mode 100644 index aa8c723b..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-firepheonix-week06.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: "GSoC '25 Week 06 Update by Shubham Singh" -excerpt: "Music Player + Mid Term Evaluation" -category: "DEVELOPER NEWS" -date: "2025-07-13" -slug: "2025-07-13-gsoc-25-firepheonix-week06" -author: "@/constants/MarkdownFiles/authors/shubham-singh.md" -tags: - - gsoc25 - - sugarlabs - - week06 - - firepheonix -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 6 Progress Report by Shubham Singh - -**Project:** [Color Sensor for Music Blocks](https://github.com/sugarlabs/musicblocks/issues/4537) -**Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Walter Bender](https://github.com/walterbender) -**Reporting Period:** 2025-07-07 – 2025-07-13 - ---- - - -## Goals for This Week - -- Printing the outputs detected by the color detector. -- Implementing the music player. - ---- - -## This Week's Achievements - -1. **The music notations and their durations are now logged to the console** - - I finally logged all the colors to the console in a systematic way, without affecting projectstorage.js. -  - - -2. **Implemented the music playing feature** - - For example, the music player plays X rows, and the music for those X rows is played simultaneously, just like in the PhraseMaker. - - The system works on the principle: if green → no note played; if not green → note played. - - All notes are started simultaneously, then played according to their mapped timings. - - And here's a sample of the music generated. - - <iframe width="800" height="405" src="https://www.youtube.com/embed/ySjvYi936tg?si=FxZQn19AiLRixlpM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> - - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Wasn't able to figure out the next steps in development, and felt stuck while trying to find multiple ways of using the existing data. - **Solution:** I logged the data to the console and observed the PhraseMaker's approach to simultaneous playing. - ---- - -## Key Learnings - -- Sometimes logging the output to the console helps you take the next steps more effectively. For example, in API responses, you'll need to have the same type of UI as the type of response generated, so it's better to take care of that step beforehand. - ---- - -## Next Week's Roadmap - -- Build the action block output. -- Try to build a simple Do Re Mi Fa Sol La Ti sequence and its reverse, using exported action blocks in Music Blocks. - ---- - -## Resources & References - -- **Nothing much, just the Music Blocks documentation sufficed.** - ---- - -## Acknowledgments - -Thank you to my mentors [Walter Bender](https://github.com/walterbender) and [Devin Ulibarri](https://github.com/pikurasa) for invaluable guidance throughout this development phase. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-omsuneri-week06.md b/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-omsuneri-week06.md deleted file mode 100644 index 680433de..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-13-gsoc-25-omsuneri-week06.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -title: "GSoC’25 Week 06 Update by Om Santosh Suneri" -excerpt: "AI-powered Debugger for Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-07-13" -slug: "2025-07-13-gsoc-25-omsuneri-week06" -author: "@/constants/MarkdownFiles/authors/om-santosh-suneri.md" -tags: "gsoc25,sugarlabs,week06,Debugger,AI,Music Blocks,GSoC Midterm" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 06 Progress Report by Om Santosh Suneri - -**Project:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) -**Mentors:** [Walter Bender](https://github.com/walterbender/) [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa/) -**Reporting Period:** 2025-07-06 - 2025-07-12 - ---- - -## Goal for This Week - -**Build a tightly integrated debugging experience by embedding the JSON-to-Text converter into the main debugger Streamlit app and enabling users to export complete chat logs with the AI assistant** - ---- - -## This Week’s Achievements - -### Introduction - -This week’s focus was two-fold: - -1. **Merge and integrate** the Music Blocks JSON-to-Text converter directly into the existing Streamlit-based debugger UI. -2. **Enhance user experience** by introducing a "Chat Export" feature that allows users to download their complete AI-debugger conversation history in `.txt` format. - -These updates mark a major usability milestone and make the debugging experience smoother and more developer-friendly. - -### What I Did - -#### 1. Embedded JSON-to-Text Converter in the Debugger Workflow - -Previously, users had to first convert their Music Blocks JSON into readable text using a separate converter app and then copy that result into the debugger interface. This extra step caused friction in the user flow. - -Now, I’ve **fully integrated the `convert_music_blocks()` function** (from our `json_parser.py` module) directly into the debugger pipeline. Here’s how it works: - -* A user pastes raw Music Blocks JSON code into a text area inside the main debugger app. -* Upon clicking **"🚀 Launch My Music Blocks Project!"**, the code is parsed using `json.loads()` and fed into the `convert_music_blocks()` function. -* This recursive function translates the block structure into a clean, readable text representation using a tree-like format (`├──`, `│`, etc.), supporting clamp/stack logic and deeply nested project structures. -* The converted code is **stored in `st.session_state.project_code`** and becomes the foundational context for the entire debugging session. - -**Key Enhancements**: - -* Handles more block types like `arc`, `incrementOne`, `pitch`, and `settransposition`. -* Automatically redacts base64-encoded data like audio/image blobs by replacing them with `"data"` in output. -* Maintains formatting consistency to assist LLM comprehension and improve semantic chunk retrieval. - ---- - -#### 2. Chat Export Functionality - -To support documentation, sharing, and revisiting past sessions, I implemented a **chat export button**. The feature is context-aware and only appears when the user has interacted with the debugger. - -**Implementation Details**: - -* On each AI-user interaction, chat messages are appended to `st.session_state.chat_history` as a list of message dictionaries (`{"role": ..., "content": ...}`). -* The `generate_chat_export()` function: - - * Adds a timestamp using Python’s `datetime.now()`. - * Includes both the original converted project code and the full chat history. - * Formats everything into plain text. -* The Streamlit `st.download_button()` is used to render the export option, generating a downloadable `.txt` file named like `music_blocks_chat_20250711_143512.txt`. - -This makes the tool much more practical for teachers or learners who want to **archive** AI insights, share results, or continue the session later. - ---- - -### Why These Features Matter - -**Improved UX**: -With the converter now inside the debugger, users no longer need to juggle multiple tools. They can paste once, click once, and begin debugging immediately. - -**Smarter Debugging**: -The LLM uses the converted project code + relevant chunks from Music Blocks documentation (via `retrieve_relevant_chunks()`) to generate highly contextual, beginner-friendly replies. - -**Educational Value**: -Students and educators can **save their interactions**, review solutions offline, or submit chat logs for peer or mentor feedback. - ---- - -### Preview Features - -<a href=""><img src="https://i.ibb.co/FbHymBYN/Screenshot-2025-07-11-at-2-16-30-PM.png" alt="Music Blocks Debugger"></a> - -* 🔁 One-click conversion of Music Blocks JSON to structured text. -* 💬 Chat-driven debugging using Music Blocks Bot + documentation chunks. -* 💾 "Export Chat" button for persistent chat history. -* 🧽 "Clear Chat" button to reset sessions easily. - ---- - -## Midterm Evaluation Summary (Weeks 01–06) - -The first six weeks of GSoC 2025 have been focused on architecting and implementing the core systems behind the **AI-powered Debugger for Music Blocks**. From block parsing and embedding generation to LLM integration and full-stack deployment, the project has steadily evolved into a functional, AI-assisted debugging tool optimized for kids and educators. - ---- - -### Key Technical Achievements - -* **JSON-to-Text Parser**: Migrated the logic-heavy JavaScript converter to Python, maintaining tree-structured formatting (`├──`, `│`) and supporting recursion for nested Music Blocks projects. This makes visual projects readable and interpretable as text. - -* **Streamlit Interface**: Built a clean, user-friendly UI that enables users to paste JSON, parse it live, and interact with the AI debugger—all in one app. Integrated Gemini for generating responses tailored to kids. - -* **Vector Search with Qdrant**: Generated semantic embeddings from 14 curated Music Blocks projects and stored them in a Qdrant vector DB. This enables chunk retrieval from documentation and real examples to enhance LLM understanding. - -* **RAG Pipeline**: Combined user input + parsed project code + vector context to construct dynamic prompts for the LLM. Prompt behavior adapts based on session length to balance discovery and solution guidance. - -* **Export + UX Enhancements**: Added `.txt` chat export, refined session state handling, and introduced autoscroll + dynamic prompt control for a polished user experience. - ---- - -### Why It Matters - -By allowing users to paste a Music Blocks JSON file and instantly receive both a clean text summary and interactive feedback from an AI assistant, the tool reduces the barrier to debugging and learning. It helps students understand project flow, educators explain logic, and kids explore possibilities in a guided, friendly way. - ---- - -### Final Thoughts - -Over the past six weeks, I’ve transitioned from building isolated components to integrating them into a cohesive, interactive debugger. This week’s merge of the JSON converter into the main app simplified the workflow and enabled richer, context-aware prompts for the LLM. - -Technically, it deepened my understanding of state management, error handling, and modular design. Functions like convert_music_blocks() and retrieve_relevant_chunks() proved invaluable for maintaining clean, scalable code. The debugger is now not just functional — it’s ready to be embedded, deployed, and used meaningfully by kids and educators alike. - ---- - -### Next Week’s Roadmap - -* **Deploy the app to Sugar Labs’ AWS server** for long-term availability and community usage. -* **Develop a Music Blocks Widget** to embed the debugger directly into the Music Blocks environment for seamless integration and real-time support. - ---- - -## Resources & References - -- **Repository:** [AI-powered Debugger for Music Blocks](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks) -- **Debugger Streamlit App:** [Music Blocks Debugger](https://debuggmb.streamlit.app/) -- **Directory for Projects:** [Embedding Project Set](https://github.com/omsuneri/AI-powered-Debugger-for-Music-Blocks/tree/main/data/docs) - ---- - -### Acknowledgments - -Thanks to my mentors Walter Bender for the consistent feedback and support, and to Devin Ulibarri for assisting with insights into Music Blocks educational usage. The Sugar Labs community continue to be an invaluable support system. - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-14-dmp-25-therealharshit-week06.md b/src/constants/MarkdownFiles/posts/2025-07-14-dmp-25-therealharshit-week06.md deleted file mode 100644 index ceb3afa2..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-14-dmp-25-therealharshit-week06.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: "DMP ’25 Week 06 Update by Harshit Verma" -excerpt: "I added a new step to help students understand their code’s intent before debugging begins. I also worked on improving the terminal’s formatting and finalized Mistral 7B as the debugging model to be integrated with Sugar AI" -category: "DEVELOPER NEWS" -date: "2025-07-14" -slug: "2025-07-14-dmp-25-therealharshit-week06" -author: "@/constants/MarkdownFiles/authors/harshit-verma.md" -tags: "dmp25,sugarlabs,week06,midterm,therealharshit" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 06 Progress Report by Harshit Verma - -**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-07-07 - 2025-07-13 - ---- - -## Goals for This Week - -- **Goal 1:** Work on contextualization before debugging. -- **Goal 2:** Add CSS-style formatting to the debugging terminal. -- **Goal 3:** Finalize model decision for debugging. - ---- - -## This Week’s Achievements - -1. **Implemented Code Context Display for Learners** - - As discussed in the debugging meeting, added a step that shows the context or purpose of the code to the student, helping them understand what the code is trying to do before showing debug suggestions. - - This helps children first grasp what the code is meant to do, which builds confidence and improves the effectiveness of the debugging tips that follow. - - Introduced a new step in the debugging flow: before showing any suggestions, the interface displays a brief summary of the code’s intent or functionality. - -2. **Worked on Debug Terminal Formatting** - - Tried to apply CSS-like styles to make debug output more structured and visually appealing. - - GTK limitations posed challenges, continued work on enhancing the Markdown parser instead. - -3. **Finalize model decision for debugging** - - Decided to use **Mistral 7B**, which will be integrated with Sugar AI for better compatibility and performance. - - Based on performance tests and Sugar AI's deployment pipeline, It offers a good balance of output quality and resource efficiency for server-side use. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Styling Virtual Terminal Emulator (VTE) output with CSS. - **Solution:** Learned that we can't apply CSS to the VTE terminal output as they are not GTK widget, so I decided to work on further improving the markdown parser. - ---- - -## Key Learnings - -- Learned how code contextualization can help beginner coders by giving them an idea of what the code should do, and it also improves their ability to understand and fix problems. -- Developed a design-focused mindset for user-centric debugging tools. - ---- - -## Next Week’s Roadmap - -- Start working on replacing pippy-debugger-server with sugar-ai. -- Start working on saving debug history to Sugar Journal. -- Work on preparing a presentation as part of DMP midterm evaluation. - ---- - -# Midterm Progress Report (6 Week Summary) - -## Project Objective - -The goal of this project is to enhance the Pippy learning environment by integrating an LLM-powered debugger. The debugger uses LLMs to provide readable, friendly suggestions for fixing broken code, helping young learners understand and improve their programs. - ---- - -## Technical Implementation - -- Set up a **FastAPI backend** (`/debug`) to handle Python code input. - -- Integrated **Hugging Face model** for generating debugging tips. - -- Created **Run & Debug** buttons in Pippy’s GTK interface. - -- Connected **Pippy** with the backend server via API. - -- Implemented a **Debug terminal** in the UI to display suggestions. - -- Developed a **basic Markdown parser** for formatted output in VTE. - -- Added a **Contextualization step** to show students what the code intends to do before debugging begins. - ---- - -## Research & Design - -- Explored multiple **UI layouts** for debug output. - -- Tested different **LLM prompts** for clarity and simplicity. - -- Held discussions on **Debugging best practices for children**. - -- Evaluated models and selected **Mistral 7B** for deployment via Sugar AI. - ---- - -## Project Demo - -Please watch the project demo to see the progress I've made so far. -[Watch here](https://drive.google.com/file/d/1-FHfsd0YiOZ2Fb7V7HeSswcga89jEvos/view?usp=drive_link) - ---- - -## Resources & References - -**Repository** -- [Pippy](https://github.com/therealharshit/Pippy/tree/DMP2025/Pippy-Debugger) -- [sugar-ai](https://github.com/sugarlabs/sugar-ai) -- [pippy-debugger-server](https://github.com/therealharshit/pippy-debugger-server) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! - ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-14-gsoc-25-BishoyWadea-week06.md b/src/constants/MarkdownFiles/posts/2025-07-14-gsoc-25-BishoyWadea-week06.md deleted file mode 100644 index 22f6a7e0..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-14-gsoc-25-BishoyWadea-week06.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: "GSoC ’25 Week 06 Update by Bishoy Wadea" -excerpt: "Mid term evaluation reflection" -category: "DEVELOPER NEWS" -date: "2025-07-13" -slug: "gsoc-25-BishoyWadea-week06" -author: "@/constants/MarkdownFiles/authors/bishoy-wadea.md" -tags: "gsoc25,sugarlabs,week06,midterm,BishoyWadea" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 06 Progress Report by Bishoy Wadea - -**Project:** [Euclid’s Game](https://github.com/Bishoywadea/Euclid-s-Game) -**Mentors:** [Ibiam Chihurumnaya](https://github.com/chimosky) -**Assisting Mentors:** [Walter Bender](https://github.com/walterbender/) -**Reporting Period:** 2025-06-07 - 2025-07-14 - ---- - -## Goals for This Week - -- **Goal 1:** Start implementing Euclid’s Game ---- - -## This Week’s Achievements - -### *Goal 1: add helpful video tutorial in Soma Cube Game* - -1. **add video in help button** - - commit: [modify code to handle help videos](https://github.com/Bishoywadea/Soma-Cube/commit/63a7daaa8009f5f54791cdf9081e765846135f70) - -Soma Cube as Sugar activity [youtube: Q4BKp3Yo3Uw] - ---- - -### *Goal 2: Start implementing Euclid’s Game* - -**description of the game:** -The game inspired by Euclid’s game is a two-player mathematical strategy game -that illustrates the principles of the Euclidean algorithm, particularly in finding the -greatest common divisor (GCD) of two numbers. The game begins with two unequal -positive integers written on a board. Players alternate turns, and on each turn, a -player writes a new number on the board, which is the positive difference of any two -numbers already present. The new number must be distinct from all numbers -previously written. The game continues until a player cannot make a valid move; this -player loses the game. - -**Menu Light Theme:** - -This shows the main menu screen of Euclid’s Game in light mode. You can see the toolbar at the top with buttons like New Game and Help, along with options to switch between light and dark themes. Below that, there are buttons for selecting difficulty levels and choosing game modes, such as 2‑player or vs AI. - - - -**Menu Dark Theme:** - -This shows the main menu screen of Euclid’s Game in Dark theme - - - -**Gameplay Dark Theme:** - -Here you’re looking at the core game screen in dark mode. There's a board displaying numbers—the starting pair and any differences added. You can also see the current player’s turn and the move counter. - - - -**Gameplay Dark Theme:** - - - -**Gameplay Light Theme** - -This is the same gameplay view but in light theme. - -**Help Panel** - -This overlay provides instructions or guidance on how to play the game. It likely appears when you click the “Help” button from the toolbar, offering context and tips for first-time users. - - ---- - -## Challenges & Solutions - -- **Challenge:** Creating a responsive and user-friendly . - **Solution:** Implemented smooth game play logic to ensure accuracy and a satisfying user experience. ---- - -## Midterm Evaluation Reflection - -As I reach the halfway point of my GSoC journey, I’ve had the chance to reflect on the past six weeks—both the technical milestones and personal growth that came with them. - -### Progress So Far -Over the first phase of GSoC, I successfully developed and shipped five fully functional Sugar activities: -- [**Four Color Map Puzzle**](https://github.com/Bishoywadea/Four-Color-Map) – Core gameplay, UI enhancements, region data integration. -- [**Broken Calculator**](https://github.com/Bishoywadea/Broken-Calculator) – Restrictive math puzzle with scoring, themes, and child-friendly UX. -- [**Soma Cube**](https://github.com/Bishoywadea/Soma-Cube) – A 3D spatial reasoning puzzle featuring piece manipulation, textures, collision, and video tutorials. -- [**Fifteen Puzzle**](https://github.com/Bishoywadea/FifteenPuzzle) – Classic sliding puzzle with smooth animations and responsive layout. -- [**Euclid’s Game**](https://github.com/Bishoywadea/Euclid-s-Game) – Strategic math game with theme switching, help overlays, and polished UI. - - -Each activity was built from scratch or significantly improved, covering diverse gameplay styles—from logic puzzles to real-time spatial challenges—all designed with **educational value and child accessibility** in mind. - -### What I’ve Learned -- **Technical Mastery:** Strengthened my experience with **Pygame**, **Three.js**, and **GTK**, along with concepts like game loops, animation, and real-time input handling. -- **UI/UX Design:** Built interfaces tailored for young learners, focusing on clarity, feedback, and accessibility. -- **Open Source Discipline:** Embraced good development practices—clean commits, documentation, issue tracking, and community feedback cycles. - -### cknowledgments -This progress would not have been possible without the patient guidance of my mentors, Ibiam. Their feedback has helped me think more deeply about software design, education, and the impact of simplicity. The Sugar Labs community’s encouragement has also been motivating and insightful. - - ---- - -## Next Week’s Roadmap - -- Fix any feedback provided by members of the organization. -- Start implementing the Magic moving game. ---- diff --git a/src/constants/MarkdownFiles/posts/2025-07-15-gsoc-25-AdityaKrSingh26-week09.md b/src/constants/MarkdownFiles/posts/2025-07-15-gsoc-25-AdityaKrSingh26-week09.md deleted file mode 100644 index 569f8375..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-15-gsoc-25-AdityaKrSingh26-week09.md +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: "GSoC ’25 Week 09 Update by Aditya Kumar Singh and Midterm Summary" -excerpt: "Enhanced collaboration in Human Body activity by refining Paint and Tour interactions, improved UX in Doctor mode, and launched key features in Stickman like frame handling and animation controls." -category: "DEVELOPER NEWS" -date: "2025-07-15" -slug: "2025-07-15-gsoc-25-AdityaKrSingh26-week09" -author: "@/constants/MarkdownFiles/authors/aditya-singh.md" -tags: "gsoc25,sugarlabs,week09,AdityaKrSingh26,midterm" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 09 Progress Report by Aditya Kumar Singh and Midterm Summary - -**Project:** [Sugarizer](https://github.com/llaske/sugarizer) -**Mentors:** [Lionel Laské](https://github.com/llaske) -**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) -**Reporting Period:** 2025-07-10 – 2025-07-16 - ---- - -## Goals for This Week - -- **Goal 1:** Fix key UX and sync issues in the Human Body activity for Paint and Tour modes. -- **Goal 2:** Improve interactivity and usability in Doctor mode. -- **Goal 3:** Add shared leaderboard functionality for Doctor participants. -- **Goal 4:** Begin dashboard and animation logic in Stickman activity. - ---- - -## This Week’s Achievements - -1. **Human Body Paint & Tour Interaction Fixes** - - **Issue:** When switching from Tour to Paint, highlighted parts remained visually active across users. - - **Fix:** Restored original mesh material on mode switch using `restoreMeshColor()` and synced the update with a new `restoreMaterials` action. - - **Issue:** Unnecessary part-name popup showed for everyone when anyone painted. - - **Fix:** Restricted the popup to only the user who performed the action, enhancing clarity in shared sessions. - - **Issue:** Doctor mode lacked reminders of the current target part after failed guesses. - - **Fix:** Implemented a reminder popup after every 3 failed attempts to display: `"Remind you, we're looking for [Part Name]"`. - ```javascript - // restore material - if (msg.action = = "modeChange") { - if (msg.content != 0) return; - if (currentModel) { - currentModel.traverse((node) => { - if (node.isMesh && node.userData.originalMaterial) { - node.material = node.userData.originalMaterial.clone(); - } - }); - } - } - // Reminder popup - if (failedAttempts % 3 === 0 && failedAttempts > 0) { - showModal("Remind you, we're looking for " + l10n.get(bodyParts[presenceCorrectIndex].name)); - } - ``` - - Links : PR [#1800](https://github.com/llaske/sugarizer/pull/1800) - > Failed Attempt Popup -  - - -2. **Shared Doctor Mode Leaderboard Enhancements** - - Reworked the leaderboard to show users with the **highest score on top** in real-time. - - Implemented logic to sort and re-render the leaderboard HTML dynamically after each answer. - - Ensured that scores are updated and synchronized across all participants using the `scoreUpdate` action. - ```javascript - playerScores.sort((a, b) => b[1] - a[1]); - ``` - - XO icons rendered dynamically using user colors: - ```javascript - iconElement.style.backgroundImage = `url(${generateXOLogoWithColor(playerColor)})`; - ``` - > Real-time XO Leaderboard during Shared Doctor Mode -  - - -3. **Stickman Activity – Dashboard Features Bootstrap** - - **Launched key drawing infrastructure**: - - Users can now **create stickman**, **drag**, and **move** the whole figure. - - Proper **distance constraints** between joints maintain anatomical correctness. - - Integrated real-time canvas rendering loop to support: - - Drawing joint previews. - - Added mouse interaction listeners to support **joint selection and dragging**. - - -4. **Stickman Frame Handling + Animation Tools** - - Added **Add Frame**, **Preview Frame**, and **Remove Frame** options via UI. - - Integrated **Play / Pause** logic controlled via speed slider (`speedpalette.js`) to control animation playback. - - Introduced **Onion Skinning**—each frame preview shows a translucent version of adjacent frames for better motion consistency. - - Enabled **Template Palette** with selectable pre-built poses (run, dance). - - **Export as Video** and playback scaffold in progress using HTML5 Canvas. - - Links : PR [#1799](https://github.com/llaske/sugarizer/pull/1799) - > Stickman Dashboard UI with Toolbar and Timeline -  - - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Popup messages overloaded users in shared mode. - **Solution:** Added `networkId` checks to restrict popup visibility only to the sender. - ---- - -## Key Learnings - -- Gained deeper understanding of **presence synchronization patterns** in collaborative activities. -- Learned best practices for **frame-by-frame animation** and **canvas optimization**. -- Improved on creating **real-time UI updates** and dynamic SVG rendering using data-driven design. - ---- - -## Midterm Summary - -Over the past nine weeks, my journey with Sugar Labs through GSoC has been incredibly rewarding, both technically and personally. Here's a quick recap of my key milestones: - -- **Weeks 01–03:** I dove deep into the world of 3D anatomy, cleaning and merging segmented organ models, improving mesh clarity, and laying the foundation for the interactive Paint Mode in the Human Body activity. -- **Weeks 04–05:** I introduced internationalization with `i18next.js`, created a palette system to switch between anatomical models, and improved educational clarity through accurate labeling and skeletal refactoring. -- **Week 06:** I implemented onboarding tutorials, optimized models for performance, and started building shared logic for collaborative Paint Mode. -- **Weeks 07–08:** I built synchronization features for Tour and Doctor modes, including real-time scoring, shared camera states, and adaptive mesh highlighting. I also bootstrapped the new Stickman activity with animation tools and scaffolding. -- **Week 09 (this week):** I improved user experience by fixing shared mode bugs, added a real-time XO leaderboard in Doctor mode, and implemented critical frame-based animation controls like onion skinning and play/pause for Stickman. - -Throughout this phase, I’ve gained: - -- A much deeper understanding of **Three.js**, especially around camera controls, mesh interactions, and rendering pipelines. -- Hands-on experience in designing **real-time collaborative environments**, ensuring consistent state across clients. -- Confidence in writing **modular, scalable JavaScript**, integrating localization, and building UI that’s both intuitive and accessible. -- Awareness of **educational UX design**, where clarity and simplicity matter just as much as functionality. - - -I’m sincerely **grateful to my mentors** Lionel and Samarth for their patient guidance, critical feedback, and unwavering support. I’ve also grown by engaging with the Sugar Labs community, learning from discussions, and reading others’ code. - -This journey so far has not only improved my technical depth but also taught me how to think like an open-source contributor—collaborative, responsible, and focused on impact. I'm excited for the second half of GSoC and all the challenges and learning it will bring. - -Thank you again to everyone who's been part of this experience so far! - -## Next Week’s Roadmap - -- Fix remaining issue on Human Body -- Fix issues on dashboard and frame for Stickman activity -- Handle the adding a new stickman feature -- Handle Journal storage for stickman activity - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - diff --git a/src/constants/MarkdownFiles/posts/2025-07-19-gsoc-25-Elwin-Li-week07.md b/src/constants/MarkdownFiles/posts/2025-07-19-gsoc-25-Elwin-Li-week07.md deleted file mode 100644 index d76fb926..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-19-gsoc-25-Elwin-Li-week07.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "GSoC '25 Week 7 Update by Elwin Li" -excerpt: "MusicBlocks generation model" -category: "DEVELOPER NEWS" -date: "2025-07-19" -slug: "2025-07-19-gsoc-25-Elwin-Li-week07" -author: "@/constants/MarkdownFiles/authors/elwin-li.md" -tags: "gsoc25,sugarlabs,week7,javaScript editor,debugger,syntax highlighting" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 7 Progress Report by Elwin Li - -**Project:** MusicBlocks Generation Model - -**Mentors:** [Walter Bender](https://github.com/walterbender), [Anindya Kundu](https://github.com/meganindya), [Devin Ulibarri](https://github.com/pikurasa) - -**Reporting Period:** 2025-07-12 - 2025-07-19 - ---- - -## Goals for This Week - -- **Goal:** Work on obtaining a dataset for MusicBlocks generation model - ---- - -## This Week’s Achievements - -Before diving into the technical work, I want to share some context on the direction of my project. Last week, I experimented with a prompt-engineered Gemini API call to generate MusicBlocks code from natural language prompts. However, I found that this approach did not work well for examples more complex than simple nursery rhymes. As a result, I decided to explore the possibility of fine-tuning a model specifically for MusicBlocks code generation. - -I spent a significant amount of time this week learning about the process of fine-tuning large language models. Through this research, I discovered that a high-quality dataset is essential for effective fine-tuning. This realization shaped the rest of my week's work, as I shifted my focus toward obtaining and preparing such a dataset. - -This week, I mainly focused on gathering data for the MusicBlocks generation model. I used the example projects in the examples folder as my data source. Since these projects were in blocklist format, I needed to find a way to convert all of them to JavaScript code. - -To accomplish this, I developed a widget that can load projects directly from the examples folder, generate the corresponding JavaScript code, and download it. This streamlined the process of extracting code from a large number of example projects. - -<a href="https://ibb.co/7NTw72yd"><img src="https://i.ibb.co/HpMWmngf/Screenshot-2025-07-20-at-1-04-37-AM.png" alt="Examples Loader Widget"></a> - - -However, I found that only about half of the projects could be successfully converted to JavaScript. Many of the example projects contained blocks that are not currently supported for block-to-code conversion, which limited the amount of usable data I could extract for the model. - -After completing these achievements, I realized that since I didn't have much data available, fine-tuning might not be the most effective approach. Instead, I decided to shift my focus towards Retrieval-Augmented Generation (RAG) as an alternative. I have now started learning about the RAG process and how it could be applied to the MusicBlocks generation task. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** The Gemini API prompt engineering approach only worked for very simple examples and failed on more complex MusicBlocks projects. - - **Solution:** Decided to explore fine-tuning a model for MusicBlocks code generation, which required learning about the fine-tuning process and dataset requirements. - -- **Challenge:** Many example projects could not be converted from blocklist to JavaScript due to unsupported blocks in the block-to-code conversion process. - - **Solution:** Built a widget to automate the conversion and identify which projects could be used, maximizing the amount of usable data. - -- **Challenge:** Realized that the available dataset was too small for effective fine-tuning. - - **Solution:** Shifted focus to learning about Retrieval-Augmented Generation (RAG) as an alternative approach. - ---- - -## Key Learnings - -- Gained hands-on experience with prompt engineering for LLMs and its limitations for domain-specific code generation. -- Learned about the requirements and process for fine-tuning large language models, including the importance of dataset size and quality. -- Improved skills in automating data extraction and conversion workflows using custom widgets. -- Discovered the potential of Retrieval-Augmented Generation (RAG) as a practical alternative to fine-tuning when data is limited. - ---- - -## Next Week’s Roadmap - -- Continue learning about and experimenting with Retrieval-Augmented Generation (RAG) for MusicBlocks code generation. -- Investigate tools and frameworks for implementing RAG in the context of MusicBlocks. -- Explore ways to further expand or enhance the dataset, if possible. -- Begin prototyping a basic RAG pipeline using the data collected so far. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-20-gsoc-25-AdityaKrSingh26-week10.md b/src/constants/MarkdownFiles/posts/2025-07-20-gsoc-25-AdityaKrSingh26-week10.md deleted file mode 100644 index 7e75e45c..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-20-gsoc-25-AdityaKrSingh26-week10.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: "GSoC ’25 Week 10 Update by Aditya Kumar Singh" -excerpt: "Improved UX and syncing in Human Body activity, enhanced Stickman dashboard visuals, redesigned proportions, and implemented Journal save & multi-stickman support." -category: "DEVELOPER NEWS" -date: "2025-07-20" -slug: "2025-07-20-gsoc-25-AdityaKrSingh26-week010" -author: "@/constants/MarkdownFiles/authors/aditya-singh.md" -tags: "gsoc25,sugarlabs,week10,AdityaKrSingh26" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 10 Progress Report by Aditya Kumar Singh and Midterm Summary - -**Project:** [Sugarizer](https://github.com/llaske/sugarizer) -**Mentors:** [Lionel Laské](https://github.com/llaske) -**Assisting Mentors:** [Samarth Bagga](https://github.com/SamarthBagga) -**Reporting Period:** 2025-07-16 - 2025-07-23 - ---- - -## Goals for This Week - -- **Goal 1:** Improve Human Body UX (Tour/Doctor mode randomization, camera reset, leaderboard toggle). -- **Goal 2:** Polish Stickman activity dashboard and frame preview behavior. -- **Goal 3:** Improve stickman appearance and proportions. -- **Goal 4:** Enable multi-stickman support and journal storage. - ---- - -## This Week’s Achievements - -1. **Random Part Selection in Doctor/Tour Modes** - - Ensured every new session randomly selects a body part to focus on. - - The selection is now host-driven and synced to all participants. - ```javascript - function selectRandomPartForDoctor() { - presenceCorrectIndex = Math.floor(Math.random() * bodyParts.length); - document.dispatchEvent(new CustomEvent("target-updated", { - detail: { part: presenceCorrectIndex } - })); - } - ``` - - -2. **Camera Reset and Leaderboard Cleanup on Exit** - - Fixed host → client camera sync when exiting Tour mode. - - Leaderboard UI now clears correctly when Doctor mode ends. - ```javascript - function resetTourState() { - if (!window.isHost) { - camera.position.set(defaultX, defaultY, defaultZ); - controls.target.set(0, 1, 0); - controls.update(); - } - hideLeaderboard(); - } - ``` - - -3. **Frame Preview Enhancement in Stickman Activity** - - Previously, users had to add a new frame for the thumbnail preview to refresh. - - Now, any movement or change in the canvas auto-updates the preview. - - **Approach:** - - Detect changes in the canvas (e.g., drag end or part movement). - - Clone the updated canvas to the current frame’s preview. - - This ensures instant visual feedback while animating. - - -4. **Stickman Design Overhaul** - - Revisited the drawing logic and proportions: - - Shorter neck - - Thicker limbs - - Solid, filled circular head - - Inspired by Pivot Animator to offer a more professional, relatable look. - > Updated Stickman Design -  - - -5. **Multi-Stickman Canvas Support** - - Users can now add more than one stickman in the scene. - - Each stickman is an isolated object with its own: - - Position and joint data - - Frame history - - Selectable state - - **Algorithm:** - - Maintain a list of stickman instances. - - On user interaction, determine which stickman is targeted. - - Only that stickman responds to move, draw, and animate actions. - > Multiple Stickman preview in acitvity -  - - -6. **Journal Integration for Stickman** - - Implemented save/load logic to persist stickman data (frames, templates, active character). - - **Approach:** - - On save: Serialize all current stickmen, their frame sequences, and selected templates into a JSON blob. - - On load: Deserialize and reconstruct all visual data, restoring the full session. - - This allows users to save their progress and resume where they left. - - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Preventing multiple stickmen from interfering with each other’s states. - **Solution:** Scoped interaction events to only apply to the selected stickman instance. - -- **Challenge:** Updating previews without triggering unnecessary rendering overhead. - **Solution:** Triggered preview redraws only on meaningful events like drag-end or transformation complete. - ---- - -## Key Learnings - -- Learned how to architect multi-actor systems on a single canvas while maintaining performance. -- Strengthened my understanding of event-driven synchronization in real-time collaborative applications. - ---- - -## Next Week’s Roadmap - -- Fix remaining issue on Human Body -- Increase the size of Stickman -- Show frames only for selected stickman for multiple stickman -- Show joints only for selected stickman for multiple stickman -- Add popup when removing stickman with frames count >1 - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - diff --git a/src/constants/MarkdownFiles/posts/2025-07-20-gsoc-25-diwangshu-week07.md b/src/constants/MarkdownFiles/posts/2025-07-20-gsoc-25-diwangshu-week07.md deleted file mode 100644 index bf6790b3..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-20-gsoc-25-diwangshu-week07.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: "GSoC ’25 Week 07 Update by Diwangshu Kakoty" -excerpt: "Reflection Learning Widget in Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-07-20" -slug: "2025-07-20-gsoc-25-diwangshu-week07" -author: "@/constants/MarkdownFiles/authors/diwangshu-kakoty.md" -tags: "gsoc25,sugarlabs,week06,AI" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week 07 Progress Report by Diwangshu Kakoty - -**Project:** [AI Tools for Reflection](https://github.com/Commanderk3/reflection_ai) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Sumit Srivastava](https://github.com/sum2it) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa), [Ajeet Pratap Singh](https://github.com/apsinghdev) -**Reporting Period:** 2025-07-14 - 2025-07-19 - ---- - -## Goals for This Week - -- **Goal 1:** Implement periodic summary generation. -- **Goal 2:** Upgrading the 'reflection' widget. -- **Goal 3:** Fix bugs occured by these changes. - ---- - -## This Week’s Achievements - -1. **Implement periodic summary generation** - - As mentioned in the previous blog, I’ve now implemented periodic summary generation. Currently, it uses a straightforward prompt that requests a summary after every five bot messages. While this is a simple and somewhat detailed approach, it’s still basic and may not consistently produce accurate results. I’m in the process of testing it. - - - If it proves unreliable, I’ll switch to invoking the LLM with a dedicated prompt template after every five bot messages. This will ensure a structured and consistent summary each time. - -2. **Upgrading the 'reflection' widget** - - - The widget now allows users to interact with all available AI mentors directly within the interface. When a user initiates a conversation, their project code is automatically sent to the server, enabling mentors to provide more context-aware guidance and feedback. For this I developed a '/code' endpoint. This is the flow: - - - Music Blocks sends the project code to the server as a POST request in JSON format. - - - The server processes this data by running a conversion module and then calls the reasoning LLM to generate the corresponding algorithm. - - - It then responds with both the flowchart and the algorithm. - - - The client is responsible for storing this information and including it in requests sent to the /chat endpoint. - - - - I have also enhanced the save functionality. Users can now choose to save their entire conversation history at any point. In addition, the system automatically stores generated summaries and analytical insights, ensuring that important information and progress are preserved for future reference. - ---- - -## Challenges & How I Overcame Them - -- **Challenge :** I faced a minor challenge while implementing the periodic summary. My approach is to start simple and build up as needed, so I initially relied on prompting. However, the LLM wasn’t following the instruction. After some brainstorming, I realized that other instructions like 'Limit your response to 30 words' might have been conflicting with it - - **Solution :** I modified the conflicting prompts and experimented with few-shot prompting, which resolved the issue. ---- - -## Key Learnings - -- Adjusting or refining conflicting prompts, combined with the use of few-shot prompting, can significantly improve an LLM’s output. This highlights the importance of prompt engineering in guiding model behavior and achieving desired results. ---- - -## Next Week’s Roadmap - -- I need to finish building the widget to store user data, such as messages, summaries, and analysis reports using IndexedDB. -- Once that’s completed, I’ll move on to the 'analysis generation' phase. - ---- - -## Resources & References - -- **Repository:** [reflection_streamlit](https://github.com/Commanderk3/reflection_streamlit) -- **Streamlit App:** [Reflection App](https://reflectionapp-2yoxtvn6sknvktme2zorvq.streamlit.app/) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/2025-07-21-dmp-25-therealharshit-week07.md b/src/constants/MarkdownFiles/posts/2025-07-21-dmp-25-therealharshit-week07.md deleted file mode 100644 index d2fa04b6..00000000 --- a/src/constants/MarkdownFiles/posts/2025-07-21-dmp-25-therealharshit-week07.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "DMP ’25 Week 07 Update by Harshit Verma" -excerpt: "Presented my work on Pippy Debugger to mentors and also started working on developing API endpoint in Sugar-AI." -category: "DEVELOPER NEWS" -date: "2025-07-21" -slug: "2025-07-21-dmp-25-therealharshit-week07" -author: "@/constants/MarkdownFiles/authors/harshit-verma.md" -tags: "dmp25,sugarlabs,week07,therealharshit" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 07 Progress Report by Harshit Verma - -**Project:** [LLM-powered Debugger for Pippy](https://github.com/sugarlabs/Pippy/issues/95) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Ibiam Chihurumnaya](https://github.com/chimosky), [Kshitij Shah](https://github.com/kshitijdshah99) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-07-14 - 2025-07-20 - ---- - -## Goals for This Week - -- **Goal 1:** Prepare a presentation for the DMP Midterm Evaluation. -- **Goal 2:** Start working on the `/debug` endpoint in Sugar-AI. - ---- - -## This Week’s Achievements - -1. **Prepared a presentation for the DMP Midterm Evaluation.** - - I prepared a comprehensive presentation to showcase the progress of the **Pippy Debugger** at the DMP midterm review. The presentation covered everything from project objectives and methods to current results, challenges, and future plans. - - Additionaly, I also gave a mock presentation of my work to the Sugar Labs mentors. - - [DMP Midterm Presentation](https://docs.google.com/presentation/d/13bAMCpKi6ezlhBEQ7NGR7eszumwpYZnL8dGFLNlnBF8/edit?usp=sharing) - -2. **Started working on developing API endpoint in Sugar-AI** - - Began development of a new `/debug` endpoint in Sugar-AI. This endpoint will handle code input and return structured debug suggestions from the LLM. - - I have also started the process of integrating Sugar-AI with Pippy. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Understaing Sugar-AI’s existing API structure. - **Solution:** I followed the documentaion and my mentors guidance. - ---- - -## Key Learnings - -- How to design and deliver a structured presentation. -- Introduction to Sugar-AI’s internal API design and how to extend it. - ---- - -## Next Week’s Roadmap - -- Finalize the work of `/debug` endpoint in Sugar-AI. -- Work on making the LLM response more kids friendly. -- Start working on saving debug history to Sugar Journal. - ---- - -## Resources & References - -**Repository** -- [Pippy](https://github.com/therealharshit/Pippy/tree/DMP2025/Pippy-Debugger) -- [sugar-ai](https://github.com/sugarlabs/sugar-ai) -- [pippy-debugger-server](https://github.com/therealharshit/pippy-debugger-server) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for your continued guidance and support! - ---- diff --git a/src/constants/MarkdownFiles/posts/TESTMarkdownFormat.md b/src/constants/MarkdownFiles/posts/TESTMarkdownFormat.md deleted file mode 100644 index 7bac706c..00000000 --- a/src/constants/MarkdownFiles/posts/TESTMarkdownFormat.md +++ /dev/null @@ -1,474 +0,0 @@ ---- -title: "Comprehensive Markdown Syntax Guide" -excerpt: "A complete reference template showcasing all common markdown features and formatting options" -category: "TEMPLATE" -date: "2025-06-13" -slug: "markdown-guide" -author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" -tags: "markdown,reference,guide,syntax,documentation,template" -image: "https://images.unsplash.com/photo-1506744038136-46273834b3fb?w=2070" ---- -<!-- markdownlint-disable --> - -# Comprehensive Markdown Syntax Guide - -This document serves as a complete reference for markdown syntax, demonstrating various formatting elements and features supported by our enhanced markdown parser with GitHub-style rendering. - -## Headings - -# Heading Level 1 -## Heading Level 2 -### Heading Level 3 -#### Heading Level 4 -##### Heading Level 5 -###### Heading Level 6 - -## Text Formatting - -**Bold text** or __also bold text__ - -*Italic text* or _also italic text_ - -***Bold and italic text*** or ___also bold and italic___ - -~~Strikethrough text~~ - -==Highlighted text with custom styling== - -Super^script^ text and Sub~script~ text - -Here's some `inline code` within a paragraph for demonstration. - -## Code Examples - -### Inline Code vs Code Blocks - -Single backticks for `inline code highlighting` like `const variable = "value"` or `npm install`. - -### Code Blocks with Language Support - -```javascript -// JavaScript example with syntax highlighting -function calculateSum(a, b) { - return a + b; -} - -const result = calculateSum(5, 10); -console.log(`The sum is: ${result}`); -``` - -```python -# Python example -def fibonacci(n): - if n <= 1: - return n - return fibonacci(n-1) + fibonacci(n-2) - -# Generate first 10 Fibonacci numbers -for i in range(10): - print(f"F({i}) = {fibonacci(i)}") -``` - -```typescript -// TypeScript example -interface User { - id: number; - name: string; - email: string; -} - -const createUser = (userData: Partial<User>): User => { - return { - id: Date.now(), - name: userData.name || "Anonymous", - email: userData.email || "user@example.com" - }; -}; -``` - -```css -/* CSS example */ -.markdown-content { - font-family: 'Inter', sans-serif; - line-height: 1.6; - color: #333; -} - -.code-block { - background: #f6f8fa; - border-radius: 6px; - padding: 16px; - overflow-x: auto; -} -``` - -```bash -# Bash commands -git clone https://github.com/username/repo.git -cd repo -npm install -npm run dev -``` - -```sql --- SQL example -SELECT users.name, posts.title, posts.created_at -FROM users -JOIN posts ON users.id = posts.user_id -WHERE posts.published = true -ORDER BY posts.created_at DESC -LIMIT 10; -``` - -## Links and References - -### Basic Links -[Basic link to example.com](https://example.com) - -[Link with title](https://example.com "Example Website") - -### Auto-links -<https://example.com> - -<email@example.com> - -## Lists - -### Unordered Lists -- Item 1 -- Item 2 - - Nested Item 2.1 - - Nested Item 2.2 - - Deeply nested item -- Item 3 - -Alternative syntax: -* Item 1 -* Item 2 - * Nested item -* Item 3 - -### Ordered Lists -1. First item -2. Second item - 1. Nested item 2.1 - 2. Nested item 2.2 - 1. Deeply nested numbered item -3. Third item - -### Task Lists -- [x] Completed task -- [ ] Incomplete task -- [x] Another completed task -- [ ] Task with **bold text** -- [ ] Task with `inline code` - -### Definition Lists -First Term -: Definition of the first term - -Second Term -: Definition of the second term -: Another definition of the second term - -Complex Term -: This is a more complex definition that can include **bold text**, *italic text*, and `inline code`. - -## Images and Media - -### Basic Image - - -### Linked Image -[](https://example.com) - -### YouTube Video Embeds - -[youtube: MM-H69cHYMk] - -## Tables - -### Basic Table -| Header 1 | Header 2 | Header 3 | -|----------|:--------:|---------:| -| Default | Centered | Right | -| aligned | aligned | aligned | -| text | text | text | - -### Advanced Table with Formatting -| Command | Description | Example | -| --- | --- | --- | -| `git status` | List all new or modified files | Shows modified files in red | -| `git diff` | Show file differences not yet staged | `git diff HEAD~1` | -| `git add .` | Stage all changes | Adds all files to staging | -| `git commit -m "message"` | **Commit** with message | Creates new commit | - -### Feature Comparison Table -| Feature | Basic Plan | Pro Plan | Enterprise | -|---------|:----------:|:--------:|:----------:| -| Users | 5 | 25 | Unlimited | -| Storage | 10GB | 100GB | 1TB | -| Support | Email | Priority | 24/7 Phone | -| Price | $10/mo | $25/mo | Custom | - -## Blockquotes - -### Simple Blockquote -> This is a simple blockquote - -### Multi-paragraph Blockquote -> This is a blockquote with multiple paragraphs -> -> Second paragraph in the blockquote - -### Nested Blockquotes -> This is the first level of quoting. -> -> > This is nested blockquote. -> -> Back to the first level. - -### Complex Blockquote -> #### Blockquote with other elements -> -> - Lists inside blockquote -> - Another item with `inline code` -> -> **Bold text** inside blockquote with *italic* and `code`. -> -> ```javascript -> // Code block inside blockquote -> console.log("Hello from blockquote!"); -> ``` - -## Horizontal Rules - -Three or more hyphens: - ---- - -Asterisks: - -*** - -Underscores: - -___ - -## GitHub-Style Alerts - -:::note -This is a note alert. Use it to provide additional information that's helpful but not critical. -::: - -:::tip Pro Tip -This is a tip alert. Great for sharing best practices and helpful suggestions! -::: - -:::important Important Notice -This is an important alert. Use it for information that users should definitely pay attention to. -::: - -:::warning Be Careful -This is a warning alert. Use it to highlight potential issues or things to watch out for. -::: - -:::caution Critical Warning -This is a caution alert. Use it for serious warnings about potential problems or security issues. -::: - -## Collapsible Sections - -### Basic Collapsible -:::details Click to expand basic details -This content is hidden by default and can be expanded by clicking the summary. - -You can include: -- **Formatted text** -- `Code examples` -- And other markdown elements - -```javascript -console.log("Code works too!"); -``` -::: - -### Advanced Collapsible -:::details Advanced Configuration Options -Here are some advanced configuration options: - -#### Database Settings -- **Host**: localhost -- **Port**: 5432 -- **Database**: myapp_production - -#### Security Configuration -```yaml -security: - encryption: AES-256 - hashing: bcrypt - session_timeout: 3600 -``` - -#### Performance Tuning -| Setting | Development | Production | -|---------|-------------|------------| -| Cache TTL | 60s | 3600s | -| Max Connections | 10 | 100 | -| Timeout | 30s | 10s | -::: - -<details> -<summary>HTML-style Collapsible Section</summary> - -This is using HTML details/summary tags. - -- You can include **formatted text** -- And other elements -- `Code snippets` - -```python -def hello_world(): - print("Hello from collapsible section!") -``` - -</details> - -## Extended Features - -### Footnotes - -Here's a sentence with a footnote[^1]. - -Here's another footnote reference[^2]. - -Multiple footnotes in one sentence[^3][^4]. - -[^1]: This is the footnote content with **formatting**. -[^2]: This footnote contains `code` and *emphasis*. -[^3]: Short footnote. -[^4]: This is a longer footnote that can contain multiple sentences. It can even contain code blocks and other formatting elements. - -### Emoji Support - -#### Emotions and Reactions -:smile: I'm happy to see this working! -:heart: Love this feature! -:thumbsup: Looks good to me! -:thumbsdown: This needs work. -:eyes: I'm watching this. -:tada: Celebration time! - -#### Technical and Development -:rocket: Let's launch this feature! -:fire: This is awesome! -:star: Five-star quality! -:bug: There's a bug here. -:wrench: Fix needed. -:gear: Configuration required. -:sparkles: New feature! -:package: New release. -:zap: Performance improvement. -:boom: Breaking change. - -#### Communication and Status -:warning: Be careful with this syntax. -:info: Here's some information. -:check: This is correct! -:x: This is wrong. -:bulb: Great idea! -:memo: Take notes. -:link: Related link. -:lock: Secure content. -:unlock: Public content. - -#### Objects and Places -:computer: Development environment. -:phone: Mobile responsive. -:email: Contact information. -:calendar: Scheduled event. -:clock: Timing important. -:house: Home page. -:car: Fast delivery. -:plane: Deploy quickly. -:coffee: Developer fuel. -:pizza: Team lunch. - -### Deletions and Insertions - -~~This text has been deleted~~ and replaced with new content. - -<del>This is also deleted text</del> - -<ins>This text has been inserted</ins> - -## Advanced Formatting Combinations - -### Mixed Formatting Examples - -Here's text with **bold**, *italic*, `code`, ==highlighted==, ~~strikethrough~~, and [[Ctrl+A]] keyboard shortcut. - -> **Important Quote**: Use `console.log()` for debugging, but remember to ==remove it== before production. ~~Don't use alert().~~ :warning: - -| Feature | Status | Shortcut | Notes | -|---------|--------|----------|--------| -| **Bold** | :check: | [[Ctrl+B]] | Works everywhere | -| *Italic* | :check: | [[Ctrl+I]] | `_text_` also works | -| `Code` | :check: | [[Ctrl+`]] | Inline highlighting | -| ==Highlight== | :check: | N/A | Custom feature | - -### Complex List with Everything - -1. **First Item** with `code` and [link](https://example.com) - - Nested item with ==highlighting== - - Another nested item with :rocket: emoji - - [ ] Unchecked task with ~~strikethrough~~ - - [x] Completed task with **bold text** - -2. **Second Item** with math: $E = mc^2$ - ```python - # Code block in list - def example(): - return "Hello World" - ``` - -3. **Third Item** with blockquote: - > This is a quote inside a list item - > with **bold** and *italic* text - -## Accessibility Features - -### Screen Reader Friendly Content - -All images have descriptive alt text: - - -All links have descriptive text: -[Read the complete accessibility guidelines](https://example.com "Complete guide to web accessibility") - -### Semantic HTML Elements - -<details> -<summary>Semantic Structure Information</summary> - -Our markdown parser generates semantic HTML with: -- Proper heading hierarchy -- Accessible form controls -- ARIA labels where appropriate -- Focus management for interactive elements - -</details> - ---- - -### Final Thoughts - -This comprehensive markdown guide demonstrates the full capabilities of our enhanced parser. From basic formatting to advanced features like mathematical expressions and interactive elements, this parser provides a rich, GitHub-style experience. - -Thank you for reading this detailed markdown reference! :heart: :rocket: - -Remember to use the copy button on code blocks to quickly copy examples! :sparkles: - ---- - -*Last updated: 2025-06-13 | Version 2.0 | Contributors: Safwan Sayeed* \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/YYYY-MM-DD-GSoC_DMP_SSoC_Template.md b/src/constants/MarkdownFiles/posts/YYYY-MM-DD-GSoC_DMP_SSoC_Template.md deleted file mode 100644 index 48d61b91..00000000 --- a/src/constants/MarkdownFiles/posts/YYYY-MM-DD-GSoC_DMP_SSoC_Template.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "GSoC ’25 Week XX Update by Safwan Sayeed" -excerpt: "This is a Template to write Blog Posts for weekly updates" -category: "TEMPLATE" -date: "2025-05-10" -slug: "YYYY-MM-DD-gsoc-25-sa-fw-an-weekXX" -author: "@/constants/MarkdownFiles/authors/safwan-sayeed.md" -tags: "gsoc25,sugarlabs,weekXX,sa-fw-an" -image: "assets/Images/GSOC.png" ---- - -<!-- markdownlint-disable --> - -# Week XX Progress Report by Safwan Sayeed - -**Project:** [Project Name](https://github.com/sugarlabs/www-v2) -**Mentors:** [Mentor1](https://github.com/Username), [Mentor2](https://github.com/Username) -**Assisting Mentors:** [Mentor3](https://github.com/Username), [Mentor4](https://github.com/Username) -**Reporting Period:** yyyy-mm-dd - yyyy-mm-dd - ---- - -## Goals for This Week - -- **Goal 1:** Describe the first planned deliverable. -- **Goal 2:** Describe the second planned deliverable. -- **Goal 3:** Describe an additional target. - ---- - -## This Week’s Achievements - -1. **[Task or Feature]** - - What you did and why it matters. - - Links (if any): PR [#123](https://github.com/owner/repo/pull/123), Issue [#456](https://github.com/owner/repo/issues/456). - -2. **[Task or Feature]** - - Brief summary or a video. - [youtube: MM-H69cHYMk] - -3. **[Task or Feature]** - - Add screenshots or diagrams here if useful: -  - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Describe a blocker or difficulty. - **Solution:** Outline your approach or resources used. - -- **Challenge:** Another issue faced. - **Solution:** Steps taken to resolve or next action plan. - ---- - -## Key Learnings - -- Gained familiarity with **XYZ library or tool**. -- Deepened understanding of **SOLID principles**, **architecture modeling**, **DFDs**, etc. -- Improved skills in **testing**, **documentation**, and **collaboration workflows**. - ---- - -## Next Week’s Roadmap - -- Implement **Feature XYZ** and write corresponding tests. -- Refine **technical design** based on mentor feedback. -- Prepare a mini-demo for the community check-in. - ---- - -## Resources & References - -- **PRD:** [Link to Product Requirements Document]({{prd_link}}) -- **Tech Spec & Diagrams:** [Architecture & Specs]({{tech_spec_link}}) -- **Repository:** [github.com/owner/repo](https://github.com/owner/repo) -- Any additional links, diagrams, or attachments. - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow GSoC contributors for ongoing support. - ---- - diff --git a/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week01.md b/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week01.md deleted file mode 100644 index 9e0be52a..00000000 --- a/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week01.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "DMP ’25 Week 01 Update by Aman Chadha" -excerpt: "Working on a RAG model for Music Blocks core files to enhance context-aware retrieval" -category: "DEVELOPER NEWS" -date: "2025-06-09" -slug: "2025-06-09-dmp-25-aman-week01" -author: "Aman Chadha" -description: "DMP '25 Contributor working on retrieval-augmented generation for Music Blocks" -tags: "dmp25,musicblocks,rag,week01" -image: "assets/Images/c4gt_DMP.png" ---- - -<!--markdownlint-disable--> - -# Week 01 Progress Report by Aman Chadha - -**Project:** [JS Internationalization with AI Translation Support](https://github.com/sugarlabs/musicblocks/pull/4459) - -**Mentors:** [Walter Bender](https://github.com/walterbender) - -**Reporting Period:** 2025-06-02 - 2025-06-08 - ---- - -## Goals for This Week - -- Develop a Retrieval-Augmented Generation (RAG) model using the core files of Music Blocks to provide context-aware responses. -- Collect and parse .po files, extracting msgid and msgstr pairs along with comments showing usage in source files. -- Use AST parsing (with Babel) to gather metadata chunks from source files to improve retrieval relevance. - ---- - -## This Week’s Achievements - -1. **RAG Model Development** - - Started working on building a RAG model focused on the core Music Blocks files. This aims to give the model context about what Music Blocks is and how it functions, improving answer relevance. - -2. **Metadata Extraction from .po Files** - - Successfully collected msgid and msgstr pairs from translation files. - - Parsed comments above the translations to identify which files use each msgstr. - -3. **AST Parsing and Chunking** - - Used Babel to parse Music Blocks source files and extract relevant code chunks. - - Stored these chunks with their associated metadata to enable better context retrieval during RAG. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Parsing complex .po files with varied comment styles and ensuring correct association of usage metadata. - **Solution:** Created robust parsing scripts to handle different comment formats and verified chunk associations manually on sample files. - -- **Challenge:** Extracting meaningful code chunks via AST parsing while maintaining useful granularity. - **Solution:** Experimented with different AST traversal strategies and filters to optimize chunk size for retrieval. - ---- - -## Key Learnings - -- Gained deeper understanding of the internals of Music Blocks core files and their translation system. -- Improved skills with Babel AST parsing and metadata extraction techniques. -- Learned the importance of detailed metadata in enhancing RAG model retrieval accuracy. - ---- - -## Next Week’s Roadmap - -- Build a demo to showcase the RAG model's ability to answer Music Blocks-related queries with context from core files. -- Begin integrating metadata-enriched .po file chunks into the RAG database for improved translation string retrieval. -- Optimize chunking and metadata tagging strategy based on initial demo feedback. - ---- - -## Resources & References - -- **Music Blocks Repository:** [github.com/your-org/musicblocks](https://github.com/your-org/musicblocks) -- **Babel AST Docs:** https://babeljs.io/docs/en/babel-parser -- **RAG Model Concepts:** https://arxiv.org/abs/2005.11401 - ---- - -## Acknowledgments - -Thanks to my mentors and the DMP community for their guidance and support throughout this work. - ---- - -## Connect with Me - -- GitHub: [@aman-chadha](https://github.com/ac-mmi) -- Gmail: [aman.chadha.mmi@gmail.com](mailto:aman.chadha.mmi@gmail.com) - ---- diff --git a/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week02.md b/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week02.md deleted file mode 100644 index 4d3533a5..00000000 --- a/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week02.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "DMP '25 Week 02 Update by Aman Chadha" -excerpt: "Enhanced RAG output format with POS tagging and optimized code chunking for Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-06-16" -slug: "2025-06-16-dmp-25-aman-chadha-week02" -author: "@/constants/MarkdownFiles/authors/aman-chadha.md" -tags: "dmp25,sugarlabs,week02,aman-chadha" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 02 Progress Report by Aman Chadha - -**Project:** [JS Internationalization with AI Translation Support](https://github.com/sugarlabs/musicblocks/pull/4459) -**Mentors:** [Walter Bender](https://github.com/walterbender) -**Assisting Mentors:** *None this week* -**Reporting Period:** 2025-06-09 - 2025-06-16 - ---- - -## Goals for This Week - -- **Refactor RAG model output** to a structured dictionary format that includes part-of-speech (POS) tagging. -- **Optimize AST-based chunking** by limiting code context to 5 lines above and below translation usage, per mentor feedback. -- **Begin functional testing** of the updated RAG pipeline on real-world translation queries. - ---- - -## This Week's Achievements - -1. **RAG Output Enhancement** - - Refactored the Retrieval-Augmented Generation model to return results as structured dictionaries. - - Each entry now includes `msgid`, `msgstr`, source metadata, and the dominant part of speech, improving retrieval relevance. - -2. **Code Chunking Optimization** - - Reduced each extracted code chunk to include only 5 lines above and below the relevant `msgid` usage. - - This improves retrieval precision and avoids irrelevant surrounding code. - - Implemented using Babel’s AST traversal logic. - -3. **Initial Model Testing** - - Started testing the RAG model using sample translation queries. - - Observed noticeable improvements in answer context relevance due to cleaner chunks and richer metadata. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Integrating POS tagging meaningfully into the RAG data pipeline. - **Solution:** Designed a dictionary schema that includes the part-of-speech alongside translation metadata, and verified correctness using test entries. - -- **Challenge:** Tuning chunk granularity without losing contextual utility. - **Solution:** Followed mentor Walter’s advice to use fixed ±5 line windows, and manually verified semantic coherence of resulting chunks. - ---- - -## Key Learnings - -- Part-of-speech tagging can significantly improve the contextual strength of retrieved translations. -- Smaller, focused code chunks often result in better retrieval precision for RAG applications. -- Mentor feedback and collaborative iteration are key to refining both code structure and user outcomes. - ---- - -## Next Week's Roadmap - -- Integrate POS-tagged RAG responses into the full i18n fallback translation pipeline. -- Expand test coverage to include edge-case translations and re-used `msgid`s. -- Prepare an internal demo to show RAG-powered retrieval resolving contextually ambiguous translation strings. - ---- - -## Resources & References - -- **Repository:** [github.com/sugarlabs/musicblocks](https://github.com/sugarlabs/musicblocks) -- **RAG Concepts:** [arxiv.org/abs/2005.11401](https://arxiv.org/abs/2005.11401) -- **Babel Parser Docs:** [babeljs.io/docs/en/babel-parser](https://babeljs.io/docs/en/babel-parser) -- **spaCy POS Tagging:** [spacy.io/usage/linguistic-features#pos-tagging](https://spacy.io/usage/linguistic-features#pos-tagging) - ---- - -## Acknowledgments - -Thanks to my mentor Walter Bender for his guidance on optimizing chunking strategy and enriching the retrieval logic with linguistic features. - ---- - -## Connect with Me - -- GitHub: [@aman-chadha](https://github.com/ac-mmi) -- Gmail: [aman.chadha.mmi@gmail.com](mailto:aman.chadha.mmi@gmail.com) - ---- diff --git a/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week03.md b/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week03.md deleted file mode 100644 index 8debe535..00000000 --- a/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week03.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: "DMP '25 Week 03 Update by Aman Chadha" -excerpt: "Translated RAG-generated context strings, initiated batch processing, and planned for automated context regeneration" -category: "DEVELOPER NEWS" -date: "2025-06-23" -slug: "2025-06-23-dmp-25-aman-chadha-week03" -author: "@/constants/MarkdownFiles/authors/aman-chadha.md" -tags: "dmp25,sugarlabs,week03,aman-chadha" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 03 Progress Report by Aman Chadha - -**Project:** [JS Internationalization with AI Translation Support](https://github.com/sugarlabs/musicblocks/pull/4459) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/devinulibarri) -**Assisting Mentors:** *None this week* -**Reporting Period:** 2025-06-17 – 2025-06-23 - ---- - -## Goals for This Week - -- Translate a sample set of RAG-generated context strings using AI-powered tools. -- Share Japanese translation variants (Kana and Kanji) with mentors for review. -- Begin building a batch-processing workflow to generate context for all 1535 msgid entries in the .po files. -- Plan an update pipeline to regenerate context for newly added or reused translation strings automatically. - ---- - -## This Week’s Achievements - -1. **Translation of RAG-Generated Contexts** - - Translated ~70 RAG-generated context descriptions using DeepL. - - Shared English and Japanese translations with mentors Walter and Devin for review. - - For Japanese, provided both **Kana** and **Kanji** variants to ensure localization accuracy. - -2. **Batch Processing Pipeline Development** - - Initiated work on a batch-processing system to automate RAG context generation for all 1535 msgid entries in the translation .po file. - - This will drastically reduce manual overhead and improve coverage. - -3. **Planning for Context Maintenance Workflow** - - Designed a future-proofing plan to automatically detect newly added or reused msgids in pull requests. - - Began outlining a GitHub Actions-based workflow to regenerate context chunks when changes are merged into the repo. - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Japanese localization required thoughtful distinction between script types (Kana vs Kanji). - **Solution:** Generated both forms using translation tools and consulted native guidance to ensure cultural appropriateness. - -- **Challenge:** Scaling RAG context generation to 1500+ entries without losing efficiency. - **Solution:** Started designing a batch system to streamline the entire generation process and set up hooks for automation in future updates. - ---- - -## Key Learnings - -- Multi-language support requires nuanced translation strategies, especially for languages like Japanese. -- Batch automation is essential when working with large-scale i18n datasets and AI-generated content. -- Proactive planning for long-term maintenance helps keep i18n tooling relevant as the codebase evolves. - ---- - -## Next Week’s Roadmap - -- Complete batch-processing implementation for generating RAG context for all msgids. -- Add persistence/storage layer to cache generated results and avoid recomputation. -- Set up a GitHub workflow for regenerating context on new PRs that modify or add translation strings. - ---- - -## Resources & References - -- **Music Blocks Repository:** [github.com/sugarlabs/musicblocks](https://github.com/sugarlabs/musicblocks) -- **DeepL Translator API:** [deepl.com/docs-api](https://www.deepl.com/docs-api) -- **GitHub Actions Docs:** [docs.github.com/actions](https://docs.github.com/actions) -- **RAG Concepts:** [arxiv.org/abs/2005.11401](https://arxiv.org/abs/2005.11401) - ---- - -## Acknowledgments - -Thanks to mentors Walter Bender and Devin Ulibarri for their ongoing guidance, especially on translation validation and workflow design. - ---- diff --git a/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week04.md b/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week04.md deleted file mode 100644 index 2ae1d29b..00000000 --- a/src/constants/MarkdownFiles/posts/dmp-25-AmanChadha-week04.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: "DMP '25 Week 04 Update by Aman Chadha" -excerpt: "Completed context generation for all UI strings and submitted Turkish translations using DeepL with RAG-generated context" -category: "DEVELOPER NEWS" -date: "2025-06-30" -slug: "2025-06-30-dmp-25-aman-chadha-week04" -author: "@/constants/MarkdownFiles/authors/aman-chadha.md" -tags: "dmp25,sugarlabs,week04,aman-chadha" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 04 Progress Report by Aman Chadha - -**Project:** [JS Internationalization with AI Translation Support](https://github.com/sugarlabs/musicblocks/pull/4459) -**Mentors:** [Walter Bender](https://github.com/walterbender), [Devin Ulibarri](https://github.com/devinulibarri) -**Reporting Period:** 2025-06-24 – 2025-06-30 - ---- - -## Goals for This Week - -- Complete RAG-based context generation for **all UI strings** in the `.po` file. -- Translate the Turkish `.po` file using DeepL with generated context. -- Share Turkish translation with mentors for review and validation of context effectiveness. - ---- - -## This Week’s Achievements - -1. **Full Context Generation Completed** - - Successfully generated context for all 1,536 active `msgid` entries using the RAG (Retrieval-Augmented Generation) model. - - Ensured each UI string now has an associated contextual description to guide translators. - -2. **Turkish Translation via DeepL with Context** - - Used the DeepL API to translate the Turkish `.po` file, injecting the RAG-generated context for each `msgid`. - - This serves as a real-world test to evaluate how well contextual guidance improves translation accuracy and usability. - - Currently awaiting feedback on the quality of Turkish translations to assess the effectiveness of the context-driven approach. - ---- - -## Challenges & How I Addressed Them - -- **Challenge:** Integrating RAG-generated context into `.po` translation pipeline. - **Solution:** Adapted the `.po` processing script to pair each `msgid` with its context before sending it to DeepL, ensuring translators benefit from semantic clarity. - -- **Challenge:** Validating quality of translations in a language I do not speak. - **Solution:** Coordinated with mentors to review Turkish output and identify whether contextual enrichment improved translation fidelity. - ---- - -## Key Learnings - -- Contextual guidance significantly strengthens AI-driven translation quality, especially for UI-specific phrases. -- Systematic pairing of context with each string allows scalable improvements across languages. -- Human review remains crucial to validate AI-generated translations and refine context generation methods. - ---- - -## Next Week’s Roadmap - -- Collect and analyze mentor feedback on the Turkish `.po` file. -- Fine-tune the RAG context generation logic based on observed shortcomings, if any. -- Generalize the context-injection workflow for use with other languages (e.g., Spanish, French). -- Begin documenting the context generation + translation pipeline for future contributors. - ---- - -## Resources & References - -- **Music Blocks Repository:** [github.com/sugarlabs/musicblocks](https://github.com/sugarlabs/musicblocks) -- **DeepL Translator API:** [deepl.com/docs-api](https://www.deepl.com/docs-api) -- **GitHub Actions Docs:** [docs.github.com/actions](https://docs.github.com/actions) -- **RAG Concepts:** [arxiv.org/abs/2005.11401](https://arxiv.org/abs/2005.11401) - ---- - -## Acknowledgments - -Thanks to mentors Walter Bender and Devin Ulibarri for their feedback, review assistance, and continued support in improving translation workflows. - ---- diff --git a/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week01.md b/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week01.md deleted file mode 100644 index e85da8dc..00000000 --- a/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week01.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: "DMP '25 Week 01 Update by Anvita Prasad" -excerpt: "Initial research and implementation of Music Blocks tuner feature" -category: "DEVELOPER NEWS" -date: "2025-06-08" -slug: "2025-06-08-DMP-25-AnvitaPrasad-week01" -author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" -tags: "dmp25,sugarlabs,week01,AnvitaPrasad" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 01 Progress Report by Anvita Prasad - -**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) -**Mentors:** [Walter Bender](https://github.com/walterbender) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-02 - 2025-06-08 - ---- - -## Goals for This Week - -- **Goal 1:** Update Tone.js to the latest version -- **Goal 2:** Begin tuner implementation with pitch detection -- **Goal 3:** Create basic tuner visualization - ---- - -## This Week's Achievements - -1. **Updated Tone.js Library** - - Successfully upgraded from version 15.0.4 to 15.1.22 - - Verified compatibility with existing codebase - -2. **Implemented Pitch Detection** - - Integrated YIN algorithm for pitch detection - - Established foundation for note identification - -3. **Created Basic Tuner Interface** - - Implemented 11-segment tuner display - - Added initial cents adjustment UI - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Understanding complex audio processing concepts - **Solution:** Studied Web Audio API documentation and experimented with example code - ---- - -## Key Learnings - -- Gained familiarity with Tone.js API and audio processing -- Learned about pitch detection algorithms and their implementation - ---- - -## Next Week's Roadmap - -- Complete tuner implementation with accurate visualization -- Implement cents adjustment calculations -- Add fine-tuning to pitch detection system -- Test with various audio sources -- Write Week 02 blog post summarizing progress and learnings - ---- - -## Resources & References - -- **Web Audio Resources:** [MDN Web Audio API Guide](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) -- **Pitch Detection:** [PitchDetect Example](https://github.com/cwilso/pitchdetect) -- **Online Tuner Reference:** [Musicca's Online Tuner Guide](https://www.musicca.com/tuner) - ---- - -## Acknowledgments - -Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week02.md b/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week02.md deleted file mode 100644 index 0ceec86f..00000000 --- a/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week02.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "DMP '25 Week 02 Update by Anvita Prasad" -excerpt: "Research and design of tuner visualization system and cents adjustment UI" -category: "DEVELOPER NEWS" -date: "2025-06-15" -slug: "2025-06-15-DMP-25-AnvitaPrasad-week02" -author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" -tags: "dmp25,sugarlabs,week02,AnvitaPrasad" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 02 Progress Report by Anvita Prasad - -**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) -**Mentors:** [Walter Bender](https://github.com/walterbender) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-09 - 2025-06-15 - ---- - -## Goals for This Week -- **Goal 1:** Design dual-mode tuner interface -- **Goal 2:** Research and prototype cents adjustment UI -- **Goal 3:** Investigate temperament systems and EDO implementations -- **Goal 4:** Implement visual feedback system for pitch detection - ---- - -## This Week's Achievements - -1. **Researched Dual-Mode Tuner Design** - - Analyzed requirements for two proposed tuning modes: - - Specific Target Pitch mode with fixed reference - - Arbitrary mode with dynamic ±50 cents range detection - - Started working on UI mockups for both modes - - Researching effective visual feedback systems for pitch deviation - -2. **Implemented Initial Cents Adjustment Feature** - - Created basic manual cents adjustment UI - - Exploring alternative UI approaches for better user experience - - Studying various tuner implementations for inspiration - -3. **Developed Tuner Visualization System** - - Implemented center-outward segment lighting system - - Left/right segments indicate flat/sharp notes respectively - - Number of lit segments shows pitch deviation magnitude - -4. **Pitch Detection System Research** - - Studied advanced pitch detection methodologies - - Researched FFT spectrum analysis and phase information evaluation - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Difficulty in accurately detecting pitch in real-time - **Solution:** Researched and implemented better audio processing algorithms with help from mentor feedback - -- **Challenge:** Making the tuner interface user-friendly and responsive - **Solution:** Studied existing tuner applications and simplified the visual feedback system - ---- - -## Key Learnings -- Gained deep understanding of Equal Divisions of the Octave (EDO) systems and their implementation challenges -- Learned about various temperament systems (Equal, Just, Werckmeister, Kirnberger) -- Studied advanced audio processing techniques including FFT window optimization and spectrum phase analysis -- Researched UX patterns for precise musical instrument tuning interfaces -- Explored different approaches to visual feedback systems for micro-pitch detection - ---- - -## Next Week's Roadmap -- Complete tuner implementation with accurate visualization -- Finalize and implement the selected cents adjustment UI design -- Write Week 03 blog post summarizing progress and learnings - ---- - -## Resources & References -- **EDO & Tuning Systems:** [Ableton's Guide to EDO Tunings](https://tuning.ableton.com/edo/intro-to-edo/) -- **Online Tuner Reference:** [Musicca's Online Tuner Guide](https://www.musicca.com/tuner) -- **Pitch Detection Implementation:** [PitchDetect JavaScript Implementation](https://github.com/cwilso/PitchDetect/blob/main/js/pitchdetect.js) -- **Research Reference:** [F-Droid Tuner Implementation](https://f-droid.org/en/packages/de.moekadu.tuner/) - ---- - -## Acknowledgments -Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support. - ---- diff --git a/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week05.md b/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week05.md deleted file mode 100644 index 99e54ba4..00000000 --- a/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week05.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "DMP '25 Week 05 Update by Anvita Prasad" -excerpt: "Implementation of manual cent adjustment interface and mode-specific icons for the tuner system" -category: "DEVELOPER NEWS" -date: "2025-07-06" -slug: "2025-07-06-DMP-25-AnvitaPrasad-week05" -author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" -tags: "dmp25,sugarlabs,week05,AnvitaPrasad" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 05 Progress Report by Anvita Prasad - -**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) -**Mentors:** [Walter Bender](https://github.com/walterbender) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-06-30 - 2025-07-06 - ---- - -## Goals for This Week -- **Goal 1:** Design and implement a slider for manual cent adjustment -- **Goal 2:** Develop functionality for cent adjustment system -- **Goal 3:** Design and implement mode-specific icons for the tuner interface - - ---- - -## This Week's Achievements - -1. **Mode-Specific Icon Design and Implementation** - - Created distinctive icons for both tuning modes - - Successfully integrated icons into the tuner interface - - Ensured visual consistency with existing Music Blocks design language - -2. **Manual Cent Adjustment Interface Redesign** - - Transitioned from pie menu to slider-based interface - - Implemented basic slider UI for cent adjustment - - Designed interface to accommodate ±50 cents range - - Optimized for both recorded and uploaded samples through the sampler - -3. **Cent Adjustment System Development** - - Implementing core functionality for precise pitch adjustment - - Developed system to handle cent adjustments within ±50 range - - Created framework for real-time pitch modification - -4. **Integration and Testing** - - Successfully integrated new components with existing tuner system - - Conducted initial testing of slider functionality - - Verified icon visibility and clarity in different modes - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Maintaining precise control over cent adjustments while ensuring smooth slider operation -- **Solution:** Implemented a custom scaling algorithm and added intermediate value snapping for better control - - ---- - -## Key Learnings -- Gained deeper understanding of real-time audio processing in web applications -- Discovered best practices for handling micro-pitch adjustments in digital audio systems -- Enhanced knowledge of Web Audio API's capabilities and limitations - ---- - -## Next Week's Roadmap -- Conduct extensive testing with various audio sources and instruments -- Process free/open samples from identified sources -- Design basic categorization system for samples -- Write Week 06 blog post summarizing progress and learnings - ---- - -## Resources & References -- **Audio Processing:** [Web Audio API Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) -- **Cent Calculation:** [Cents to Frequency Ratio Calculator](https://www.sengpielaudio.com/calculator-centsratio.htm) -- **Musical Tuning:** [Musical Acoustics - Cents and Frequency Ratios](https://newt.phys.unsw.edu.au/jw/notes.html) -- **UI Components:** Referenced existing Music Blocks slider implementations for consistency - ---- - -## Acknowledgments -Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week06.md b/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week06.md deleted file mode 100644 index d15a85fc..00000000 --- a/src/constants/MarkdownFiles/posts/dmp-25-AnvitaPrasad-week06.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: "DMP '25 Week 06 Update by Anvita Prasad" -excerpt: "Improve Synth and Sample Feature for Music Blocks" -category: "DEVELOPER NEWS" -date: "2025-07-13" -slug: "2025-07-13-DMP-25-AnvitaPrasad-week06" -author: "@/constants/MarkdownFiles/authors/anvita-prasad.md" -tags: "dmp25,sugarlabs,week06,AnvitaPrasad,midterm" -image: "assets/Images/c4gt_DMP.png" ---- - -<!-- markdownlint-disable --> - -# Week 06 Progress Report by Anvita Prasad - -**Project:** [Music Blocks - Improve Synth and Sample Features](https://github.com/sugarlabs/musicblocks/issues/4539) -**Mentors:** [Walter Bender](https://github.com/walterbender) -**Assisting Mentors:** [Devin Ulibarri](https://github.com/pikurasa) -**Reporting Period:** 2025-07-07 - 2025-07-13 - ---- - -## Goals for This Week -- **Goal 1:** Implement manual cent adjustment functionality in the sampler widget -- **Goal 2:** Ensure cent adjustments persist when saving samples -- **Goal 3:** Research methods for manual cent adjustment implementation -- **Goal 4:** Collect SVG icons for the set instrument widget -- **Goal 5:** Design basic categorization system for samples - ---- - -## This Week's Achievements - -1. **Cent Adjustment Persistence Implementation** - - Extended the CUSTOMSAMPLES array to include cent adjustment values - - Modified _addSample function to maintain backward compatibility - - Updated __save function to include cent adjustment in block properties - - Enhanced _updateBlocks to display cent adjustments in block text (e.g., "C4 +10¢") - -2. **Playback Rate Calculation System** - - Implemented the mathematical formula for converting cents to playback rate - - Applied consistent calculation throughout the codebase (playbackRate = Math.pow(2, cents/1200)) - - Ensured accurate pitch modification across all sample playback scenarios - -3. **Synth Integration** - - Modified _createSampleSynth function to store cent adjustments with samples - - Updated trigger function to apply adjustments to playback rate during sample playback - - Created framework for real-time pitch modification during performance - -4. **Instrument Organization and Visualization** - - Collected SVG icons for each instrument and instrument family - - Designed a hierarchical structure to better organize the set instruments widget - - Created a more intuitive categorization system for instrument selection - - Improved visual navigation through instrument families - ---- - -## Challenges & How I Overcame Them - -- **Challenge:** Persisting Cent Adjustment Information - **Solution:** In the previous week, I had implemented cent adjustments by modifying the playback rate in real-time, but this information wasn't being stored with the sample. This meant that when a user saved a sample after making cent adjustments, the adjustments were lost, creating inconsistency in musical compositions. I researched two main approaches: storing notes as floating-point MIDI values (e.g., 60.1 for C4+10¢) or storing integer MIDI notes and cent adjustments separately. I chose the second approach for better compatibility with Music Blocks' existing codebase, clearer data representation, and easier UI integration. I'm still testing this implementation to ensure it works correctly across all use cases. - -- **Challenge:** Modifying the Sample Data Structure - **Solution:** I carefully extended the CUSTOMSAMPLES array to include the cent adjustment value while ensuring backward compatibility. This required precise modifications to several core functions that interact with the sample data structure. - ---- - -## Key Learnings -- Audio Processing Fundamentals: Deepened understanding of how cent adjustments affect pitch perception and the mathematical relationship between cents and playback rate. -- Data Persistence Strategies: Learned different approaches to storing and retrieving fine-grained musical parameters, and the trade-offs between integrated vs. separate storage models -- DOM Manipulation for Audio UI: Gained experience creating responsive audio controls that provide visual feedback while manipulating sound parameters in real-time -- Code Refactoring Best Practices: Developed skills in modifying existing functionality while maintaining backward compatibility, especially in a complex music programming environment -- Tone.js Audio API: Enhanced understanding of Tone.js's Sampler implementation and how to manipulate playback parameters like playback rate for pitch adjustments - ---- - -## Midterm Evaluation Summary (Weeks 01–06) - -Over the past six weeks, I've made significant progress on improving Music Blocks' synth and sample features, focusing on enhancing the tuning system and implementing micro-pitch adjustments. I've successfully completed the development of a comprehensive dual-mode tuner system that provides precise pitch feedback and visualization. Additionally, I've implemented a manual cent adjustment feature that allows for microtonality exploration and fine-tuning of samples. These enhancements significantly expand Music Blocks' capabilities for musical education, enabling students to explore pitch relationships beyond standard Western tuning systems and providing educators with powerful tools for teaching advanced musical concepts. - -### Technical Achievements - -1. **Audio Foundation Improvements** - - Updated Tone.js library from version 15.0.4 to 15.1.22 - - Integrated YIN algorithm for accurate pitch detection - - Implemented low-pass filtering to handle high-frequency noise - - Enhanced pitch detection accuracy using parabolic interpolation - -2. **Tuner System Development** - - Created comprehensive dual-mode tuner interface: - - Chromatic mode that automatically finds closest pitch - - Target pitch mode with fixed reference point - - Implemented 11-segment visualization system with center-outward lighting - - Added clear visual feedback for cent deviation - - Designed mode-specific icons and toggle interface - -3. **Cent Adjustment System** - - Evolved from initial pie menu design to more efficient slider interface - - Implemented ±50 cents range adjustment capability - - Created framework for real-time pitch modification - - Developed system to store and apply cent adjustments to samples - - Extended data structures to maintain cent adjustment information - -4. **Integration and Testing** - - Conducted extensive testing with various audio sources - - Created test suite for tuner accuracy verification - - Optimized signal processing for better performance - - Ensured backward compatibility throughout implementation - -### Educational and Creative Impact - -These improvements significantly enhance Music Blocks' capabilities for musical education and exploration: - -- **Microtonality Access**: Students can now explore pitches between standard Western notes, opening doors to world music traditions and experimental composition -- **Improved Accuracy**: The enhanced tuner provides precise feedback for instrument tuning and vocal training -- **Educational Value**: Visual feedback systems help students understand pitch relationships and develop better ear training -- **Creative Possibilities**: Cent adjustments enable more expressive performances and composition with subtle pitch variations - -### Final Thoughts - -The first half of this project has established a solid foundation for Music Blocks' enhanced audio capabilities. The dual-mode tuner and cent adjustment systems provide both technical accuracy and user-friendly interfaces for students and educators. These features have significantly expanded Music Blocks' capacity for musical exploration beyond standard Western tuning. Moving forward, I'll focus on sample organization and multiple sample functionality to further enhance the expressiveness and educational value of the platform. - ---- - -## Next Week's Roadmap -- Implement the basic categorization system for samples -- Process free/open samples from identified sources -- Work on handling multiple samples -- Test the manual cent adjustment feature and finalise the approach -- Write Week 07 blog post summarizing progress and learnings - ---- - -## Resources & References -- **Audio Processing:** [Web Audio API Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) -- **Cent Calculation:** [Cents to Frequency Ratio Calculator](https://www.sengpielaudio.com/calculator-centsratio.htm) -- **Musical Tuning:** [Musical Acoustics - Cents and Frequency Ratios](https://newt.phys.unsw.edu.au/jw/notes.html) -- **Tone.js Documentation:** [Tone.js Sampler](https://tonejs.github.io/docs/14.7.77/Sampler) -- **Audio Sample Processing:** [Microtonality in Digital Audio Workstations](https://www.researchgate.net/publication/327567188_Microtonality_and_the_DAW_A_Design_Study) - ---- - -## Acknowledgments -Thank you to my mentors, the Sugar Labs community, and fellow contributors for ongoing support. - ---- \ No newline at end of file diff --git a/src/constants/ProductsData.ts b/src/constants/ProductsData.ts deleted file mode 100644 index 4275a2a5..00000000 --- a/src/constants/ProductsData.ts +++ /dev/null @@ -1,30 +0,0 @@ -export type ProductType = { - name: string; - description: string; - colors: Record<string, string>; // Image URLs mapped by color names - link: string; // External purchase link -}; - -export const products: ProductType[] = [ - { - name: 'Classic Cotton T-Shirt', - description: - 'Support Sugar Labs®—a US-based 501(c)(3) nonprofit empowering youth through technology education—with this premium cotton t-shirt, designed for comfort and durability.', - colors: { - blue: 'assets/Products/sugarTshirtBlue.jpeg', - white: 'assets/Products/sugarTshirtWhite.jpeg', - green: 'assets/Products/sugarTshirtGreen.jpeg', - purple: 'assets/Products/sugarTshirtPurple.jpeg', - }, - link: 'https://www.bonfire.com/store/sugar-labs-merch/', // Purchase link - }, - { - name: 'SugarLabs USB', - description: - 'Easily install Fedora Sugar On A Stick (SOAS) to your device directly from this USB flash drive. The Fedora SOAS on this USB drive is for Intel and AMD x86_64 systems.', - colors: { - white: 'assets/Products/sugarlabsUsb.jpeg', - }, - link: 'https://www.usbmemorydirect.com/store/novelty/sugarlabs/', // Purchase link - }, -]; diff --git a/src/constants/Stats.ts b/src/constants/Stats.ts deleted file mode 100644 index 0a1bd8b3..00000000 --- a/src/constants/Stats.ts +++ /dev/null @@ -1,83 +0,0 @@ -import kidlaptop from '/assets/Stats/KidsWhoseLife.svg'; -import studentsCollaborating from '/assets/Stats/ProjectsForTeaching.svg'; -import studentMobile from '/assets/Stats/ProblemSolvingTasks.svg'; -import activity from '/assets/Stats/ActivitiesDownloaded.svg'; -import language from '/assets/Stats/Languages.svg'; -import mentorsTeaching from '/assets/Stats/MentorsHelping.svg'; -import apostrophie from '/assets/Stats/quote-icon.svg'; -import leftHeart from '/assets/Stats/HeartLeft.svg'; -import rightHeart from '/assets/Stats/HeartRight.svg'; -import faq from '/assets/Images/faq.png'; - -export const stats = { - kidlaptop, - studentsCollaborating, - studentMobile, - activity, - language, - mentorsTeaching, - apostrophie, - leftHeart, - rightHeart, - faq, -}; - -export const statisticsData = [ - { - title: - 'Kids whose lives have been enriched by using the Sugar Learning Platform.', - value: '3,000,000+', - imageSrc: stats.kidlaptop, - imageAlt: 'Student with laptop', - gradient: 'from-green-600 to-green-700', - bgColor: 'bg-green-50', - borderColor: 'border-green-200', - }, - { - title: - 'Projects for teaching and learning created by Sugar Labs students and teachers.', - value: '344+', - imageSrc: stats.studentsCollaborating, - imageAlt: 'Students collaborating', - gradient: 'from-red-600 to-red-700', - bgColor: 'bg-red-50', - borderColor: 'border-red-200', - }, - { - title: 'Problem-solving tasks completed by students ages 13-17.', - value: '1,450+', - imageSrc: stats.studentMobile, - imageAlt: 'Student with mobile device', - gradient: 'from-green-600 to-green-700', - bgColor: 'bg-green-100', - borderColor: 'border-green-300', - }, - { - title: 'Activities Downloaded', - value: '11,531,321+', - imageSrc: stats.activity, - imageAlt: 'Activity icon', - gradient: 'from-yellow-600 to-yellow-700', - bgColor: 'bg-yellow-50', - borderColor: 'border-yellow-200', - }, - { - title: 'Languages our educational software has been translated into', - value: '170', - imageSrc: stats.language, - imageAlt: 'Language icon', - gradient: 'from-blue-600 to-blue-700', - bgColor: 'bg-blue-50', - borderColor: 'border-blue-200', - }, - { - title: - 'Mentors helping youth learn in programs like Google Code-In (GCI) and Google Summer of Code', - value: '55+', - imageSrc: stats.mentorsTeaching, - imageAlt: 'Mentors teaching', - gradient: 'from-red-600 to-red-700', - bgColor: 'bg-red-100', - borderColor: 'border-red-300', - }, -]; diff --git a/src/constants/Testimonials.ts b/src/constants/Testimonials.ts deleted file mode 100644 index 2339fa77..00000000 --- a/src/constants/Testimonials.ts +++ /dev/null @@ -1,63 +0,0 @@ -export const testimonials = [ - { - name: 'Student at Soham Shubham Science', - username: 'Soham Shubham Science', - body: 'Music Blocks is a programming environment for children interested in music and graphics. It expands upon Turtle Blocks by adding a collection of features relating to pitch and rhythm.', - img: 'https://subhamgroupofinstitutions.com/wp-content/uploads/2022/08/Subham_logo-1-removebg-preview.png', - }, - { - name: 'Richard Hermann', - username: - 'Richard Hermann, PhD, Prof. of Music Theory and Composition, University of New Mexico', - body: 'I think Music Blocks will inspire many young folks to become programmers, mathematicians, composers, and music theorists. It will also provide important experiences to other young folk who pursue other fields. You are to be congratulated on your efforts.', - img: 'https://www.richardhermann.net/_Media/rhmh-tentrock_med.jpeg', - }, - { - name: 'Riya Lohia', - username: 'Riya Lohia GSoc 2018 Student', - body: 'I would like to thank my mentors Walter Bender and Devin Ulibarri for their constant guidance and motivation...', - img: 'https://avatar.vercel.sh/james', - }, - { - name: 'Sourabha G.', - username: 'Sourabha G. GSoC 2021 Student', - body: 'This summer was super fun and filled with learning! I enjoyed testing over 60+ activities with kids to get first-hand feedback which had a positive impact in the way they approach problems...', - img: 'https://avatar.vercel.sh/james', - }, - { - name: 'LinuxInsider', - username: 'LinuxInsider', - body: 'Fedora-Based Sugar on a Stick Is One Sweet Desktop.', - img: 'https://avatar.vercel.sh/james', - }, - { - name: 'Harshit Verma', - username: 'Harshit Verma', - body: 'Contribution to Sugar Labs has been an incredible rewarding experience. It has not only helped me grow as a developer but also given me confidence to work on real world projects. I’m excited about what’s next in my open source journey, and I can’t wait to continue learning and contributing!', - img: 'https://miro.medium.com/v2/resize:fill:44:44/1*devzHlZAKt4fVu5Cg0eN6w.png', - }, - { - name: 'Om Santosh Suneri', - username: 'Om Santosh Suneri', - body: 'My first open source contribution was challenging but incredibly rewarding. If you’re hesitant about contributing, just dive in. Find a project you love, pick an issue, and start exploring.Who knows? Your first PR might be just around the corner.', - img: 'https://miro.medium.com/v2/da:true/resize:fill:44:44/0*975x0N6-dYtP01Y7', - }, - { - name: 'Vipul Gupta', - username: 'Vipul Gupta', - body: 'Sugar Labs excelled all my expectations of how an open-source community would be like. The work I did during the course of the program would sure benefit the community. But more importantly, from day one, I felt to be working for something much bigger than myself.', - img: 'https://miro.medium.com/v2/resize:fill:44:44/1*QK0Aauitgk6kBBB6XpX98A.jpeg', - }, - { - name: 'Sam Parkinson', - username: 'Sam Parkinson, Google Code-in grand prize winner', - body: "GCI was truly something that changed my life. I went from being an open source newbie to being able to contribute to really cool projects, thanks to the amazing GCI and Sugar Labs communities. It's something that I would recommend any young programmer consider doing. Participating in GCI is something that can make dreams come true.", - img: 'https://avatar.vercel.sh/james', - }, - { - name: 'Riya J', - username: 'Riya J. GSoC 2023 Student', - body: 'I learned a lot during the whole summer especially about backward compatibility when I worked on Sugar, which is a free/libre open-source software learning platform for children. I would like to thank my mentors, Chihurumnaya Ibiam and Sourabha Ganesh who provided constant support whenever I faced any issue. Looking forward to contributing more to Open Source!', - img: 'https://media.licdn.com/dms/image/v2/D5603AQGfK0K2z8gjMg/profile-displayphoto-shrink_100_100/B56ZR54oTdHwAY-/0/1737211676388?e=1749686400&v=beta&t=Kk7H2ex_3Vzmuw69QRiR55ZuXftrd4n60xRUFTbeDGo', - }, -]; diff --git a/src/constants/TryCardData.ts b/src/constants/TryCardData.ts deleted file mode 100644 index ae08f30f..00000000 --- a/src/constants/TryCardData.ts +++ /dev/null @@ -1,193 +0,0 @@ -import MusicBlocksImg from '/assets/Cards/MusicBlocks.png'; -import TurtleBlocksImg from '/assets/Cards/TurtleBlocks.png'; -import SugarizerImg from '/assets/Cards/Sugarizer.png'; -import BootableDriveImg from '/assets/Cards/BootableDrive.png'; -import DesktopInitializationImg from '/assets/Cards/DesktopInitialization.png'; -import TrisquelImg from '/assets/Cards/Trisquel.svg'; -import RaspberryPiImg from '/assets/Cards/RaspberryPi.png'; -import FlatHubImg from '/assets/Cards/Flathub.png'; -import Finance from '/assets/Cards/activity-finance.svg'; -import Maze from '/assets/Cards/activity-maze.svg'; -import Measure from '/assets/Cards/activity-measure.svg'; -import Turtle3D from '/assets/Cards/activity-turtle3d.svg'; -import Words from '/assets/Cards/activity-words.svg'; -import Ruler from '/assets/Cards/activity-ruler.svg'; -import StarChart from '/assets/Cards/activity-star-chart.svg'; -import Recall from '/assets/Cards/activity-recall.svg'; -import Physics from '/assets/Cards/activity-physics.svg'; - -interface CardDataType { - title: string; - description: string; - tryNowText: string; - tryNowHref: string; - learnMoreText: string; - learnMoreHref: string; - imagePath: string; - gradientClass: string; -} - -export const TryCardData: CardDataType[] = [ - { - title: 'Music Blocks', - description: - 'Create musical code with the browser-based visual programming language Music Blocks', - tryNowText: 'Try Music Blocks now!', - tryNowHref: 'https://musicblocks.sugarlabs.org/', - learnMoreText: 'Learn more about Music Blocks', - learnMoreHref: '/musicblocks', - imagePath: MusicBlocksImg, - gradientClass: 'bg-gradient-to-r from-blue-700 to-blue-500', - }, - { - title: 'Turtle Blocks', - description: - 'Explore math and computation through beautiful, artful and creative geometry.', - tryNowText: 'Try Turtle Blocks now!', - tryNowHref: 'https://turtle.sugarlabs.org/', - learnMoreText: 'Learn more about Turtle Blocks', - learnMoreHref: '/turtleblocks', - imagePath: TurtleBlocksImg, - gradientClass: 'bg-gradient-to-r from-pink-600 to-blue-500', - }, - { - title: 'Try now on any device with Sugarizer.', - description: - 'Get a taste of Sugar with Sugarizer, which opens in your browser with no installation.', - tryNowText: 'Try Sugarizer now!', - tryNowHref: 'https://try.sugarizer.org/', - learnMoreText: 'Learn more about Sugarizer', - learnMoreHref: '/sugarizer', - imagePath: SugarizerImg, - gradientClass: 'bg-gradient-to-r from-yellow-400 to-green-500', - }, - { - title: 'Desktop/laptop bootable drive', - description: - 'With Sugar a Stick (SOAS), you can experience the full Sugar Learning Platform on any computer at any time from a bootable thumb drive', - tryNowText: 'Try Bootable drive now!', - tryNowHref: 'https://fedoraproject.org/spins/soas/download/', - learnMoreText: 'Learn more about Bootable Drive', - learnMoreHref: '/bootablesoas', - imagePath: BootableDriveImg, - gradientClass: 'bg-gradient-to-r from-gray-900 to-gray-400', - }, - { - title: 'Desktop/laptop installation', - description: - 'Sugar Learning platform can be installed as a full operating system on ost desktop and laptop computers.', - tryNowText: 'Try Desktop Installation now!', - tryNowHref: 'https://fedoraproject.org/spins/soas/download/', - learnMoreText: 'Learn more about Installation', - learnMoreHref: '/bootablesoas', - imagePath: DesktopInitializationImg, - gradientClass: 'bg-gradient-to-r from-blue-700 to-blue-500', - }, - { - title: 'Try Trisquel for full freedom', - description: - 'Get all the benefits of a bootable/installation frive on the fully free and well maintained Trisquel distro.', - tryNowText: 'Try Trisquel now!', - tryNowHref: 'https://trisquel.info/en/download', - learnMoreText: 'Learn more about Trisquel', - learnMoreHref: '/trisquel', - imagePath: TrisquelImg, - gradientClass: 'bg-gradient-to-r from-blue-700 to-blue-900', - }, - { - title: 'Try Sugar on Raspberry Pi', - description: 'The full Sugar environment on a Raspberry P.(RPk)', - tryNowText: 'Try Raspberry Pi now!', - tryNowHref: 'https://wiki.sugarlabs.org/go/Raspbian', - learnMoreText: 'Learn more about Raspberry Pi', - learnMoreHref: '/raspberry', - imagePath: RaspberryPiImg, - gradientClass: 'bg-gradient-to-r from-red-600 to-green-500', - }, - { - title: 'Convenient installation via Flatpak', - description: - 'Create musical code with the browser based visual programming language Music Blocks', - tryNowText: 'Try Flatpak now!', - tryNowHref: 'https://flathub.org/apps/search?q=sugar%20labs', - learnMoreText: 'Learn more about Flatpak', - learnMoreHref: '/flathub', - imagePath: FlatHubImg, - gradientClass: 'bg-gradient-to-r from-gray-400 to-gray-900', - }, -]; - -export const Activities = [ - { - title: 'Finance', - description: 'Roleplay with money', - icon: Finance, - buttonText: 'Get Finance', - href: 'https://activities.sugarlabs.org/en-US/sugar/addon/4040', - version: 'v3', - }, - { - title: 'Maze', - description: 'Have fun with progressive challenges', - icon: Maze, - buttonText: 'Get Maze', - href: 'https://activities.sugarlabs.org/en-US/sugar/addon/4727', - version: 'v3', - }, - { - title: 'Measure', - description: 'Use your computer to measure things in the physical world', - icon: Measure, - buttonText: 'Get Measure', - href: 'https://activities.sugarlabs.org/en-US/sugar/addon/4197', - version: 'v3', - }, - { - title: 'TurtleBlocks3D', - description: 'Turtle Blocks? But in three dimensions!', - icon: Turtle3D, - buttonText: 'Get TurtleBlocks3D', - href: 'https://activities.sugarlabs.org/en-US/sugar/addon/4757', - version: 'v3', - }, - { - title: 'Words', - description: 'Compose and share your ideas', - icon: Words, - buttonText: 'Get Words', - href: 'https://activities.sugarlabs.org/en-US/sugar/addon/4315', - version: 'v3', - }, - { - title: 'Ruler', - description: 'Measure and explore math', - icon: Ruler, - buttonText: 'Get Ruler', - href: 'https://activities.sugarlabs.org/en-US/sugar/addon/4192', - version: 'v3', - }, - { - title: 'StarChart', - description: 'Explore numbers and information in charts', - icon: StarChart, - buttonText: 'Get StarChart', - href: 'https://activities.sugarlabs.org/en-US/sugar/addon/4300', - version: 'v3', - }, - { - title: 'Recall', - description: 'Test your memory with this fun game', - icon: Recall, - buttonText: 'Get Recall', - href: 'https://v4.activities.sugarlabs.org/app/org.sugarlabs.RecallActivity.html', - version: 'v4', - }, - { - title: 'Physics', - description: 'Physical world simulator and playground', - icon: Physics, - buttonText: 'Get Physics', - href: 'https://activities.sugarlabs.org/en-US/sugar/addon/4193', - version: 'v3', - }, -]; diff --git a/src/constants/TryMore3D.ts b/src/constants/TryMore3D.ts deleted file mode 100644 index 65e3dd6b..00000000 --- a/src/constants/TryMore3D.ts +++ /dev/null @@ -1,93 +0,0 @@ -export const tryMoreActivities = [ - { - title: 'Abacus', - description: 'A tool for simple arithmetic calculations', - buttonText: 'Get Abacus', - img: 'assets/Activities/Abacus.svg', - }, - { - title: 'BlockParty', - description: 'Blocks arrangement game', - buttonText: 'Get BlockParty', - img: 'assets/Activities/BlockPartyActivity.svg', - }, - { - title: 'Cells', - description: - 'This game is based on the mechanisms present in gene regulatory networks', - buttonText: 'Get Cells', - img: 'assets/Activities/CellManagement.svg', - }, - { - title: 'Flappy', - description: 'The popular Flappy bird game', - buttonText: 'Get Flappy', - img: 'assets/Activities/flappy.svg', - }, - { - title: 'JAMath', - description: 'A fun and interactive math game', - buttonText: 'Get JAMath', - img: 'assets/Activities/JAMath.svg', - }, - { - title: 'Jumble', - description: 'Rearrange and uncover the hidden pattern', - buttonText: 'Get Jumble', - img: 'assets/Activities/Jumble.svg', - }, - { - title: 'JupyterLabs', - description: 'Coding, data science, and visualization', - buttonText: 'Get JupyterLabs', - img: 'assets/Activities/JupyterLabs.svg', - }, - { - title: 'Math Hurdler', - description: 'Solve equations to keep moving forward', - buttonText: 'Get Math Hurdler', - img: 'assets/Activities/math-hurdler.svg', - }, - { - title: 'Memorize', - description: 'Here you can play games that challenge your memory!', - buttonText: 'Get Memorize', - img: 'assets/Activities/Memorize.svg', - }, - { - title: 'Read ETexts', - description: - 'Download and read thousands of free e-books in plain text format from Project Gutenberg!', - buttonText: 'Get Read ETexts', - img: 'assets/Activities/ReadEtextsActivity.svg', - }, - { - title: 'Recall', - description: 'Memory exercise game', - buttonText: 'Get Recall', - img: 'assets/Activities/RecallActivity.svg', - }, - { - title: 'Speak', - description: 'An animated face that speaks whatever you type', - buttonText: 'Get Speak', - img: 'assets/Activities/Speak.svg', - }, - { - title: 'Tic-Tac-Toe', - description: 'A classic strategy game of Xs and Os', - buttonText: 'Get Tic-Tac-Toe', - img: 'assets/Activities/TicTacToe.svg', - }, -]; - -export const firstRow = tryMoreActivities.slice( - 0, - tryMoreActivities.length / 2, -); -export const secondRow = tryMoreActivities.slice(tryMoreActivities.length / 2); -export const thirdRow = tryMoreActivities.slice( - 0, - tryMoreActivities.length / 2, -); -export const fourthRow = tryMoreActivities.slice(tryMoreActivities.length / 2); diff --git a/src/constants/TryNowData/bootableSoasData.ts b/src/constants/TryNowData/bootableSoasData.ts deleted file mode 100644 index 4def5fc0..00000000 --- a/src/constants/TryNowData/bootableSoasData.ts +++ /dev/null @@ -1,85 +0,0 @@ -export const bootableSoasData = { - title: 'Boot SOAS', - subtitle: 'Sugar On A Stick', - quote: - '“Through Sugar, we strive to provide every child with the opportunity to learn learning within a context that will allow them both to engage in an on-going critical dialog with others and to develop independent means towards their personal goals.” — Walter Bender', - description: - 'Learn how to boot Sugar Labs OS on your computer. Follow our step-by-step guide to get started easily.', - images: [{ src: 'assets/TryNowImages/step7.png', alt: 'Boot SOAS step 7' }], -}; - -interface StepData { - step: number; - title: string; - description: string; - image: string; - links?: { text: string; url: string }[]; -} - -export const steps: StepData[] = [ - { - step: 1, - title: 'Sugar On a Stick', - description: - 'To boot Sugar Labs OS on your computer, you will need a bootable Sugar on Stick setup already. To see how to set it up, visit the wiki.', - links: [ - { - text: 'wiki', - url: 'https://wiki.sugarlabs.org/go/Sugar_on_a_Stick/Installation', - }, - ], - image: 'assets/TryNowImages/step1.jpg', - }, - { - step: 2, - title: 'Insert the USB Drive', - description: - 'Plug the prepared Sugar on a Stick USB drive into an available USB port on your computer.', - image: 'assets/TryNowImages/step2.jpg', - }, - { - step: 3, - title: 'Access Advanced Boot Options (Windows)', - description: - "On Windows systems, access the advanced boot options by holding the 'Shift' key while clicking 'Restart.' This will bring you to the advanced boot menu.", - image: 'assets/TryNowImages/step3.jpg', - }, - { - step: 4, - title: 'Choose to Boot from USB (Windows)', - description: - "In the advanced boot menu, select 'Use a Device' to proceed with booting from the USB drive.", - image: 'assets/TryNowImages/step4.jpg', - }, - { - step: 5, - title: ' Select the USB Drive (Windows)', - description: - 'Choose your USB drive from the list of devices to boot into the Sugar OS.', - image: 'assets/TryNowImages/step5.jpg', - }, - { - step: 6, - title: 'Traditional Boot Method (Non-Windows Systems)', - description: - "For non-Windows computers:Power on your computer and immediately press the appropriate key (commonly F9, F12, or Esc) repeatedly to access the boot menu or BIOS settings. In the boot menu, select your USB drive, often identified by its brand or model name, and press 'Enter' to boot into Sugar.", - image: 'assets/TryNowImages/step6.jpg', - }, - { - step: 7, - title: 'Enjoy Sugar on a Stick', - description: - 'After selecting the USB drive, your computer should boot into the Sugar OS interface. If you encounter any issues during the boot process, seek assistance in the Sugar Labs Matrix room. For detailed instructions and additional resources, visit the Sugar Labs Booting SoaS page.', - image: 'assets/TryNowImages/step7.png', - links: [ - { - text: 'Matrix room', - url: 'https://matrix.to/#/#sugar:matrix.org', - }, - ], - }, -]; - -export const mockupImage = { - path: 'assets/TryNowImages/boatsoasMockup.png', -}; diff --git a/src/constants/TryNowData/flathubData.ts b/src/constants/TryNowData/flathubData.ts deleted file mode 100644 index c2e5989a..00000000 --- a/src/constants/TryNowData/flathubData.ts +++ /dev/null @@ -1,102 +0,0 @@ -export const flathubData = { - title: 'Sugar on Flatpak', - subtitle: 'Simplified Learning Platform Distribution', - quote: - '“The context of human development is always a culture, not an isolated technology.” – Seymour Papert, computer scientist and educator', - description: - 'Flatpak enables easy installation and distribution of Sugar Labs educational activities across different Linux platforms.', - images: [ - { - src: 'assets/TryNowImages/flathub1.png', - alt: 'Sugar Labs Activities Installation', - }, - ], -}; - -export const flathubSections = [ - { - title: 'Flatpak and Sugar', - content: - 'Flatpak provides a streamlined way to package and distribute Sugar Labs educational activities. It ensures that learning tools can be easily installed on various Linux distributions, making education more accessible.', - button: 'Explore Sugar Labs Activities', - buttonLink: 'https://flathub.org/apps/search?q=sugar%20labs', - }, -]; - -export const flathubLogoCards = [ - { - logo: 'assets/Cards/Flathub.png', - title: 'Educational Activities', - description: [ - 'Access 34+ educational activities including Paint, Abacus, Music Keyboard, and Story', - ], - buttons: [ - { - text: 'Browse Activities', - link: 'https://flathub.org/apps/collection/developer/Sugar%20Labs%20Community/1', - target: '_blank', - }, - ], - }, - { - logo: 'assets/TryNowImages/fpLogoCard2.png', - title: 'Easy Installation', - description: [ - 'Install Sugar activities with just a few commands on any Linux distribution', - ], - buttons: [ - { - text: 'Get Started', - link: 'https://flatpak.org/setup/', - target: '_blank', - }, - ], - }, - { - logo: 'assets/TryNowImages/fpLogoCard3.png', - title: 'Cross-Platform Support', - description: [ - 'Compatible with multiple Linux distributions and learning environments', - ], - buttons: [ - { - text: 'Explore Platforms', - link: 'https://flathub.org/setup', - target: '_blank', - }, - ], - }, -]; - -export const numberedCards1 = [ - { - number: '1', - title: 'Install Flatpak', - description: 'Add Flatpak repository to your Linux system', - borderColor: '#68A6F7', - link: 'https://flatpak.org/setup/', - }, - { - number: '2', - title: 'Find Sugar Activities', - description: 'Browse the collection of 34+ educational applications', - borderColor: '#68A6F7', - link: 'https://flathub.org/apps/collection/developer/Sugar%20Labs%20Community/1', - }, -]; - -export const numberedCards2 = [ - { - number: '3', - title: 'Install Activities', - description: - 'Download educational tools like Paint, Abacus, and Music Keyboard', - borderColor: '#F8251F', - }, - { - number: '4', - title: 'Start Learning', - description: 'Explore interactive educational experiences for all ages', - borderColor: '#F8251F', - }, -]; diff --git a/src/constants/TryNowData/musicBlocksData.ts b/src/constants/TryNowData/musicBlocksData.ts deleted file mode 100644 index ac55f9ff..00000000 --- a/src/constants/TryNowData/musicBlocksData.ts +++ /dev/null @@ -1,219 +0,0 @@ -export const musicBlocksData = { - title: 'Music Blocks', - subtitle: 'A Musical Microworld', - quote: - '“All musicians are subconsciously mathematicians” – Thelonious Monk, jazz pianist and composer', - description: - 'Music Blocks is a collection of manipulative tools for exploring fundamental musical concepts in an integrative and fun way.', - images: [ - { - src: 'assets/TryNowImages/musicBlocks1.png', - alt: 'Music Blocks Example 1', - }, - { - src: 'assets/TryNowImages/musicBlocks2.png', - alt: 'Music Blocks Example 2', - }, - { - src: 'assets/TryNowImages/musicBlocks3.png', - alt: 'Music Blocks Example 3', - }, - { - src: 'assets/TryNowImages/musicBlocks4.png', - alt: 'Music Blocks Example 4', - }, - ], -}; - -export const musicBlocksSections = [ - { - title: 'Using Music Blocks', - content: - 'Music Blocks is designed to run in the browser. It is derived from Turtle Blocks JS which can be found here. You can run the software locally from the index.html file, from the GitHub repository, or by setting up a local server. If you want to run Music Blocks offline, download this repo and point your browser to the index.html file found in the musicblocks directory on your local file system. See Using Music Blocks and Music Blocks Guide', - button: 'Try Music Blocks Now', - links: [ - { - text: 'here', - url: 'https://github.com/sugarlabs/turtleblocksjs', - }, - { - text: 'Github', - url: 'https://github.com/sugarlabs/musicblocks/', - }, - { - text: 'Using Music Blocks', - url: 'http://github.com/sugarlabs/musicblocks/tree/master/documentation', - }, - { - text: 'Music Blocks Guide', - url: 'http://github.com/sugarlabs/musicblocks/tree/master/guide', - }, - ], - }, - { - title: 'Credits', - content: - 'Music Blocks is a fork of TurtleArtJS created by Walter Bender. (Turtle Blocks JS has many contributors).\n Devin Ulibarri has contributed functional and user-interface designs. Many of his contributions were inspired by the music education ideas, representations and practices (e.g. aspects of matrix, musical cups) developed and published by Dr. Lawrence Scripp with whom Devin studied at New England Conservatory and for whom he worked at Affron Scripp & Associates, LLC.\n Much of the initial coding of the fork from Turtle Blocks was done by Yash Khandelwal as part of Google Summer of Code (GSoC) 2015. Hemant Kasat contributed to additional widgets as part of GSoC 2016. Additional contributions are being made by Tayba Wasim, Dinuka Tharangi Jayaweera, Prachi Agrawal, Cristina Del Puerto, and Hrishi Patel as part of GSoC 2017. During GSoC 2018, Riya Lohia developed a Temperament Widget. Ritwik Abhishek added a keyboard widget and a pitch-tracking widget.\n Many students contributed to the project as part of Google Code-in (2015–16, 2016–17, and 2017–2018). Sam Parkinson built the Planet during GCI 2016–17. Euan Ong redesigned the Planet code as a series of GCI tasks in 2017–18.', - button: null, - links: [ - { - text: 'contributors', - url: 'https://github.com/sugarlabs/turtleblocksjs/graphs/contributors', - }, - ], - }, -]; - -export const mockupImage = { - path: 'assets/TryNowImages/musicMockup.png', -}; - -export const musicblockstext = { - path: 'assets/TryNowImages/mbText.png', -}; - -export const foundabug = [ - { - title: 'Found a Bug?', - content: 'Report it in the issues section of THIS repository.', - links: [ - { - text: 'issues', - url: 'https://github.com/sugarlabs/musicblocks/issues', - }, - ], - button: null, - }, -]; - -export const musicBlocksLogoCards = [ - { - logo: 'assets/TryNowImages/mbLogoCard1.png', - title: 'Music Blocks Online', - description: [ - 'Children can learn programming from scratch and have fun creating music and videos by combining blocks that control instruments, rhythms, and changing pitch values.', - ], - buttons: [ - { - text: 'Trying out Music Blocks', - link: 'https://musicblocks.sugarlabs.org/', - target: '_blank', - }, - ], - }, - { - logo: 'assets/TryNowImages/mbLogoCard2.png', - title: 'Videos to learn how to use Music Blocks', - description: [ - 'You can learn the basics of Music Blocks through videos. We will explain what you can do with the software, how to start using it, how to program, and more.', - ], - buttons: [ - { - text: 'Go to Youtube channel', - link: 'https://www.youtube.com/channel/UCdXacR2zOXff4XCKRLTSnRw', - target: '_blank', - }, - ], - }, - { - logo: 'assets/TryNowImages/mbLogoCard3.png', - title: 'Videos that teach you how to create works using Music Blocks', - description: [ - 'This article explains how to create music and video works while programming using Music Blocks. Feel free to create your own original works.', - ], - buttons: [ - { - text: 'Go to Youtube channel', - link: 'https://www.youtube.com/channel/UCdXacR2zOXff4XCKRLTSnRw', - target: '_blank', - }, - ], - }, - { - logo: 'assets/TryNowImages/mbLogoCard4.png', - title: 'Music Blocks Challenge Print', - description: [ - 'This is a quiz-style printout that teaches you about the functions of Music Blocks and how to create works. Click the link below to download the PDF file.', - ], - buttons: [ - { - text: 'Download PDF file', - link: 'https://gakken-steam.jp/music_blocks/common/pdf/challengeprint.zip', - target: '_blank', - }, - ], - }, -]; - -export const teamMembers = [ - { - name: 'WALTER BENDER', - role: 'Developer of Music Blocks', - description: - 'Developer of Music Blocks. Former director of the MIT Media Lab. Founder of the OLPC (One Laptop Per Child) project, which provides $100 computers to children in developing countries. Founder of the nonprofit organization Sugar Labs.', - image: 'assets/TryNowImages/walter.png', - bgColor: '#B0D0FF', - }, - { - name: 'DEVIN ULIBARRI', - role: 'CEO of Remake Music LLC', - description: - 'Developer of Music Blocks. CEO of Remake Music LLC. Head of Music + Code Lead Teaching Artist Training at MAP Family Learning Center.', - image: 'assets/TryNowImages/devin.png', - bgColor: '#FFB3C6', - }, -]; - -export const numberedCards1 = [ - { - number: '1', - title: 'You can create music through programming!', - description: - 'Rhythms and melodies can be created intuitively, so anyone can easily create original music.', - image: 'assets/TryNowImages/mbNumberedCard1.png', - borderColor: '#FFED51', - }, - { - number: '2', - title: 'You can study math!', - description: - "Since musical elements such as 'note length' and 'performance speed' are controlled numerically, students will develop mathematical literacy.", - image: 'assets/TryNowImages/mbNumberedCard2.png', - borderColor: '#FFED51', - }, - { - number: '3', - title: 'You can show your work all over the world!', - description: - 'You can publish your work on a dedicated cloud. Download the work you like and collaborate with friends around the world.', - image: 'assets/TryNowImages/mbNumberedCard3.png', - borderColor: '#FFED51', - }, -]; - -export const numberedCards2 = [ - { - number: '1', - title: 'You can create music through programming!', - description: - 'Rhythms and melodies can be created intuitively, so anyone can easily create original music.', - image: '', - borderColor: '#F8251F', - }, - { - number: '2', - title: 'You can study math!', - description: - "Since musical elements such as 'note length' and 'performance speed' are controlled numerically, students will develop mathematical literacy.", - image: '', - borderColor: '#F8251F', - }, - { - number: '3', - title: 'You can show your work all over the world!', - description: - 'You can publish your work on a dedicated cloud. Download the work you like and collaborate with friends around the world.', - image: '', - borderColor: '#F8251F', - }, -]; diff --git a/src/constants/TryNowData/raspberryPiData.ts b/src/constants/TryNowData/raspberryPiData.ts deleted file mode 100644 index aff4459c..00000000 --- a/src/constants/TryNowData/raspberryPiData.ts +++ /dev/null @@ -1,107 +0,0 @@ -export const raspberrydata = { - title: 'Raspberry-Pi', - subtitle: 'Sugar on RaspberryPi', - quote: - '“Programming should be on every child’s low shelf, within reach for frequent use.” — Walter Bender, Sugar Labs founder', - description: - 'Raspberry Pi are a series of small, low cost, low power computers. The Sugar Desktop Environment can be run on a Raspberry Pi. You will need a display, keyboard, and a mouse.', - images: [{ src: 'assets/TryNowImages/raspberry.jpg', alt: 'RaspberryPi 1' }], -}; - -export const raspberrySections = [ - { - title: 'Recommendation', - content: - 'As of August 2017, the best way to experience the Sugar learning platform on a Raspberry Pi (RPi) is by using Sugar on a Stick (SoaS), a portable version of Sugar that runs from a USB drive. SoaS offers a rich collection of educational activities, making it ideal for learners, and it benefits from regular security updates to ensure a safe and stable environment. Designed as a spin of the Fedora operating system, SoaS combines the flexibility of Fedora with the educational focus of Sugar. For setup instructions, refer to the SoaS/RPi documentation, which guides users through the process of downloading, installing, and running it on a Raspberry Pi.', - button: '', - links: [ - { - text: 'Sugar on a Stick/Raspberry Pi', - url: 'https://github.com/sugarlabs/RPi-Docs/blob/main/src/installation.md', - }, - ], - }, - { - title: 'Developers', - content: - 'Developers may focus on Fedora or Debian when setting up a development environment for Sugar on Raspberry Pi, because Sugar development on generic computers is focused on those operating systems.', - button: '', - links: [ - { - text: 'Fedora', - url: 'https://github.com/sugarlabs/sugar/blob/master/docs/fedora.md', - }, - { - text: 'Debian', - url: 'https://github.com/sugarlabs/sugar/blob/master/docs/debian.md', - }, - ], - }, -]; - -export const raspberryLogoCards = [ - { - logo: 'assets/TryMoreSvgs/trisquel-desktop.svg', - title: 'using Raspbian', - description: [ - 'Raspbian (now known as Raspberry Pi OS) is the most widely used OS for Raspberry Pi and is based on Debian.', - 'You can install the Sugar learning environment using package managers or custom scripts.', - 'It’s lightweight, actively maintained, and optimized for Raspberry Pi hardware.', - 'Best suited for users already familiar with Raspberry Pi setups.', - ], - buttons: [ - { - text: 'Read Raspbian installation guide', - link: 'https://wiki.sugarlabs.org/go/Raspbian', - }, - ], - }, - { - logo: 'assets/TryMoreSvgs/fedora.svg', - title: 'using Fedora', - description: [ - 'Fedora offers a reliable and cutting-edge platform to run Sugar on various hardware, including Raspberry Pi.', - 'Sugar on a Stick (SoaS) is a Fedora-based spin tailored for educational purposes.', - 'You can run Sugar live from a USB stick or install it on the Pi directly with some configuration.', - 'Suitable for users seeking a polished Linux experience with SELinux and Wayland support.', - ], - buttons: [ - { - text: 'View Fedora instructions', - link: 'https://github.com/sugarlabs/sugar/blob/master/docs/fedora.md', - }, - ], - }, - { - logo: 'assets/TryMoreSvgs/debian.svg', - title: 'using Debian', - description: [ - 'Debian is the upstream source of Raspbian and offers a very stable environment for Sugar.', - 'You can install Sugar via APT repositories or build it from source for more customization.', - 'Recommended for developers and advanced users familiar with Debian packaging and systems.', - 'You gain fine-grained control over packages and system updates.', - ], - buttons: [ - { - text: 'Read Debian instructions', - link: 'https://github.com/sugarlabs/sugar/blob/master/docs/debian.md', - }, - ], - }, - { - logo: 'assets/TryMoreSvgs/ubuntu.svg', - title: 'using Ubuntu', - description: [ - 'Ubuntu is a user-friendly Linux distribution and supports running Sugar with a few extra steps.', - 'You can install Sugar directly via terminal or explore Ubuntu derivatives for a lighter setup.', - 'Popular among new users due to its graphical interface and large support community.', - 'Ideal if you’re already using Ubuntu on other machines and want consistency.', - ], - buttons: [ - { - text: 'View Ubuntu setup guide', - link: 'https://github.com/sugarlabs/sugar/blob/master/docs/ubuntu.md', - }, - ], - }, -]; diff --git a/src/constants/TryNowData/sugarizerData.ts b/src/constants/TryNowData/sugarizerData.ts deleted file mode 100644 index 7ded60b8..00000000 --- a/src/constants/TryNowData/sugarizerData.ts +++ /dev/null @@ -1,142 +0,0 @@ -export const logoCardsData = [ - { - logo: 'assets/TryMoreSvgs/web.svg', - title: 'Web', - description: [ - 'Try Sugarizer directly from your browser.', - 'A great way to get a taste of sugar!', - 'No installation needed.', - 'Works on desktop, laptop, and mobile devices.', - 'Works on any operating system (Windows, Mac, GNU/Linux, etc.)', - ], - buttons: [ - { - text: 'Try Sugarizer in your Browser now', - link: 'https://try.sugarizer.org/', - }, - ], - }, - { - logo: 'assets/TryMoreSvgs/android.svg', - title: 'Mobile (Android)', - description: [ - 'Try Sugarizer on your android tablet of phone.', - 'Available in Google Play and F-Droid for Android users.', - "Utilizes your device's touch capabilities.", - 'Most functionality works both online and offline.', - 'Android devices can be an economical choice for bringing Sugar to your school.', - ], - buttons: [ - { - text: 'Install Sugarizer from Google Play', - link: 'https://play.google.com/store/apps/details?id=org.olpc_france.sugarizer&pli=1', - }, - { - text: 'Install Sugarizer from F-Droid', - link: 'https://f-droid.org/packages/org.olpc_france.sugarizer/', - }, - ], - }, - { - logo: 'assets/TryMoreSvgs/ios.svg', - title: 'Mobile (iOS)', - description: [ - 'Try Sugarizer on your android tablet of phone.', - 'Available in the App store for iOS users.', - "Utilizes your device's touch capabilities.", - 'Most functionality works both online and offline.', - ], - buttons: [ - { - text: 'Install Sugarizer from the App Store', - link: 'https://apps.apple.com/us/app/sugarizer/id978495303', - }, - ], - }, - { - logo: 'assets/TryMoreSvgs/deploy.svg', - title: 'Deploy', - description: [ - 'This option is best for sysadmins of schools looking to run their own Sugarizer Learning Platform.', - 'An entire server-side stack is available for deployment.', - 'Comes with tools for administrators and teachers.', - 'Comes with collaboration features for students to work together.', - 'A great choice for schools who want to use Sugar comprehensively.', - ], - buttons: [ - { - text: 'Learn more about Sugarizer Server', - link: 'https://github.com/llaske/sugarizer-server', - }, - ], - }, - { - logo: 'assets/TryMoreSvgs/windows.svg', - title: 'Windows', - description: [ - 'Run Sugar on your Windows machine.', - 'Get a taste of Sugar with Sugarizer on your Windows laptop or desktop.', - 'Comes with the complete set of applications available on other platforms.', - 'Installs within Windows; no boot necessary.', - ], - buttons: [ - { - text: 'Download Sugarizer for Windows', - link: 'https://sugarizer.org/download/Sugarizer-Setup-1.8.0.exe', - }, - ], - }, - { - logo: 'assets/TryMoreSvgs/mac.svg', - title: 'MacOS', - description: [ - 'Run Sugarizer on your Apple desktop or laptop.', - 'Get a taste of Sugar with Sugarizer on your MacOS laptop or desktop.', - 'Comes with the complete set of applications available on other platforms.', - 'Installs within MacOS; no boot necessary.', - ], - buttons: [ - { - text: 'Download Sugarizer for MacOS', - link: 'https://sugarizer.org/download/Sugarizer-1.8.0.dmg', - }, - ], - }, - { - logo: 'assets/TryMoreSvgs/linux.svg', - title: 'GNU- Linux', - description: [ - 'Run Sugarizer on your GNU/Linux desktop or laptop.', - 'Get a taste of Sugar with Sugarizer on your GNU/Linux laptop or desktop.', - 'Comes with the complete set of applications available on other platforms.', - "Experience the Sugar differently from its 'classic' Desktop Environment with Sugarizer.", - 'Installs within your current distribution as a Debian file or AppImage.', - ], - buttons: [ - { - text: 'Download Sugarizer Debian file', - link: 'https://sugarizer.org/download/Sugarizer_1.8.0_amd64.deb', - }, - { - text: 'Download Sugarizer AppImage file', - link: 'https://sugarizer.org/download/Sugarizer-1.8.0.AppImage', - }, - ], - }, -]; - -export const sugarizerData = { - title: 'Sugarizer', - subtitle: 'is Multi-Platform', - quote: - '“Debugging is one of the most powerful educational ideas of the 21st century.” — Cynthia Solomon', - description: - 'Sugarizer makes the Sugar Learning Platform and its activities available on web, mobile, Windows, and MacOS.', - images: [ - { src: 'assets/TryNowImages/sugarizer.png', alt: 'Sugarizer Example' }, - ], -}; - -export const mockupImage = { - path: 'assets/TryNowImages/sugarizerMockup.png', -}; diff --git a/src/constants/TryNowData/trisquelData.ts b/src/constants/TryNowData/trisquelData.ts deleted file mode 100644 index ce1ba35f..00000000 --- a/src/constants/TryNowData/trisquelData.ts +++ /dev/null @@ -1,76 +0,0 @@ -export const trisquelData = { - title: 'Trisquel', - subtitle: 'Sugar in total freedom', - quote: - '“Sugar is a free software platform that is designed for children for learning. Our goal is to raise a generation of critical thinkers and problem-solvers by establishing a culture of independent thinking and learning.” — Walter Bender, Sugar Labs founder', - description: - "Trisquel GNU/Linux is a fully free operating system (OS) for homes, businesses, and schools, which receives reliable support for Sugar Desktop. It's a great choice for booting or installing Sugar on any computer.", - images: [ - { - src: 'assets/TryNowImages/trisquel.png', - alt: 'Trisquel Sugar Blocks 1', - }, - { - src: 'assets/TryNowImages/trisquel2.png', - alt: 'Trisquel Turtle Blocks 2', - }, - ], -}; - -export const trisquelLogoCards = [ - { - logo: 'assets/TryMoreSvgs/trisquel-desktop.svg', - title: 'Download an ISO with Sugar Desktop', - description: [ - 'Great if you have a laptop or desktop you can dedicate for this purpose.', - 'Gratis and free: Trisquel asks for a donation, but does not require payment.', - 'Respect for privacy: Your data is safely stored locally on your computer.', - 'Ad-free and simple: Zero distractions, so your child can stay focused.', - ], - buttons: [ - { - text: 'Download: Trisquel Sugar TOAST', - link: 'https://trisquel.info/en/download', - }, - ], - }, - { - logo: 'assets/TryMoreSvgs/trisquel-community.svg', - title: 'Get community support for Trisquel', - description: [ - 'There is no paid support for Trisquel. Go to the community forum for assistance.', - 'Multi-lingual: Forums are supported in English, Spanish, French, Italian, Galego, and German.', - ], - buttons: [ - { - text: 'Explore community forums', - link: 'https://trisquel.info/en/forum', - }, - ], - }, - { - logo: 'assets/TryMoreSvgs/trisquel-documentation.svg', - title: 'Read the documentation', - description: [ - 'Learn more about what makes Trisquel different.', - 'Read about Trisquel’s commitment to accessibility.', - 'Read about all the different ways that you can get community help for Trisquel.', - 'Read about how you can get involved.', - ], - buttons: [ - { - text: 'Explore Sugar Labs’s documentation', - link: 'https://wiki.sugarlabs.org/go/Trisquel_On_A_Sugar_Toast', - }, - ], - }, -]; - -export const trisquelSections = [ - { - title: "Trisquel is fully free 'as in freedom'", - content: - 'What makes Trisquel different from other OSes like Windows and iOS is it’s fully free as in freedom, including the freedom to study the source code. The Trisquel maintainers have given reliable support for Sugar, which is another reason that we recommend it as a great option for those of you interested in booting the Sugar Learning Environment (aka Sugar Desktop) from a live USB or installing onto your computer.', - button: '', - }, -]; diff --git a/src/constants/TryNowData/turtleBlocksData.ts b/src/constants/TryNowData/turtleBlocksData.ts deleted file mode 100644 index 7a7534cc..00000000 --- a/src/constants/TryNowData/turtleBlocksData.ts +++ /dev/null @@ -1,176 +0,0 @@ -export interface SectionLink { - text: string; - url: string; -} - -export interface TurtleBlockSection { - title: string; - content: string; - button?: string | null; - links?: SectionLink[]; -} - -export const turtleBlocksData = { - title: 'Turtle Blocks', - subtitle: 'Playground for Coding', - quote: - '“Knowledge is a noun; learning is a verb.” — Walter Bender, Sugar Labs founder', - description: - 'Turtle Blocks JavaScript lets users create colorful art with a Logo-inspired turtle using snap-together coding blocks. It’s beginner-friendly yet powerful enough for advanced programming, graphics, and math exploration.', - images: [ - { - src: 'assets/TryNowImages/turtleblocks2.png', - alt: 'Turtle Blocks Example 1', - }, - { - src: 'assets/TryNowImages/turtleblocks1.png', - alt: 'Turtle Blocks Example 2', - }, - { - src: 'assets/TryNowImages/turtleBlocks.png', - alt: 'Turtle Blocks Example 3', - }, - ], -}; - -export const turtleBlocksSections: TurtleBlockSection[] = [ - { - title: 'Using turtle art JS', - content: - "Turtle Blocks Javascript is designed to run in a browser. Most of the development has been done in Chrome, but it also works in Firefox. You can run it directly from index.html, from a server maintained by Sugar Labs, from the github repo, or by setting up a local server. Once you've launched it in your browser, start by clicking on (or dragging) blocks from the Turtle palette. Use multiple blocks to create drawings; as the turtle moves under your control, colorful lines are drawn. You add blocks to your program by clicking on or dragging them from the palette to the main area. You can delete a block by dragging it back onto the palette. Click anywhere on a 'stack' of blocks to start executing that stack or by clicking in the Rabbit (fast) or Turtle (slow) on the Main Toolbar.", - button: null, - links: [ - { - text: 'server maintained by Sugar Labs', - url: 'http://turtle.sugarlabs.org/', - }, - { - text: 'local server', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/server.md', - }, - { - text: 'github repo', - url: 'http://rawgit.com/sugarlabs/turtleblocksjs/master/index.html', - }, - ], - }, - { - title: 'Getting Started Documentation', - content: - 'The basic buttons and basic blocks are explained in detail in Documentation. A guide to programming with Turtle Blocks is available in Turtle Blocks Guide. A quick start: Google Code-in participant Jasmine Park has created some guides to using Turtle Blocks: Turtle Blocks: An Introductory Manual and Turtle Blocks: A Manual for Advanced Blocks.', - links: [ - { - text: 'Documentation', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/documentation/README.md', - }, - { - text: 'Turtle Blocks Guide', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/guide/README.md', - }, - { - text: 'Turtle Blocks: An Introductory Manual', - url: 'http://people.sugarlabs.org/walter/TurtleBlocksIntroductoryManual.pdf', - }, - { - text: 'Turtle Blocks: A Manual for Advanced Blocks', - url: 'http://people.sugarlabs.org/walter/TurtleBlocksAdvancedBlocksManual.pdf', - }, - ], - button: null, - }, - { - title: 'Found a Bug?', - content: 'Bugs can be reported in the issues section of the repository', - links: [ - { - text: 'issues section', - url: 'https://github.com/sugarlabs/turtleblocksjs/issues', - }, - ], - button: null, - }, - { - title: 'Advance Features', - content: - 'Turtle Blocks has a plugin mechanism that is used to add new blocks. You can learn more about how to use plugins (and how to write them) from the Plugins Guide.', - links: [ - { - text: 'Plugins Guide', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/README.md', - }, - ], - button: null, - }, - { - title: 'List of Plugins', - content: - 'Mindstorms: blocks to interact with the LEGO mindstorms robotics kit\n RoDi: blocks to interact with Rodi wireless robot\n Maths: addition blocks for some more advanced mathematics\n Translate: blocks for translating strings between languages, e.g., English to Spanish\n Dictionary: a block to look up dictionary definitions\n Weather: blocks to retrieve global weather forecasts\n Logic: blocks for bitwise Boolean operations\n Finance: a block for looking up market prices\n Bitcoin: a block for looking up bitcoin exchange rates\n Nutrition: blocks for exploring the nutritional content of food\n Facebook: a block for publishing a project to facebook\n Heap: blocks to support a heap and for loading and saving data\n Accelerometer: blocks for accessing an accelerometer\n Turtle: blocks to support advanced features when using multiple turtles\n Gmap: blocks to support generation of Google maps.', - links: [ - { - text: 'Mindstorms', - url: 'https://github.com/SAMdroid-apps/turtlestorm', - }, - { - text: 'RoDi', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/rodi.json', - }, - { - text: 'Maths', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/maths.json', - }, - { - text: 'Translate', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/translate.json', - }, - { - text: 'Dictionary', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/dictionary.json', - }, - { - text: 'Weather', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/weather.json', - }, - { - text: 'Logic', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/logic.json', - }, - { - text: 'Finance', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/finance.json', - }, - { - text: 'Bitcoin', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/bitcoin.json', - }, - { - text: 'Nutrition', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/nutrition.json', - }, - { - text: 'Facebook', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/facebook.json', - }, - { - text: 'Heap', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/heap.json', - }, - { - text: 'Accelerometer', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/accelerometer.json', - }, - { - text: 'Turtle', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/turtle.json', - }, - { - text: 'Gmap', - url: 'https://github.com/sugarlabs/turtleblocksjs/blob/master/plugins/gmap.json', - }, - ], - button: null, - }, -]; - -export const mockupImage = { - path: 'assets/TryNowImages/turtleMockup.png', -}; diff --git a/src/constants/Volunteer.ts b/src/constants/Volunteer.ts deleted file mode 100644 index bb78d89e..00000000 --- a/src/constants/Volunteer.ts +++ /dev/null @@ -1,9 +0,0 @@ -import volunteer1 from '/assets/Volunteer/volunteer-1.png'; -import volunteer2 from '/assets/Volunteer/volunteer-2.png'; -import volunteer3 from '/assets/Volunteer/volunteer-3.png'; - -export const volunteerImages = [ - { id: 1, alt: 'Volunteer 1', src: volunteer1 }, - { id: 2, alt: 'Volunteer 2', src: volunteer2 }, - { id: 3, alt: 'Volunteer 3', src: volunteer3 }, -]; diff --git a/src/constants/VolunteerAndDev/DeveloperTestimonials.ts b/src/constants/VolunteerAndDev/DeveloperTestimonials.ts deleted file mode 100644 index 6e248189..00000000 --- a/src/constants/VolunteerAndDev/DeveloperTestimonials.ts +++ /dev/null @@ -1,44 +0,0 @@ -export const developertestimonials = [ - { - name: 'Sourabha G.', - username: 'Sourabha G. (GSoC 2021 contributor)', - body: "This summer was super fun and filled with learning! I enjoyed testing over 60+ activities with kids to get first-hand feedback, which had a positive impact in the way they approach problems. The fact that these activities are used by kids as a tool of learning motivates me to contribute more and more. I'm going to continue to contribute and be a part of Sugar Labs.", - img: 'https://avatar.vercel.sh/jack', - }, - { - name: 'Riya Lohia', - username: 'Riya Lohia (GSoC 2018 contributor)', - body: 'I would like to thank my mentors Walter Bender and Devin Ulibarri for their constant guidance and motivation. A big thanks to Sugar Labs community and Google Summer of Code (GSoC) for providing such a wonderful opportunity for learning and helping me to be an active member of Open Source Community.', - img: 'https://avatar.vercel.sh/jill', - }, - { - name: 'Om Santosh Suneri', - username: 'Om Santosh Suneri', - body: 'My first open source contribution was challenging but incredibly rewarding. If you’re hesitant about contributing, just dive in. Find a project you love, pick an issue, and start exploring. Who knows? Your first PR might be just around the corner.', - img: 'https://media.licdn.com/dms/image/v2/D5603AQEWfqFxGN6Msg/profile-displayphoto-shrink_800_800/B56ZS5vxjvHQAc-/0/1738283097234?e=1749686400&v=beta&t=dT5SgsauobXe5gcQsiGMm91rfY_ILQvxkHT9Ukzck-s', - }, - { - name: 'Karan Palan', - username: 'Karan Palan (GSoC 2024 contributor)', - body: 'Overall, my work on the Masonry project during GSoC 2024 has involved a mix of design, prototyping, and development activities… This experience has not only strengthened my technical skills but also provided valuable insights into the collaborative, iterative nature of open-source development. I look forward to continuing to contribute to the Music Blocks project and helping to create a more accessible and engaging visual programming environment for users around the world.', - img: 'https://media.licdn.com/dms/image/v2/D5603AQFd4DwGD9a1Ig/profile-displayphoto-shrink_800_800/profile-displayphoto-shrink_800_800/0/1719038630136?e=1749686400&v=beta&t=ZNXwm01ufeYSP0Q1SOuDGaXdMULxU2O_zEjkfni_ktM', - }, - { - name: 'Diwangshu Kakoty', - username: 'Diwangshu Kakoty', - body: 'I wanted to try open-source contributions to learn more about real-world projects. How is software developed? How do developers work in a team? What are the coding practices that professionals use? I sought answers to these questions and found them when I joined Sugar Labs and its awesome community of developers.', - img: 'https://miro.medium.com/v2/resize:fill:96:96/0*3WyfLW5_tE0JqmZI', - }, - { - name: 'Tayba Wasim', - username: 'Tayba Wasim (GSoC 2017 contributor)', - body: 'Once you successfully solve the bug, you need to create a pull request (PR)… Don’t get disappointed or feel dejected if your PR is not merged at once, it opens up the gate to learning when you work through the suggestions provided by the mentors as they know how the PR can be improved. Once your PR is updated and merged, the momentary sense of achievement you get is a bliss!', - img: 'https://secure.gravatar.com/blavatar/d51a3c490f489d67f2bf4972eb962731f4fe2da9f8371383ed08cce4efddf56f?s=114', - }, - { - name: 'Anurag Singh', - username: 'Anurag Singh (GSoC 2024 contributor)', - body: 'This summer has been a great experience working with Sugar Labs. I learned and coded across various fields, from RPi to OS to content creation and hardware. It has been a very enriching experience, and I am truly grateful for this opportunity.', - img: 'https://avatars.githubusercontent.com/u/123321851?s=96&v=4', - }, -]; diff --git a/src/constants/VolunteerAndDev/Links.ts b/src/constants/VolunteerAndDev/Links.ts deleted file mode 100644 index c4f89685..00000000 --- a/src/constants/VolunteerAndDev/Links.ts +++ /dev/null @@ -1,37 +0,0 @@ -export const developerLinks = [ - { - name: 'Chat with us on Matrix', - url: 'https://matrix.to/#/#sugar:matrix.org', - icon: 'assets/LinksLogos/matrix.svg', - }, - { - name: 'Developer Guide', - url: 'https://github.com/sugarlabs/sugar-docs/blob/master/README.md/', - icon: 'assets/LinksLogos/github.svg', - }, - { - name: 'Mailing lists (old-school, but still active and useful)', - url: 'https://lists.sugarlabs.org/', - icon: 'assets/LinksLogos/mailingList.svg', - }, - { - name: 'Contribute to Translations', - url: 'https://translate.sugarlabs.org/', - icon: 'assets/LinksLogos/translation.svg', - }, - { - name: 'Related Projects', - url: 'https://github.com/sugarlabs/sugar-docs/blob/master/README.md', - icon: 'assets/LinksLogos/projects.svg', - }, - { - name: 'Who are the developers of Sugar Labs?', - url: 'https://www.sugarlabs.org/profiles/', - icon: 'assets/LinksLogos/developer.svg', - }, - { - name: 'Code of Conduct', - url: 'https://github.com/sugarlabs/sugar-docs/blob/master/src/CODE_OF_CONDUCT.md', - icon: 'assets/LinksLogos/conduct.svg', - }, -]; diff --git a/src/constants/VolunteerAndDev/RoleCards.ts b/src/constants/VolunteerAndDev/RoleCards.ts deleted file mode 100644 index 89fa2cf1..00000000 --- a/src/constants/VolunteerAndDev/RoleCards.ts +++ /dev/null @@ -1,34 +0,0 @@ -export const roleCards = [ - { - title: 'Educator', - description: - 'Sugar Labs is focused on education, and we value the feedback of other educators. Here are ways that educators can participate in Sugar Labs as a volunteer:', - points: [ - 'Use our software and lesson plans in your classroom, and try our Constructionism learning tools for yourself.', - 'Test software and give your feedback based on your experience as an educator.', - 'Create your own lesson plans for other teachers to use in the classroom.', - ], - extra: `Educators are encouraged to contact iaep@sugarlabs.org and ask education-specific questions. "IAEP" stands for "It's an education project". - You may also subscribe to our group mailing list at,`, - link: 'http://lists.sugarlabs.org/listinfo/iaep', - }, - { - title: 'Communicator', - description: - 'Help us document stakeholder experiences. Here are a few ways you can help:', - points: [ - "If you're a student or former student, you can share your story using Sugar, either in the form of a blog post or on a video.", - 'If you speak multiple languages, we can use assistance creating and testing translations.', - "Give your feedback about Sugar as a third-party. While not necessarily a 'volunteer', we do appreciate when members of the broader education and/or tech community test our tools and give their feedback.", - ], - }, - { - title: 'Advocate', - description: - 'Help us spread awareness about Sugar Labs and our unique mission in education. Here are a few ways you can help:', - points: [ - "If you're enthusiastic about what Sugar Labs stands for and what we do, you may help us by following us on social media and sharing our message.", - "Parents and teachers, you can speak to your child's school administrators and tell them about Sugar and its benefits.", - ], - }, -]; diff --git a/src/constants/aboutUs/faqs.ts b/src/constants/aboutUs/faqs.ts deleted file mode 100644 index 33aa952a..00000000 --- a/src/constants/aboutUs/faqs.ts +++ /dev/null @@ -1,120 +0,0 @@ -export const FAQ_CATEGORIES = [ - 'all', - 'general', - 'development', - 'activities', - 'installation', -] as const; -export type FaqCategory = (typeof FAQ_CATEGORIES)[number]; - -export interface FAQ { - question: string; - answer: string; - category: Exclude<FaqCategory, 'all'>; -} - -const faqs: FAQ[] = [ - { - question: 'What is Sugar Labs?', - answer: - 'Sugar Labs, a 501(c)(3) non-profit foundation, serves as a support base and gathering place for the community of educators and software developers who want to extend the Sugar platform and who have been creating Sugar-compatible applications.', - category: 'general', - }, - { - question: 'What is the mission of Sugar Labs?', - answer: - 'The overarching mission of Sugar Labs is to support the Sugar platform through software development, and community outreach and support. The purpose of the Sugar platform is provide a software and content environment that enhances learning.', - category: 'general', - }, - { - question: 'What are the principles that guide Sugar Labs?', - answer: - 'Sugar Labs subscribes to principle that learning thrives within a culture of freedom of expression, hence it has a natural affinity with the free software movement.', - category: 'general', - }, - { - question: - 'What makes Sugar different from other educational software platforms?', - answer: - 'The Sugar interface, in its departure from the desktop metaphor for computing, is the first serious attempt to create a user interface that is based on both cognitive and social constructivism.', - category: 'development', - }, - { - question: 'Who can use Sugar and how do they benefit?', - answer: - 'Sugar is a free software project, freely available to anyone who wants to use it or improve upon it. The Sugar platform was designed for young children (K–6), but it is finding applicability in a number of different venues.', - category: 'general', - }, - { - question: 'Are there any platforms where Sugar runs on?', - answer: - 'The Sugar Learning Platform is a leading learning platform that began in the famous One Laptop Per Child project. It is used every day by nearly 3 million children around the world.', - category: 'installation', - }, - { - question: 'What are some popular Sugar Activities for beginners?', - answer: - 'Some popular Sugar Activities for beginners include TurtleBlocks (for learning programming through graphics), Write (for writing and journaling), Calculate (for mathematics), Read (for e-books), and Speak (a text-to-speech activity). These activities are designed to be both engaging and educational, helping children learn through exploration and play.', - category: 'activities', - }, - { - question: 'How does Sugar Labs sustain its operations?', - answer: - 'Sugar Labs is supported by donations, community contributions, and mentorship programs like Google Summer of Code. It relies heavily on its global volunteer network.', - category: 'general', - }, - { - question: 'What age group is Sugar Labs software primarily designed for?', - answer: - 'Sugar Labs focuses primarily on children in the K–6 age range, aiming to provide them with interactive tools for experiential learning.', - category: 'general', - }, - - { - question: 'Can I contribute to Sugar Labs if I am not a programmer?', - answer: - 'Absolutely! Non-programmers can contribute through translations, documentation, user testing, outreach, or by creating educational content.', - category: 'development', - }, - { - question: 'How can I find beginner-friendly issues to contribute to?', - answer: - 'Sugar Labs uses GitHub for tracking issues. You can filter for labels like "good first issue" or "beginner" to find suitable tasks.', - category: 'development', - }, - - { - question: 'How do Sugar Activities support different subjects?', - answer: - 'Sugar Activities cover a wide range of subjects like math, science, reading, music, and programming—each encouraging learning through exploration and play.', - category: 'activities', - }, - { - question: - 'Can Sugar Activities be used without the full Sugar environment?', - answer: - 'Many Sugar Activities can run independently on GNU/Linux or through web-based alternatives such as Sugarizer, which provides a full Sugar experience https://www.sugarlabs.org/sugarizer/', - category: 'activities', - }, - - { - question: 'What is Sugar on a Stick?', - answer: - 'Sugar on a Stick (SoaS) is a version of Sugar that can run from a bootable USB drive. It allows users to try Sugar without installing anything on their computer. Learn more at https://www.sugarlabs.org/sugarizer/', - category: 'installation', - }, - { - question: 'Can I run Sugar on Windows or macOS?', - answer: - 'While the original Sugar is Linux-based and typically run via virtualization tools like VirtualBox, you can use Sugarizer, a web-based version of Sugar, on Windows, macOS, and other platforms. Learn more at https://www.sugarlabs.org/sugarizer/', - category: 'installation', - }, - { - question: 'Where can I download the Sugar Learning Platform?', - answer: - 'You can download Sugar preloaded on Fedora SoaS - https://fedoraproject.org/spins/soas/download or Trisquel - https://trisquel.info/en/download', - category: 'installation', - }, -]; - -export default faqs; diff --git a/src/constants/aboutUs/goals.ts b/src/constants/aboutUs/goals.ts deleted file mode 100644 index 06e991b9..00000000 --- a/src/constants/aboutUs/goals.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { MotionProps } from 'framer-motion'; - -export interface Goal { - title: string; - description: string; - category?: string; -} - -export interface SectionContentType { - title: { - main: string; - highlight: string; - }; - introduction: string; -} - -export interface AnimationsType { - goalItem: { - initial: MotionProps['initial']; - whileInView: MotionProps['whileInView']; - whileHover: MotionProps['whileHover']; - }; - flowContainer: { - initial: MotionProps['initial']; - whileInView: MotionProps['whileInView']; - transition: MotionProps['transition']; - }; - customNode: { - initial: MotionProps['initial']; - animate: MotionProps['animate']; - whileHover: MotionProps['whileHover']; - whileTap: MotionProps['whileTap']; - }; -} - -export const goals: Goal[] = [ - { - title: 'Power users, involved in feedback', - description: - 'Reach one hundred "power" users, regularly providing their feedback to the development community, by the end of 2025', - category: 'Community', - }, - { - title: 'Leadership in education', - description: - 'Take fifteen actions (e.g. conferences, articles, events-led) in 2025 that help us establish ourselves as leaders in education technology.', - category: 'Education', - }, - { - title: 'New Sugar Stories', - description: 'Publish five new Sugar Stories from the community in 2025.', - category: 'Content', - }, - { - title: 'Establish 150k in annual revenue', - description: - 'In order to magnify our impact, we aim to establish 150k in annual revenue by the end of 2025. These funds will help us establish our operations, starting by hiring one full-time staff and three part time workers to serve our stakeholders.', - category: 'Sustainability', - }, - { - title: '200 volunteers', - description: - 'In order to best serve our community, our goal is to have twenty active mentors, and 180 active volunteers.', - category: 'Community', - }, - { - title: '1,000 people on Matrix', - description: - 'Our main mode of communication is on Matrix chat. Our goal in 2025 is to have 1,000 users on our chat, discussing ideas, designs, and development for our community-led suite of learning tools.', - category: 'Communication', - }, -]; - -// Section text content -export const sectionContent: SectionContentType = { - title: { - main: 'Our ', - highlight: 'Goals', - }, - introduction: - 'At Sugar Labs, we strive to create a vibrant ecosystem where technology empowers education. Our strategic goals focus on expanding our impact while maintaining our core values.', -}; - -// Animation settings -export const animations: AnimationsType = { - goalItem: { - initial: { opacity: 0, x: -20 }, - whileInView: { opacity: 1, x: 0 }, - whileHover: { x: 10, backgroundColor: '#fef2f2' }, - }, - flowContainer: { - initial: { opacity: 0, y: 20 }, - whileInView: { opacity: 1, y: 0 }, - transition: { duration: 0.6 }, - }, - customNode: { - initial: { scale: 0.9 }, - animate: { scale: 1 }, - whileHover: { - scale: 1.05, - boxShadow: - '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', - borderColor: '#ef4444', - }, - whileTap: { scale: 0.95 }, - }, -}; diff --git a/src/constants/aboutUs/mission.ts b/src/constants/aboutUs/mission.ts deleted file mode 100644 index c25afbd0..00000000 --- a/src/constants/aboutUs/mission.ts +++ /dev/null @@ -1,32 +0,0 @@ -export const content = { - sectionId: 'mission', - title: { - prefix: 'Our', - highlighted: 'Mission', - }, - paragraphs: [ - 'Sugar Labs is dedicated to creating learning tools that transform how children learn and explore technology. Our mission is to, as a community of teachers and learners, create quality software and curriculae under a free/libre/open-source (FLO) license that encourages collaborative learning and creativity.', - 'We believe that every child deserves equal access to a robust set of learning tools regardless of their background or location. Our global network of teachers and learners work to imagine, design, and test our innovative learning tools for meaningful use in classrooms worldwide.', - "Our community-driven approach brings together educators, developers, and volunteers who are passionate about making a difference in education worldwide. Together, we're building tools that make learning engaging, accessible, and fun.", - ], - images: { - main: { - src: 'assets/Images/student3.png', - alt: 'Children using Sugar Labs software in a classroom', - }, - gallery: [ - { - src: 'assets/Images/student9.png', - alt: 'Students collaborating on a Sugar Labs project', - }, - { - src: 'assets/Images/teach4.png', - alt: 'Teacher helping students with Sugar Labs activities', - }, - { - src: 'assets/Images/student13.png', - alt: 'Children exploring creative software tools', - }, - ], - }, -}; diff --git a/src/constants/aboutUs/navigation.ts b/src/constants/aboutUs/navigation.ts deleted file mode 100644 index 5d3c0ce9..00000000 --- a/src/constants/aboutUs/navigation.ts +++ /dev/null @@ -1,36 +0,0 @@ -export interface NavigationSection { - id: string; - label: string; -} - -export const navigationSections: NavigationSection[] = [ - { id: 'mission', label: 'Our Mission' }, - { id: 'principles', label: 'Our Principles' }, - { id: 'goals', label: 'Our Goals' }, - { id: 'projects', label: 'Our Projects' }, - { id: 'roadmap', label: 'Our Roadmap' }, // -]; - -export const navigationConfig = { - scrollOffset: 20, - scrollDuration: 800, - stickyTopPosition: 70, - activeDetectionOffset: 100, - defaultActiveSection: 'mission', -}; - -export const navigationStyles = { - container: - 'sticky bg-white/90 backdrop-blur-md shadow-md rounded-lg p-4 mb-8 z-40 mt-16', - list: 'flex flex-wrap justify-center gap-4 md:gap-8', - button: { - base: 'px-4 py-2 rounded-md transition-all duration-300 text-sm md:text-base relative group hover:cursor-pointer', - active: 'text-red-500 font-medium', - inactive: 'text-gray-600 hover:text-red-500', - }, - indicator: { - base: 'absolute bottom-0 left-0 w-full h-0.5 bg-red-500 transform transition-all duration-300', - active: 'scale-x-100', - inactive: 'scale-x-0 group-hover:scale-x-100', - }, -}; diff --git a/src/constants/aboutUs/principles.ts b/src/constants/aboutUs/principles.ts deleted file mode 100644 index 88cc706e..00000000 --- a/src/constants/aboutUs/principles.ts +++ /dev/null @@ -1,62 +0,0 @@ -export interface Principle { - id: number; - title: string; - description: string; - image: string; -} - -export const principles: Principle[] = [ - { - id: 1, - title: 'Learning as a verb', - description: - 'Knowledge is a noun, learning is a verb. Instead of curating prescribed information to be instructed, we create tools for learning. Our methodology is called *Constructionism*.', - image: 'assets/Images/teach4.png', - }, - { - id: 2, - title: 'Free and open', - description: - 'We believe that learners can learn not just *with* their tools but also *from* their tools. This is why we distribute all our software and curriculae as free/libre/open (FLO)', - image: 'assets/Images/teach5.png', - }, - { - id: 3, - title: 'Equitable', - description: - 'By helping others learn and grow, we learn and grow as well. We also help make the world a better place for ourselves and others.', - image: 'assets/Images/teach6.png', - }, - { - id: 4, - title: 'Community led', - description: - 'We work with our friends, both locally and globally, to design and develop learning tools meaningful for their communities.', - image: 'assets/Images/student5.png', - }, - { - id: 5, - title: 'Accessible', - description: - 'We aim to make our learning tools accessible to as many youth as we possibly can.', - image: 'assets/Images/student7.png', - }, - { - id: 6, - title: 'Hard fun', - description: - 'Our work is challenging, but it’s also fun. We work hard to be playful and inspiring.', - image: 'assets/Images/student6.png', - }, -]; - -export const principlesContent = { - sectionId: 'principles', - title: { - prefix: 'Our', - highlight: 'Principles', - }, - description: - "Sugar Labs is founded on a set of fundamental principles that guide our work. We believe, for example, that learning is a verb, and we therefore create tools to learn with. We also believe in the freedom to study how one's tools work, and we therefore license all our work under a FLO license. Read on to learn more about our commitment to these principles, as well as our commitment to equity, community, accessibility, and hard fun.", - featuredImage: 'assets/Images/student11.png', -}; diff --git a/src/constants/aboutUs/projects.ts b/src/constants/aboutUs/projects.ts deleted file mode 100644 index 1a72d6a6..00000000 --- a/src/constants/aboutUs/projects.ts +++ /dev/null @@ -1,66 +0,0 @@ -export interface Project { - title: string; - description: string; - tags?: string[]; - imageUrl?: string; - progress?: number; - link?: string; - exlink?: string; -} - -export const projects: Project[] = [ - { - title: 'Sugar on a Stick (SoaS)', - description: - 'A USB version of the Sugar platform, an environment made for kids to learn and explore. It can be used to temporarily boot into SoaS or to install onto your computer.', - tags: ['Distribution', 'Portable'], - imageUrl: 'assets/Images/SOAS.jpeg', - link: '/bootablesoas', - }, - { - title: 'Google Summer of Code (GSoC)', - description: - 'GSoC is a global program, hosted by Google, focused on bringing more student developers into free/libre/open (FLO) software development.', - tags: ['Community', 'Development'], - imageUrl: 'assets/Images/GSOC.png', - exlink: - 'https://summerofcode.withgoogle.com/programs/2025/organizations/sugar-labs', - }, - { - title: 'Music Blocks', - description: - 'A visual programming language for exploring musical concepts. Based on the tried-and-true Logo programming language, you can blend art, geometry, and music to make challenging and fun creations.', - tags: ['Education', 'Creative'], - progress: 75, - imageUrl: 'assets/TryNowImages/musicBlocks1.png', - link: '/musicblocks', - }, - { - title: 'Sugarizer', - description: - 'Multi-platform implementation of the Sugar Learning Platform. Versions are available for the web, as well as for iOS, Android, Windows, and GNU/Linux.', - tags: ['Web', 'Mobile'], - progress: 80, - imageUrl: 'assets/TryNowImages/sugarizer.png', - link: '/sugarizer', - }, -]; - -export const projectIcons = [ - { color: 'bg-orange-100', icon: '🖥️', title: 'Sugar' }, - { color: 'bg-orange-200', icon: '🎵', title: 'Music Blocks' }, - { color: 'bg-orange-300', icon: '🌐', title: 'Sugarizer' }, - { color: 'bg-orange-100', icon: '🎮', title: 'Activities' }, -]; - -export const projectsContent = { - sectionId: 'projects', - title: { - prefix: 'Our', - highlight: 'Projects', - }, - description: - 'Sugar Labs develops and maintains several key projects that support our educational mission. These projects range from complete kid-friendly desktop environments to specific applications, each designed to enhance learning through technology.', - ctaText: 'Learn more', - displayProjectCount: 2, -}; diff --git a/src/constants/aboutUs/quickanswers.ts b/src/constants/aboutUs/quickanswers.ts deleted file mode 100644 index 92d91b5b..00000000 --- a/src/constants/aboutUs/quickanswers.ts +++ /dev/null @@ -1,33 +0,0 @@ -export const quickAnswers = [ - { - question: 'Is Music Blocks free to use?', - answer: 'Yes, Music Blocks is a 100% free to use, open sourced software.', - image: 'assets/QuickAnswers/cards.svg', - }, - { - question: 'What is Music Blocks?', - answer: - 'A visual programming language for creating music and learning coding.', - image: 'assets/QuickAnswers/Headset.svg', - }, - { - question: 'Can I use Sugar on any device?', - answer: 'Yes! It runs on Linux, Windows, macOS, and live USBs.', - image: 'assets/QuickAnswers/monitor-mobbile.svg', - }, - { - question: 'Who develops Sugar and Music Blocks?', - answer: 'Sugar Labs and a global open-source community.', - image: 'assets/QuickAnswers/people.svg', - }, - { - question: 'How can I contribute to Sugar Labs?', - answer: 'By coding, translating, designing, or writing docs!', - image: 'assets/QuickAnswers/task.svg', - }, - { - question: 'Is Sugar Labs a nonprofit?', - answer: 'Yes! It creates free, open-source educational software.', - image: 'assets/QuickAnswers/card-slash.svg', - }, -]; diff --git a/src/constants/aboutUs/roadmap.ts b/src/constants/aboutUs/roadmap.ts deleted file mode 100644 index bd763273..00000000 --- a/src/constants/aboutUs/roadmap.ts +++ /dev/null @@ -1,54 +0,0 @@ -export interface RoadmapItem { - title: string; - description?: string; - borderColor?: string; - backgroundColor?: string; - stepColor?: string; -} - -export const roadmapItems: RoadmapItem[] = [ - { - title: 'Mission, vision, values', - description: - 'Establishing our foundational principles, creating founding documents and holding elections to our Board of Directors.', - borderColor: 'border-red-500', - stepColor: 'bg-red-500', - }, - { - title: 'Community building', - description: - 'Work to establish a community of teachers and learners, maintaining ways that we can community and work together to solve problems.', - borderColor: 'border-red-400', - stepColor: 'bg-purple-500', - }, - { - title: 'Development of learning tools', - description: 'Design, develop, and deploy software tools for learning.', - borderColor: 'border-red-300', - stepColor: 'bg-blue-500', - }, - { - title: 'Study impact', - description: - 'Showcase student work, publish teacher and developer stories, and poll users to better understand our impact. Make adjustments based on results.', - borderColor: 'border-blue-400', - stepColor: 'bg-red-500', - }, - { - title: 'Strategic growth', - description: - 'Work with partners to broaden our reach and deepen our impact.', - borderColor: 'border-blue-500', - stepColor: 'bg-purple-500', - }, -]; - -export const roadmapContent = { - sectionId: 'roadmap', - title: { - prefix: 'Our', - highlight: 'Strategy', - }, - description: - 'Our strategic roadmap outlines our key milestones and future directions as we continue to grow and innovate.', -}; diff --git a/src/constants/matrixLinks.ts b/src/constants/matrixLinks.ts deleted file mode 100644 index bb93fe25..00000000 --- a/src/constants/matrixLinks.ts +++ /dev/null @@ -1,42 +0,0 @@ -export interface MatrixLink { - id: string; - title: string; - description: string; - url: string; - icon?: string; -} - -export const matrixLinks: MatrixLink[] = [ - { - id: 'organization', - title: 'Organization', - description: - "Discussion about our organization's projects, events, and planning.", - url: 'https://matrix.to/#/#sugar:matrix.org', - icon: 'building', - }, - { - id: 'webdev', - title: 'Web Development', - description: - 'Join our web development community room to discuss web technologies, frameworks, and best practices.', - url: 'https://matrix.to/#/#sugarlabs-web:matrix.org', - icon: 'code', - }, - { - id: 'mbdev', - title: 'Music Blocks Development', - description: - 'Music Blocks software development discussions and coding challenges.', - url: 'https://matrix.to/#/#musicblocksdev:matrix.org', - icon: 'terminal', - }, - { - id: 'sugarizerdev', - title: 'Sugarizer Development', - description: - 'Sugarizer software development discussions and coding challenges.', - url: 'https://matrix.to/#/#sugarizer:matrix.org', - icon: 'terminal', - }, -]; diff --git a/src/lib/utils.ts b/src/lib/utils.ts deleted file mode 100644 index 2819a830..00000000 --- a/src/lib/utils.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { clsx, type ClassValue } from 'clsx'; -import { twMerge } from 'tailwind-merge'; - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); -} diff --git a/src/main.tsx b/src/main.tsx deleted file mode 100644 index 5d7475a3..00000000 --- a/src/main.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import App from '@/App'; -import '@/styles/globals.css'; -import '@/utils/copy-code'; - -ReactDOM.createRoot(document.getElementById('root')!).render( - <React.StrictMode> - <App /> - </React.StrictMode>, -); diff --git a/src/pages/About/AboutUs.tsx b/src/pages/About/AboutUs.tsx deleted file mode 100644 index cafb4a03..00000000 --- a/src/pages/About/AboutUs.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useEffect, useState } from 'react'; -import { motion } from 'framer-motion'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import NavigationLinks from '@/components/shared/NavigationLinks'; -import HeroSection from '@/components/AboutUs/HeroSection'; -import TextMaskSection from '@/components/AboutUs/TextMaskSection'; -import MissionSection from '@/components/AboutUs/MissionSection'; -import PrinciplesSection from '@/components/AboutUs/PrinciplesSection'; -import GoalsSection from '@/components/AboutUs/GoalsSection'; -import ProjectsSection from '@/components/AboutUs/ProjectSection'; -import RoadmapSection from '@/components/AboutUs/RoadmapSection'; - -const AboutUs = () => { - const [, setIsLoaded] = useState(false); - - useEffect(() => { - setTimeout(() => setIsLoaded(true), 100); - }, []); - - return ( - <div className="bg-white min-h-screen"> - <div className="relative z-20"> - <Header /> - </div> - - <motion.main - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - transition={{ duration: 0.6 }} - className="w-full relative z-10" - > - <HeroSection /> - - <div className="w-full"> - <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> - <NavigationLinks /> - <TextMaskSection /> - </div> - </div> - - <MissionSection /> - - <div className="w-full"> - <PrinciplesSection /> - </div> - - <GoalsSection /> - - <div className="w-full"> - <ProjectsSection /> - </div> - - <RoadmapSection /> - </motion.main> - - <Footer /> - </div> - ); -}; - -export default AboutUs; diff --git a/src/pages/About/ContactUs.tsx b/src/pages/About/ContactUs.tsx deleted file mode 100644 index 8c9300d9..00000000 --- a/src/pages/About/ContactUs.tsx +++ /dev/null @@ -1,303 +0,0 @@ -import React from 'react'; -import { motion } from 'framer-motion'; -import { socialLinks } from '@/constants/Footer'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import { Link } from 'react-router-dom'; -import { - fadeIn, - slideInLeft, - slideInRight, - slideInBottom, - bounce, - staggerContainer, - subtleRise, - dividerVariants, -} from '@/styles/Animations'; - -const ContactUs: React.FC = () => { - return ( - <> - <Header /> - <div className="min-h-screen bg-gray-50"> - {/* Hero Section */} - <motion.section - variants={fadeIn} - initial="hidden" - animate="visible" - className="relative w-full bg-gradient-to-r from-blue-900 via-slate-800 to-slate-900 py-32 overflow-hidden" - > - <div className="absolute inset-0 overflow-hidden"> - <svg - className="absolute w-full h-full opacity-5" - viewBox="0 0 100 100" - preserveAspectRatio="none" - aria-hidden="true" - > - <defs> - <pattern - id="grid" - width="8" - height="8" - patternUnits="userSpaceOnUse" - > - <path - d="M 8 0 L 0 0 0 8" - fill="none" - stroke="white" - strokeWidth="0.5" - /> - </pattern> - </defs> - <rect x="0" y="0" width="100%" height="100%" fill="url(#grid)" /> - </svg> - </div> - - <div className="container mx-auto px-4 sm:px-6 lg:px-8 relative z-10"> - <motion.div - className="max-w-3xl" - variants={slideInBottom} - initial="hidden" - animate="visible" - > - <motion.h1 - className="text-4xl md:text-5xl font-bold text-white mb-4 tracking-tight" - variants={slideInBottom} - initial="hidden" - animate="visible" - > - Contact <span className="text-blue-200">Sugar Labs</span> - </motion.h1> - <motion.div - className="w-20 h-1 bg-blue-400 mb-6" - variants={dividerVariants} - initial="hidden" - animate="visible" - ></motion.div> - <motion.p - className="text-base md:text-lg text-gray-200 max-w-2xl leading-relaxed" - variants={fadeIn} - initial="hidden" - animate="visible" - transition={{ delay: 0.3 }} - > - We'd love to hear from you. Here's how you can reach our team of - educational innovators. - </motion.p> - </motion.div> - </div> - </motion.section> - - {/* Main Content */} - <section className="container mx-auto px-4 sm:px-6 lg:px-8 py-12 md:py-20"> - <div className="grid grid-cols-1 lg:grid-cols-12 gap-6 md:gap-8"> - {/* Contact Information Card */} - <motion.div - className="lg:col-span-7 bg-white rounded-xl shadow-md overflow-hidden border border-gray-200 transition-shadow duration-300 hover:shadow-lg" - variants={slideInLeft} - initial="hidden" - animate="visible" - whileHover={{ y: -5 }} - transition={{ duration: 0.3 }} - > - <div className="p-6 md:p-8 lg:p-10"> - <motion.h2 - className="text-2xl font-bold text-gray-800 mb-8 flex items-center" - variants={fadeIn} - initial="hidden" - animate="visible" - > - <span className="w-1.5 h-6 bg-blue-600 mr-3 rounded-sm"></span> - How to Reach Us - </motion.h2> - - <motion.div - className="grid grid-cols-1 md:grid-cols-2 gap-y-8 gap-x-6 lg:gap-x-8" - variants={staggerContainer} - initial="hidden" - animate="visible" - > - {/* Mail Address */} - <ContactMethod - iconSrc="assets/Icons/mail.svg" - title="By Mail" - description={ - <address className="mt-2 not-italic text-gray-600 leading-relaxed text-sm"> - Sugar Labs - <br /> - 2028 E Ben White Blvd <b>STE 240 PMB 1271</b> - <br /> - AUSTIN, TX 78741 - <br /> - USA - </address> - } - /> - - {/* Phone */} - <ContactMethod - iconSrc="assets/Icons/phone.svg" - title="By Phone" - description={ - <a - href="tel:+16177024088" - className="mt-2 text-gray-600 hover:text-blue-600 transition duration-200 block text-sm" - > - +1 (617) 702-4088 - </a> - } - /> - - {/* Email */} - <ContactMethod - iconSrc="assets/Icons/email.svg" - title="By Email" - description={ - <a - href="mailto:info@sugarlabs.org" - className="mt-2 text-gray-600 hover:text-blue-600 transition duration-200 block text-sm" - > - info@sugarlabs.org - </a> - } - /> - - {/* Matrix Chat */} - <ContactMethod - iconSrc="assets/Icons/chat.svg" - title="Via Matrix Chat" - description={ - <Link - to="matrix" - className="mt-2 text-gray-600 hover:text-blue-600 transition duration-200 block text-sm" - > - Go to Matrix Chat - </Link> - } - /> - </motion.div> - </div> - </motion.div> - - {/* Social Connect Card */} - <motion.div - className="lg:col-span-5 rounded-xl overflow-hidden shadow-md" - variants={slideInRight} - initial="hidden" - animate="visible" - whileHover={{ y: -5 }} - transition={{ duration: 0.3 }} - > - <div className="bg-gradient-to-br from-gray-800 via-gray-850 to-gray-900 p-6 md:p-8 lg:p-10"> - <motion.h2 - className="text-2xl font-bold text-white mb-6 flex items-center" - variants={fadeIn} - initial="hidden" - animate="visible" - > - <span className="w-1.5 h-6 bg-blue-500 mr-3 rounded-sm"></span> - Connect With The Community - </motion.h2> - - <motion.p - className="text-gray-300 text-sm leading-relaxed mb-8" - variants={fadeIn} - initial="hidden" - animate="visible" - transition={{ delay: 0.2 }} - > - Join our global community of educators, developers, and - learners who are passionate about bringing educational - software to children around the world. - </motion.p> - - <motion.div - className="grid grid-cols-2 sm:grid-cols-3 gap-4 mb-6" - variants={staggerContainer} - initial="hidden" - animate="visible" - > - {socialLinks.map((social, index) => ( - <motion.a - key={social.href} - href={social.href} - target="_blank" - rel="noopener noreferrer" - aria-label={`Visit our ${social.name} page`} - className="group flex flex-col items-center" - variants={bounce} - whileHover="hover" - whileTap="tap" - custom={index} - > - <div className="flex items-center justify-center w-12 h-12 bg-white/10 group-hover:bg-white/20 rounded-lg backdrop-blur-sm transition-all duration-300 ease-in-out mb-2 border border-gray-700/50 shadow-sm group-hover:shadow-blue-500/10 group-hover:shadow-md"> - <img - src={social.icon} - alt="" - width={20} - height={20} - className="filter brightness-0 invert opacity-90" - aria-hidden="true" - /> - </div> - <span className="text-xs text-gray-300 group-hover:text-gray-200 transition-colors duration-200"> - {social.name} - </span> - </motion.a> - ))} - </motion.div> - </div> - - <motion.div - className="bg-gray-800 p-5 md:p-6 border-t border-gray-700/50" - variants={fadeIn} - initial="hidden" - animate="visible" - transition={{ delay: 0.4 }} - > - <h3 className="text-xs uppercase font-bold text-gray-300 tracking-wider mb-2"> - Follow Our Progress - </h3> - <p className="text-xs text-gray-400 leading-relaxed"> - Stay updated with our latest developments and educational - initiatives. - </p> - </motion.div> - </motion.div> - </div> - </section> - </div> - <Footer /> - </> - ); -}; - -interface ContactMethodProps { - iconSrc: string; - title: string; - description: React.ReactNode; -} - -const ContactMethod: React.FC<ContactMethodProps> = ({ - iconSrc, - title, - description, -}) => ( - <motion.div className="flex items-start" variants={subtleRise}> - <motion.div - className="flex-shrink-0 p-3 bg-blue-50 rounded-lg text-blue-600 border border-blue-100" - whileHover={{ scale: 1.1 }} - transition={{ type: 'spring', stiffness: 400, damping: 10 }} - > - <img src={iconSrc} alt="" className="h-5 w-5" aria-hidden="true" /> - </motion.div> - <div className="ml-4"> - <h3 className="text-sm font-bold text-gray-800 uppercase tracking-wider"> - {title} - </h3> - {description} - </div> - </motion.div> -); - -export default ContactUs; diff --git a/src/pages/About/FAQs.tsx b/src/pages/About/FAQs.tsx deleted file mode 100644 index 77ec184e..00000000 --- a/src/pages/About/FAQs.tsx +++ /dev/null @@ -1,207 +0,0 @@ -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import { useEffect, useState } from 'react'; -import { stats } from '@/constants/Stats'; -import faqs, { FAQ_CATEGORIES } from '@/constants/aboutUs/faqs'; -import { quickAnswers } from '@/constants/aboutUs/quickanswers'; -import { motion } from 'framer-motion'; -import { - fadeIn, - slideInLeft, - slideInRight, - subtleRise, - headerReveal, - faqPageAnimations, -} from '@/styles/Animations'; -import FAQItem from '@/components/FAQItem'; - -const FAQs = () => { - const [selectedCategory, setSelectedCategory] = useState<string>('all'); - const [filteredFaqs, setFilteredFaqs] = useState(faqs); - - useEffect(() => { - const filtered = - selectedCategory === 'all' - ? faqs - : faqs.filter((faq) => faq.category === selectedCategory); - setFilteredFaqs(filtered); - }, [selectedCategory]); - - return ( - <div className="min-h-screen bg-white text-gray-900"> - <Header /> - <main className="container mx-auto p-4"> - {/* Top FAQs Section */} - <motion.section - className="my-8 flex justify-center" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.3 }} - variants={faqPageAnimations.pageSection} - > - <div className="max-w-4xl w-4/5 flex flex-col md:flex-row justify-between items-center"> - {/* Left Side - Text */} - <motion.div - className="md:w-1/2 text-left md:pr-8" - variants={slideInLeft} - > - <motion.h1 - className="text-4xl font-bold" - variants={faqPageAnimations.headingText} - > - FAQs - </motion.h1> - <motion.p - className="text-gray-600 mt-2 text-lg" - variants={faqPageAnimations.paragraphText} - > - Have questions? Here you'll find the answers most valued by our - partners, along with access to step-by-step instructions and - support. - </motion.p> - </motion.div> - - {/* Right Side - Enlarged Image */} - <motion.div - className="md:w-1/2 flex justify-end" - variants={slideInRight} - > - <motion.img - src={stats.faq} - alt="FAQs Illustration" - className="w-80 md:w-[400px] lg:w-[500px]" - variants={faqPageAnimations.heroImage} - whileHover="hover" - /> - </motion.div> - </div> - </motion.section> - - {/* FAQ Sections Container */} - <div className="w-4/5 max-w-5xl mx-auto"> - {/* Quick Answers */} - <motion.section - className="my-10" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - variants={fadeIn} - > - <motion.h2 - className="text-3xl font-bold mb-6" - variants={headerReveal} - > - Quick Answers - </motion.h2> - <motion.div - className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mt-6" - variants={faqPageAnimations.quickAnswersContainer} - > - {quickAnswers.map((qa, index) => ( - <motion.div - key={index} - className="bg-white shadow-lg rounded-2xl p-6 flex flex-col items-center border border-gray-200" - variants={faqPageAnimations.quickAnswerCard} - whileHover="hover" - whileTap="tap" - > - <motion.div - className="w-12 h-12 bg-white flex items-center justify-center rounded-lg mb-4" - variants={faqPageAnimations.quickAnswerIcon} - custom={index} - > - <img src={qa.image} alt={qa.question} className="w-6 h-6" /> - </motion.div> - <h3 className="font-semibold text-center">{qa.question}</h3> - <p className="text-gray-600 text-sm text-center mt-2"> - {qa.answer} - </p> - </motion.div> - ))} - </motion.div> - </motion.section> - - {/* Category Filter Section */} - <motion.section - className="my-8 max-w-5xl mx-auto" - initial="hidden" - whileInView="visible" - viewport={{ once: true }} - variants={fadeIn} - > - <motion.h2 - className="text-2xl font-bold mb-4" - variants={headerReveal} - > - Filter by Category - </motion.h2> - <div className="flex flex-wrap gap-3"> - <button - onClick={() => setSelectedCategory('all')} - className={`px-4 py-2 rounded-full transition-all ${ - selectedCategory === 'all' - ? 'bg-blue-600 text-white cursor-pointer' - : 'bg-gray-200 hover:bg-gray-300 cursor-pointer' - }`} - > - All - </button> - {FAQ_CATEGORIES.filter((cat) => cat !== 'all').map((category) => ( - <button - key={category} - onClick={() => setSelectedCategory(category)} - className={`px-4 py-2 rounded-full transition-all capitalize ${ - selectedCategory === category - ? 'bg-blue-600 text-white cursor-pointer' - : 'bg-gray-200 hover:bg-gray-300 cursor-pointer' - }`} - > - {category} - </button> - ))} - </div> - </motion.section> - {/* Categorized FAQs */} - <motion.section - className="my-10" - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - variants={faqPageAnimations.faqContainer} - > - <motion.h2 - className="text-3xl font-bold mb-6 capitalize" - variants={headerReveal} - > - {selectedCategory === 'all' - ? 'All FAQs' - : `${selectedCategory} FAQs`} - </motion.h2> - <motion.div - className="bg-white shadow-lg rounded-lg p-6" - variants={subtleRise} - > - {filteredFaqs.length > 0 ? ( - filteredFaqs.map((faq, index) => ( - <FAQItem - key={index} - question={faq.question} - answer={faq.answer} - index={index} - /> - )) - ) : ( - <p className="text-center text-gray-600 py-4"> - No FAQs found for this category. - </p> - )} - </motion.div> - </motion.section> - </div> - </main> - <Footer /> - </div> - ); -}; - -export default FAQs; diff --git a/src/pages/About/Leadership.tsx b/src/pages/About/Leadership.tsx deleted file mode 100644 index 906c1151..00000000 --- a/src/pages/About/Leadership.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { motion } from 'framer-motion'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import DirectorCard from '@/components/DirectorCard'; -import { directors } from '@/constants/Leadership'; -import { - simpleFadeIn, - container, - item, - testimonialHeading, - decorativeElement, - dividerVariants, -} from '@/styles/Animations'; - -const Leadership = () => { - return ( - <div> - <Header /> - <section className="py-24 px-4 bg-white"> - <div className="container mx-auto max-w-7xl"> - {/* Section header with animations */} - <div className="text-center mb-16"> - <motion.h2 - className="text-4xl md:text-5xl font-bold text-gray-900 mb-4" - initial="hidden" - whileInView="visible" - viewport={{ once: true }} - variants={testimonialHeading} - > - <motion.span - className="text-red-500 font-Pacifico" - variants={decorativeElement} - initial="hidden" - whileInView="visible" - viewport={{ once: true }} - > - Meet{' '} - </motion.span> - Our Board of Directors - </motion.h2> - - <div className="flex justify-center"> - <motion.div - className="h-1 bg-red-500 mb-8" - initial="hidden" - whileInView="visible" - viewport={{ once: true }} - variants={dividerVariants} - ></motion.div> - </div> - - <motion.p - className="text-lg text-gray-600 max-w-3xl mx-auto" - initial="hidden" - whileInView="visible" - viewport={{ once: true }} - variants={simpleFadeIn} - > - The "Sugar Labs Board of Directors" consists of dedicated six - individuals who guide our organization's mission to provide - educational tools for children worldwide. They bring diverse - expertise in education, technology, and nonprofit leadership. - </motion.p> - </div> - - {/* Directors grid with equal height cards */} - <motion.div - className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8" - variants={container} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.1 }} - > - {directors.map((director) => ( - <motion.div - key={director.id} - className="h-full" - variants={item} - whileHover="hover" - > - <DirectorCard director={director} /> - </motion.div> - ))} - </motion.div> - </div> - </section> - <Footer /> - </div> - ); -}; - -export default Leadership; diff --git a/src/pages/Contributors.tsx b/src/pages/Contributors.tsx deleted file mode 100644 index 0ee55662..00000000 --- a/src/pages/Contributors.tsx +++ /dev/null @@ -1,424 +0,0 @@ -import React, { useState, useEffect, useCallback, useMemo } from 'react'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import axios from 'axios'; -import { motion, AnimatePresence } from 'framer-motion'; -import { - Search, - Star, - GitFork, - Calendar, - Code, - Users, - ExternalLink, -} from 'lucide-react'; -import { fadeIn, staggerContainer } from '@/styles/Animations'; - -interface Repository { - id: number; - name: string; - full_name: string; - html_url: string; - description: string; - stargazers_count: number; - forks_count: number; - updated_at: string; -} - -interface Contributor { - login: string; - id: number; - avatar_url: string; - html_url: string; - contributions: number; -} - -const Contributors: React.FC = () => { - const [repos, setRepos] = useState<Repository[]>([]); - const [filteredRepos, setFilteredRepos] = useState<Repository[]>([]); - const [searchTerm, setSearchTerm] = useState<string>(''); - const [selectedRepo, setSelectedRepo] = useState<string | null>(null); - const [contributors, setContributors] = useState<Contributor[]>([]); - const [loading, setLoading] = useState<boolean>(false); - const [repoLoading, setRepoLoading] = useState<boolean>(true); - const [error, setError] = useState<string | null>(null); - - const fetchAllRepos = useCallback(async () => { - setRepoLoading(true); - setError(null); - - try { - let allRepos: Repository[] = []; - let page = 1; - let hasMore = true; - - while (hasMore) { - const response = await axios.get( - `https://api.github.com/orgs/sugarlabs/repos?per_page=100&page=${page}&sort=updated&direction=desc`, - ); - - if (response.data.length === 0) { - hasMore = false; - } else { - allRepos = [...allRepos, ...response.data]; - page++; - } - } - - setRepos(allRepos); - setFilteredRepos(allRepos); - } catch (error) { - console.error('Error fetching repositories:', error); - setError('Failed to load repositories. Please try again later.'); - } finally { - setRepoLoading(false); - } - }, []); - - const fetchAllContributors = useCallback(async (repoName: string) => { - setLoading(true); - setError(null); - - try { - let allContributors: Contributor[] = []; - let page = 1; - let hasMore = true; - - while (hasMore) { - const response = await axios.get( - `https://api.github.com/repos/sugarlabs/${repoName}/contributors?per_page=100&page=${page}`, - ); - - if (response.data.length === 0) { - hasMore = false; - } else { - allContributors = [...allContributors, ...response.data]; - page++; - } - } - - setContributors(allContributors); - } catch (error) { - console.error('Error fetching contributors:', error); - setError('Failed to load contributors. Please try again later.'); - } finally { - setLoading(false); - } - }, []); - - useEffect(() => { - fetchAllRepos(); - }, [fetchAllRepos]); - - useEffect(() => { - const filtered = repos.filter( - (repo) => - repo.name.toLowerCase().includes(searchTerm.toLowerCase()) || - (repo.description && - repo.description.toLowerCase().includes(searchTerm.toLowerCase())), - ); - setFilteredRepos(filtered); - }, [searchTerm, repos]); - - useEffect(() => { - if (!selectedRepo) { - setContributors([]); - return; - } - - fetchAllContributors(selectedRepo); - }, [selectedRepo, fetchAllContributors]); - - const handleRepoClick = useCallback((repoName: string) => { - setSelectedRepo(repoName); - }, []); - - const formatDate = useCallback((dateString: string) => { - const date = new Date(dateString); - return date.toLocaleDateString(); - }, []); - - const repositoryList = useMemo(() => { - if (repoLoading) { - return ( - <div className="flex items-center justify-center h-40"> - <div className="animate-spin rounded-full h-10 w-10 border-b-2 border-[#D4B062]"></div> - </div> - ); - } - - if (error) { - return <div className="text-red-500 text-center py-10">{error}</div>; - } - - if (repos.length === 0) { - return ( - <p className="text-gray-500 text-center py-10">No repositories found</p> - ); - } - - if (filteredRepos.length === 0) { - return ( - <p className="text-gray-500 text-center py-10"> - No repositories match your search - </p> - ); - } - - return ( - <div className="space-y-3 max-h-[65vh] overflow-y-auto pr-1 -mx-2 px-2"> - <AnimatePresence> - {filteredRepos.map((repo) => ( - <motion.div - key={repo.id} - whileHover="hover" - onClick={() => handleRepoClick(repo.name)} - className={`p-4 rounded-lg cursor-pointer transition duration-300 border-l-4 ${ - selectedRepo === repo.name - ? 'bg-[#D4B062]/10 border-[#D4B062]' - : 'hover:bg-gray-50 border-transparent hover:border-gray-200' - }`} - > - <h3 className="font-medium text-lg text-gray-800 break-words"> - {repo.name} - </h3> - <p className="text-sm text-gray-600 line-clamp-2 mt-1"> - {repo.description || 'No description'} - </p> - <div className="mt-3 flex flex-wrap gap-3 text-xs text-gray-500"> - <span className="flex items-center gap-1"> - <Star className="h-3.5 w-3.5 text-[#D4B062]" />{' '} - {repo.stargazers_count} - </span> - <span className="flex items-center gap-1"> - <GitFork className="h-3.5 w-3.5 text-[#D4B062]" />{' '} - {repo.forks_count} - </span> - <span className="flex items-center gap-1"> - <Calendar className="h-3.5 w-3.5 text-[#D4B062]" />{' '} - {formatDate(repo.updated_at)} - </span> - </div> - </motion.div> - ))} - </AnimatePresence> - </div> - ); - }, [ - repoLoading, - error, - repos, - filteredRepos, - selectedRepo, - handleRepoClick, - formatDate, - ]); - - const contributorsList = useMemo(() => { - if (!selectedRepo) { - return ( - <div className="flex flex-col items-center justify-center h-full min-h-[400px] text-center py-12"> - <Users className="h-16 w-16 text-gray-300 mb-4" /> - <p className="text-gray-500 max-w-xs"> - Select a repository from the list to view its contributors - </p> - </div> - ); - } - - if (loading) { - return ( - <div className="flex items-center justify-center h-64"> - <div className="animate-spin rounded-full h-10 w-10 border-b-2 border-[#D4B062]"></div> - </div> - ); - } - - if (error) { - return <div className="text-red-500 text-center py-10">{error}</div>; - } - - if (contributors.length === 0) { - return ( - <div className="flex flex-col items-center justify-center h-64 text-center"> - <Users className="h-16 w-16 text-gray-300 mb-4" /> - <p className="text-gray-500"> - No contributors found for this repository - </p> - </div> - ); - } - - return ( - <> - <p className="text-sm text-gray-500 mb-4"> - Showing all {contributors.length} contributors - </p> - <div className="max-h-[65vh] overflow-y-auto pr-1"> - <motion.div - variants={staggerContainer} - className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4" - > - {contributors.map((contributor) => ( - <motion.a - key={contributor.id} - whileHover="hover" - href={contributor.html_url} - target="_blank" - rel="noopener noreferrer" - className="group flex flex-col items-center p-5 bg-gray-50 rounded-lg transition duration-300 hover:bg-[#D4B062]/5 hover:shadow-md border border-gray-100" - > - <div className="relative mb-3"> - <img - src={contributor.avatar_url} - alt={`${contributor.login}'s avatar`} - className="w-16 h-16 rounded-full object-cover border-2 border-white shadow-sm" - onError={(e) => { - (e.target as HTMLImageElement).src = - 'https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png'; - }} - /> - <div className="absolute -bottom-1 -right-4 bg-[#D4B062] text-xs text-white font-bold rounded-full w-9 h-6 flex items-center justify-center"> - {contributor.contributions > 500 - ? '500+' - : contributor.contributions} - </div> - </div> - <h3 className="font-medium text-gray-800 text-center break-words w-full"> - {contributor.login} - </h3> - <div className="mt-2 flex items-center text-xs text-[#D4B062] opacity-0 group-hover:opacity-100 transition-opacity"> - View Profile <ExternalLink className="ml-1 h-3 w-3" /> - </div> - </motion.a> - ))} - </motion.div> - </div> - </> - ); - }, [selectedRepo, loading, error, contributors]); - - return ( - <> - <Header /> - <div className="min-h-screen flex flex-col font-sans bg-[#FFFEF9]"> - {/* Hero Section */} - <motion.section - initial="hidden" - animate="visible" - variants={fadeIn} - className="relative py-16 sm:py-20 overflow-hidden bg-gradient-to-b from-black via-gray-800 to-gray-600" - > - <div className="absolute inset-0 z-0 overflow-hidden"> - <div className="absolute inset-0 opacity-10"></div> - <div - className="absolute inset-0" - style={{ - backgroundImage: - 'radial-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1px)', - backgroundSize: '20px 20px', - }} - ></div> - </div> - <div className="container mx-auto px-4 md:px-6"> - <div className="flex flex-col items-center text-center z-10 relative"> - <motion.h1 - className="font-black text-4xl sm:text-5xl md:text-6xl mb-4 sm:mb-6 text-white" - initial={{ opacity: 0, y: -20 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.8 }} - > - Sugar Labs <span className="text-[#D4B062]">Developers</span> - </motion.h1> - <motion.div - className="w-16 sm:w-24 h-1 bg-[#D4B062] mb-4 sm:mb-6 rounded-full" - initial={{ width: 0 }} - animate={{ width: 96 }} - transition={{ duration: 0.8, delay: 0.3 }} - ></motion.div> - <motion.p - className="text-base sm:text-lg md:text-xl mb-8 sm:mb-10 text-gray-300 max-w-2xl leading-relaxed px-4" - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - transition={{ duration: 0.8, delay: 0.5 }} - > - Explore Sugar Labs repositories and their contributors. Browse - our open source projects and discover the developers behind - them. - </motion.p> - </div> - </div> - </motion.section> - - <div className="container mx-auto px-4 py-12"> - {/* Search input */} - <motion.div - initial={{ opacity: 0, y: 20 }} - animate={{ opacity: 1, y: 0 }} - transition={{ delay: 0.3 }} - className="max-w-md mx-auto mb-8 relative" - > - <div className="relative"> - <input - type="text" - placeholder="Search repositories..." - value={searchTerm} - onChange={(e) => setSearchTerm(e.target.value)} - className="w-full px-4 py-3 pl-12 border border-gray-200 rounded-full focus:outline-none focus:ring-2 focus:ring-[#D4B062] shadow-sm bg-white text-gray-700" - /> - <Search className="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400 h-5 w-5" /> - </div> - <p className="text-sm text-gray-500 mt-2 text-center"> - Showing {filteredRepos.length} repositories. - </p> - </motion.div> - - <div className="grid grid-cols-1 lg:grid-cols-12 gap-8"> - {/* Repositories List */} - <motion.div - initial="hidden" - animate="visible" - variants={staggerContainer} - className="lg:col-span-5 bg-white rounded-xl shadow-md p-6 overflow-hidden border border-gray-100" - > - <div className="flex items-center gap-3 mb-6"> - <div className="bg-[#D4B062] p-3 rounded-full text-white"> - <Code className="h-5 w-5" /> - </div> - <h2 className="text-2xl font-bold text-gray-800"> - Repositories - </h2> - </div> - - {repositoryList} - </motion.div> - - {/* Contributors List */} - <motion.div - initial="hidden" - animate="visible" - variants={staggerContainer} - className="lg:col-span-7 bg-white rounded-xl shadow-md p-6 overflow-hidden border border-gray-100" - > - <div className="flex items-center gap-3 mb-6"> - <div className="bg-[#D4B062] p-3 rounded-full text-white"> - <Users className="h-5 w-5" /> - </div> - <h2 className="text-2xl font-bold text-gray-800"> - {selectedRepo - ? `Contributors for ${selectedRepo}` - : 'Select a repository'} - </h2> - </div> - - {contributorsList} - </motion.div> - </div> - </div> - </div> - <Footer /> - </> - ); -}; - -export default Contributors; diff --git a/src/pages/Donate.tsx b/src/pages/Donate.tsx deleted file mode 100644 index 37441ca0..00000000 --- a/src/pages/Donate.tsx +++ /dev/null @@ -1,306 +0,0 @@ -import React, { useState } from 'react'; -import { - IMPACT_STATS, - FINANCIAL_FILINGS, - donationData, - Img, -} from '@/constants/Donation'; -import { - slideInLeft, - slideInRight, - slideInBottom, - buttonAnimation, -} from '@/styles/Animations'; -import Footer from '@/sections/Footer'; -import Header from '@/sections/Header'; -import { motion } from 'framer-motion'; - -const Donate: React.FC = () => { - const [showAllFilings, setShowAllFilings] = useState(false); - const initialFilingsToShow = 5; - const hasMoreFilings = FINANCIAL_FILINGS.length > initialFilingsToShow; - - const visibleFilings = showAllFilings - ? FINANCIAL_FILINGS - : FINANCIAL_FILINGS.slice(0, initialFilingsToShow); - - return ( - <> - <Header /> - <div className="max-w-6xl mx-auto px-4 sm:px-6 font-sans mt-10 sm:mt-10 mb-10 sm:mb-16"> - {/* Hero Section */} - <div className="flex flex-col md:flex-row gap-6 md:gap-10 mt-10"> - {/* Left Column with Heading and Buttons */} - <motion.div - className="flex-1 order-2 md:order-1" - variants={slideInLeft} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <h1 className="text-3xl sm:text-4xl font-bold mb-4 sm:mb-6"> - Make a Lasting <span className="text-red-500">Impact</span> in - Education - </h1> - - <p className="text-gray-700 mb-6 sm:mb-8 text-base sm:text-lg"> - A financial contribution to Sugar Labs is an investment in - education. Your tax-deductible donation helps us create innovative - tools for teaching and learning while mentoring budding developers - from around the world. - </p> - - <motion.div - className="flex flex-wrap gap-4 mb-6 sm:mb-8" - variants={buttonAnimation} - whileHover="hover" - whileTap="tap" - > - <a href={donationData.url} target="_blank" rel="noreferrer"> - <button className="bg-green-600 hover:bg-green-700 cursor-pointer transition-colors text-white px-6 sm:px-8 py-2 sm:py-3 rounded-full font-medium shadow-md"> - Donate Now - </button> - </a> - </motion.div> - - <div className="bg-gray-100 p-4 rounded-lg border-l-4 border-blue-500 shadow-sm text-xs sm:text-sm"> - <p className="text-gray-600"> - Your donation is tax-deductible in the United States as Sugar - Labs is a registered 501(c)(3) nonprofit organization. - </p> - </div> - </motion.div> - - {/* Right Column with Image */} - <motion.div - className="flex-1 order-1 md:order-2 mb-6 md:mb-0" - variants={slideInRight} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <img - src={Img[0]} - alt="Children asking for donations" - className="w-full rounded-lg shadow-lg object-cover h-64 sm:h-full" - /> - </motion.div> - </div> - - {/* Impact Statement Section */} - <motion.div - className="my-10 sm:my-16 bg-gradient-to-r from-blue-50 to-green-50 p-5 sm:p-8 rounded-xl shadow-sm" - variants={slideInBottom} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <h2 className="text-2xl sm:text-3xl font-bold mb-4 sm:mb-6 text-center"> - Your Donation Directly Assists Our Mission - </h2> - - <div className="prose prose-base sm:prose-lg max-w-none"> - <p className="mb-4"> - Despite the fact that computers, and the software on those - computers, run the way much of the world works, there still - remains very little support in education, especially at the levels - of primary and secondary schooling, to cultivate a computationally - literate society. Despite initiatives, a mere "day of code," - sometimes as little as "an hour of code," is woefully insufficient - to instill computational literacy in a generation of young - learners. - </p> - - <p className="mb-4"> - Sugar Labs, as an organization, and the suite of apps, curriculum, - rubrics, and mentoring, is well poised to bridge the gap for many - learners in the US and around the world - the gap between - educational services provided and what youth need developmentally - to succeed. - </p> - </div> - </motion.div> - - {/* Why Your Support Matters */} - <motion.div - className="my-10 sm:my-16" - variants={slideInBottom} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <h2 className="text-2xl sm:text-3xl font-bold mb-6 sm:mb-8 text-center"> - How Your Donation Makes a Difference - </h2> - - <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 sm:gap-8"> - {IMPACT_STATS.map((stat) => ( - <div - key={stat.title} - className="bg-white p-5 sm:p-6 rounded-lg shadow-md border border-gray-100" - > - <div className="text-green-500 text-3xl sm:text-4xl font-bold mb-2 sm:mb-3"> - {stat.value} - </div> - <h3 className="text-lg sm:text-xl font-semibold mb-2"> - {stat.title} - </h3> - <p className="text-gray-700 text-sm sm:text-base"> - {stat.description} - </p> - </div> - ))} - </div> - </motion.div> - - {/* Mission Statement */} - <motion.div - className="my-10 sm:my-16" - variants={slideInBottom} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <div className="bg-gray-50 p-5 sm:p-6 rounded-lg shadow-sm border border-gray-100"> - <h2 className="text-xl sm:text-2xl font-semibold mb-3 sm:mb-4 text-gray-800"> - Our Mission - </h2> - <p className="text-gray-800 text-xs sm:text-sm leading-relaxed mb-5 sm:mb-6"> - Sugar Labs® is a US-based 501(c)(3) nonprofit organization with a - global mission to create educational opportunities in technology - to youth around the world. Volunteer mentors and contributors work - together to develop activity- focused software for children. All - software is developed with learning as the primary goal, - necessitating the need for source code to be published publicly - for study — worked upon openly within a community where students - are invited to make contributions under guidance of experienced - mentors. - </p> - - <div className="mt-4 sm:mt-6"> - <a - href={donationData.url} - target="_blank" - rel="noreferrer" - className="text-green-600 hover:text-green-700 font-medium flex items-center text-sm sm:text-base" - > - Help support our mission - <img src={Img[1]} alt="Right Arrow" className="h-4 w-4 ml-1" /> - </a> - </div> - </div> - </motion.div> - - {/* Financial Transparency Section */} - <motion.div - className="my-10 sm:my-16" - id="financial-transparency" - variants={slideInBottom} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <h2 className="text-2xl sm:text-3xl font-bold mb-6 sm:mb-8 text-center"> - Financial Transparency - </h2> - - <div className="bg-white p-5 sm:p-8 rounded-xl shadow-md"> - <p className="mb-5 sm:mb-6 text-sm sm:text-base"> - Sugar Labs is committed to full financial transparency. As a - 501(c)(3) nonprofit organization, we make our tax filings - available for public review. - </p> - - <h3 className="text-lg sm:text-xl font-semibold mb-3 sm:mb-4"> - Our 990 Tax Filings - </h3> - - <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3 sm:gap-4"> - {visibleFilings.map((filing) => ( - <a - key={filing.year} - href={filing.link} - className="bg-gray-50 hover:bg-gray-100 transition-colors p-3 sm:p-4 rounded-lg flex flex-col items-center text-center" - target="_blank" - rel="noreferrer" - > - <img src={Img[2]} alt="PDF Icon" className="h-8 w-8 mb-2" /> - <span className="font-medium text-xs sm:text-sm"> - {filing.year} Filings - </span> - </a> - ))} - </div> - - {/* Show More Button */} - {hasMoreFilings && !showAllFilings && ( - <div className="mt-6 flex justify-center"> - <button - onClick={() => setShowAllFilings(true)} - className="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-md text-sm font-medium flex items-center" - > - Show More - </button> - </div> - )} - - <div className="mt-6 sm:mt-8 p-3 sm:p-4 bg-gray-50 rounded-lg border border-gray-200"> - <h4 className="font-medium mb-2 text-sm sm:text-base"> - Note about 2018 and earlier - </h4> - <p className="text-xs sm:text-sm text-gray-700"> - Sugar Labs Inc. received its 501(c)(3) nonprofit status in 2020. - Before 2019, Sugar Labs was a member organization under Software - Freedom Conservancy. To view our archived financial data from - before 2019, please visit:{' '} - <a - href="https://wiki.sugarlabs.org/go/Finance" - className="text-blue-600 hover:underline" - > - https://wiki.sugarlabs.org/go/Finance - </a> - </p> - </div> - </div> - </motion.div> - - {/* Donation Section */} - <motion.div - className="my-10 sm:my-16 bg-green-50 p-5 sm:p-8 rounded-xl shadow-sm" - id="donate-section" - variants={slideInBottom} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <h2 className="text-2xl sm:text-3xl font-bold mb-4 sm:mb-6 text-center"> - Support Our Mission Today - </h2> - - <p className="text-center max-w-3xl mx-auto mb-6 sm:mb-8 text-sm sm:text-base"> - Financial contributions to Sugar Labs helps us continue to create - and maintain innovative tools for learning, as well as mentor youth - at a critical point in their development. Your support makes a - meaningful difference in the lives of children around the world. - </p> - - <div className="flex justify-center gap-3 sm:gap-4 flex-wrap"> - <a href={donationData.url} target="_blank" rel="noreferrer"> - <button className="bg-green-600 hover:bg-green-700 cursor-pointer transition-colors text-white px-5 sm:px-8 py-2 sm:py-3 rounded-full font-medium shadow-md text-sm sm:text-base"> - Make a One-Time Donation - </button> - </a> - <a href={donationData.urlMonth} target="_blank" rel="noreferrer"> - <button className="bg-blue-600 hover:bg-blue-700 cursor-pointer transition-colors text-white px-5 sm:px-8 py-2 sm:py-3 rounded-full font-medium shadow-md text-sm sm:text-base"> - Become a Monthly Supporter - </button> - </a> - </div> - </motion.div> - </div> - <Footer /> - </> - ); -}; - -export default Donate; diff --git a/src/pages/JoinDevelopment.tsx b/src/pages/JoinDevelopment.tsx deleted file mode 100644 index 13240fb1..00000000 --- a/src/pages/JoinDevelopment.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import { DeveloperTestimonials } from '@/components/DeveloperTestimonials'; -import DeveloperLinks from '@/components/DeveloperLinks'; -import JoinToggle from '@/components/JoinToggle'; -import { motion } from 'framer-motion'; -import { slideInBottom } from '@/styles/Animations'; -import { useEffect } from 'react'; - -const JoinDevelopment = () => { - useEffect(() => { - window.scrollTo(0, 0); - }, []); - - return ( - <div className="bg-gradient-to-b to-red-50"> - <Header /> - <main className="container mx-auto flex flex-col items-center justify-center min-h-screen p-6"> - <JoinToggle /> - - {/* Getting Involved Section */} - <motion.div - className="mt-20 max-w-4xl flex flex-col items-center text-center px-6" - initial={{ opacity: 0, y: 20 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.6, delay: 0.2 }} - > - <h2 className="text-5xl font-bold font-[Caveat]"> - Before Beginning to Contribute - </h2> - <hr className="w-32 border-t-2 border-gray-400 mx-auto mt-2" /> - - <p className="text-lg text-gray-700 font-[Inter] mt-6 leading-relaxed"> - As a developer, whether you are just starting out or you've - participated in other development before, there are a few things you - need to know about our community. This page has important - information on not just where to find the code, documentation, and - how to reach us, but it also has information on our philosophy and a - link to our Code of Conduct. - </p> - </motion.div> - - {/* Testimonials Section */} - <div className="w-full mt-16"> - <DeveloperTestimonials /> - </div> - - {/* Important Links Section with Anchor */} - <section className="py-16 w-full" id="links"> - <motion.div - className="max-w-5xl mx-auto" - variants={slideInBottom} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.1 }} - > - <div className="text-center mb-8"> - <span className="inline-block px-3 py-1 bg-red-100 text-red-700 rounded-full text-sm font-semibold mb-4"> - Resources - </span> - <h2 className="text-4xl md:text-5xl font-bold font-[Caveat] mb-4"> - Important Links for Developers - </h2> - <div className="w-24 h-1 bg-red-700 rounded mx-auto mb-6"></div> - <p className="text-lg text-gray-700 max-w-2xl mx-auto"> - Essential resources for people interested in making development - contributions to Sugar Labs - </p> - </div> - - <DeveloperLinks /> - </motion.div> - </section> - </main> - - <Footer /> - </div> - ); -}; - -export default JoinDevelopment; diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx deleted file mode 100644 index 6a1a1d2a..00000000 --- a/src/pages/MainPage.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import Stats from '@/components/Stats.tsx'; -import Try from '@/components/Try.tsx'; -import Info from '@/components/Info.tsx'; -import { Testimonials } from '@/components/Testimonials'; -import { TryMore } from '@/components/TryMore3D'; -import Donation from '@/components/Donation.tsx'; -import PromoBanner from '@/sections/Banner'; -import { bannerConfigs } from '@/constants/Banner'; - -const MainPage = () => { - return ( - <> - <Header /> - <PromoBanner bannerConfigs={bannerConfigs} /> - <Info /> - <Stats /> - <Testimonials /> - <Try /> - <TryMore /> - <Donation /> - <Footer /> - </> - ); -}; - -export default MainPage; diff --git a/src/pages/Matrix.tsx b/src/pages/Matrix.tsx deleted file mode 100644 index 30d45078..00000000 --- a/src/pages/Matrix.tsx +++ /dev/null @@ -1,427 +0,0 @@ -import React from 'react'; -import { motion } from 'framer-motion'; -import { - ExternalLink, - Code, - Terminal, - Building, - MessageCircle, - ChevronRight, -} from 'lucide-react'; -import { matrixLinks } from '@/constants/matrixLinks'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import { - fadeIn, - subtleRise, - staggerContainer, - statCard, - headerReveal, - simpleFadeIn, - lineAnimation, -} from '@/styles/Animations'; - -interface TimelineStepProps { - step: number; - title: string; - description: string; - icon: React.ReactNode; - isLeft: boolean; - link?: { - url: string; - text: string; - }; -} - -const TimelineStep: React.FC<TimelineStepProps> = ({ - step, - title, - description, - icon, - isLeft, - link, -}) => ( - <motion.div variants={subtleRise} className="relative"> - <div className="md:hidden relative pl-12 pb-10"> - <div className="absolute left-0 top-0 w-8 h-8 rounded-full bg-[#D4B062] flex items-center justify-center z-10"> - <span className="text-white font-bold">{step}</span> - </div> - <div className="absolute left-4 top-8 h-full w-[1px] bg-[#D4B062]/30"></div> - <div className="bg-[#D4B062] p-2 rounded-full border-2 border-[#D4B062] text-white mb-3 inline-flex"> - {icon} - </div> - <div className="bg-white p-5 rounded-lg shadow-md"> - <h3 className="text-lg font-bold text-magazine-navy mb-2">{title}</h3> - <p className="text-gray-600 text-sm leading-relaxed"> - {description} - {link && ( - <a - href={link.url} - target="_blank" - rel="noopener noreferrer" - className="text-[#D4B062] hover:underline ml-1 inline-flex items-center" - > - {link.text} <ChevronRight className="h-3 w-3 ml-1" /> - </a> - )} - </p> - </div> - </div> - - <div className="hidden md:flex flex-row items-center"> - {isLeft ? ( - <> - <div className="w-1/2 pr-8 mb-0 text-right"> - <div className="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300"> - <h3 className="text-xl font-bold text-magazine-navy mb-2"> - {title} - </h3> - <p className="text-gray-600 leading-relaxed"> - {description} - {link && ( - <a - href={link.url} - target="_blank" - rel="noopener noreferrer" - className="text-[#D4B062] hover:underline ml-1 inline-flex items-center" - > - {link.text} <ChevronRight className="h-3 w-3 ml-1" /> - </a> - )} - </p> - </div> - </div> - <div className="absolute left-1/2 transform -translate-x-1/2 w-8 h-8 rounded-full bg-[#D4B062] flex items-center justify-center z-10"> - <span className="text-white font-bold">{step}</span> - </div> - <div className="w-1/2 pl-8 text-left"> - <motion.div className="flex items-center" whileHover={{ x: 5 }}> - <div className="bg-[#D4B062] p-2 rounded-full border-2 border-[#D4B062] text-white mr-3"> - {icon} - </div> - <span className="text-magazine-navy font-bold text-lg"> - {title.split(' ')[0]} - </span> - </motion.div> - </div> - </> - ) : ( - <> - <div className="w-1/2 pr-8 mb-0 text-right"> - <motion.div - className="flex items-center justify-end" - whileHover={{ x: -5 }} - > - <span className="text-magazine-navy font-bold text-lg mr-3"> - {title.split(' ')[0]} - </span> - <div className="bg-[#D4B062] p-2 rounded-full border-2 border-[#D4B062] text-white"> - {icon} - </div> - </motion.div> - </div> - <div className="absolute left-1/2 transform -translate-x-1/2 w-8 h-8 rounded-full bg-[#D4B062] flex items-center justify-center z-10"> - <span className="text-white font-bold">{step}</span> - </div> - <div className="w-1/2 pl-8"> - <div className="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300"> - <h3 className="text-xl font-bold text-magazine-navy mb-2"> - {title} - </h3> - <p className="text-gray-600 leading-relaxed"> - {description} - {link && ( - <a - href={link.url} - target="_blank" - rel="noopener noreferrer" - className="text-[#D4B062] hover:underline ml-1 inline-flex items-center" - > - {link.text} <ChevronRight className="h-3 w-3 ml-1" /> - </a> - )} - </p> - </div> - </div> - </> - )} - </div> - </motion.div> -); - -interface RoomCardProps { - link: { - id: string; - title: string; - description: string; - url: string; - icon?: string; - }; - getIcon: (iconName?: string) => React.ReactNode; -} - -const RoomCard: React.FC<RoomCardProps> = ({ link, getIcon }) => ( - <motion.div - key={link.id} - variants={statCard} - whileHover="hover" - className="bg-white rounded-xl shadow-md overflow-hidden border border-gray-100 hover:shadow-lg transition-all duration-300 h-full" - > - <div className="p-4 sm:p-6 flex flex-col h-full"> - <div className="flex items-center gap-3 mb-4"> - <div className="bg-[#D4B062] p-2 sm:p-3 rounded-full text-white flex-shrink-0"> - {getIcon(link.icon)} - </div> - <h3 className="font-bold text-lg sm:text-xl">{link.title}</h3> - </div> - <p className="text-gray-600 mb-4 sm:mb-6 leading-relaxed text-sm sm:text-base flex-grow"> - {link.description} - </p> - <motion.a - href={link.url} - target="_blank" - rel="noopener noreferrer" - className="inline-flex items-center text-[#D4B062] hover:text-magazine-navy transition-colors font-medium mt-auto" - whileHover={{ x: 5 }} - > - Join Room <ExternalLink className="ml-2 h-4 w-4" /> - </motion.a> - </div> - </motion.div> -); - -const Matrix: React.FC = () => { - const getIcon = (iconName?: string) => { - switch (iconName) { - case 'code': - return <Code className="h-5 w-5 sm:h-6 sm:w-6" />; - case 'terminal': - return <Terminal className="h-5 w-5 sm:h-6 sm:w-6" />; - case 'building': - return <Building className="h-5 w-5 sm:h-6 sm:w-6" />; - case 'message': - return <MessageCircle className="h-5 w-5 sm:h-6 sm:w-6" />; - default: - return <ExternalLink className="h-5 w-5 sm:h-6 sm:w-6" />; - } - }; - - const timelineSteps = [ - { - step: 1, - title: 'Choose a Matrix client', - description: - 'Element is the most popular Matrix client, available on web, desktop, iOS, and Android.', - icon: <Terminal className="h-5 w-5" />, - isLeft: true, - link: { - url: 'https://element.io/get-started', - text: 'element.io', - }, - }, - { - step: 2, - title: 'Create an account', - description: - "You can create an account on the Matrix.org homeserver or any other public homeserver. You'll need to provide a username and password.", - icon: <Building className="h-5 w-5" />, - isLeft: false, - }, - { - step: 3, - title: 'Join our rooms', - description: - 'Use the links in the section above to join our community rooms. You can also search for rooms within your Matrix client using the room addresses.', - icon: <MessageCircle className="h-5 w-5" />, - isLeft: true, - }, - { - step: 4, - title: 'Engage with the community', - description: - 'Introduce yourself, ask questions, share your expertise, and become an active part of our growing Matrix community.', - icon: <Code className="h-5 w-5" />, - isLeft: false, - }, - ]; - - return ( - <div className="min-h-screen flex flex-col font-sans bg-[#FFFEF9]"> - <Header /> - <main className="flex-grow"> - {/* Hero Section*/} - <motion.section - initial="hidden" - animate="visible" - variants={subtleRise} - className="relative py-16 sm:py-20 md:py-28 overflow-hidden bg-gradient-to-b from-black via-gray-800 to-white" - > - <div className="absolute inset-0 z-0 overflow-hidden"> - <div className="absolute inset-0 opacity-10"></div> - <div - className="absolute inset-0" - style={{ - backgroundImage: - 'radial-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1px)', - backgroundSize: '20px 20px', - }} - ></div> - </div> - <div className="container mx-auto px-4 md:px-6"> - <div className="flex flex-col items-center text-center z-10 relative"> - <motion.h1 - className="font-black text-4xl sm:text-5xl md:text-6xl lg:text-7xl mb-4 sm:mb-6 text-white" - variants={headerReveal} - > - Matrix <span className="text-[#D4B062]">Chat</span> - </motion.h1> - <motion.div - className="w-16 sm:w-24 h-1 bg-[#D4B062] mb-4 sm:mb-6 rounded-full" - initial={{ width: 0 }} - animate={{ width: 96 }} - transition={{ duration: 0.8, delay: 0.3 }} - ></motion.div> - <motion.p - className="text-base sm:text-lg md:text-xl mb-8 sm:mb-10 text-gray-300 max-w-2xl leading-relaxed px-4" - variants={simpleFadeIn} - > - Connect with our vibrant community through Matrix — an open - network for secure, decentralized communication that puts you in - control. - </motion.p> - <motion.a - href="#get-started" - className="bg-[#D4B062] hover:bg-white hover:text-black text-black font-medium px-6 sm:px-8 py-2.5 sm:py-3 rounded-full transition-all duration-300 shadow-lg hover:shadow-xl text-sm sm:text-base" - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - > - Get Started - </motion.a> - </div> - </div> - </motion.section> - - {/* Matrix Info */} - <motion.section - initial="hidden" - whileInView="visible" - viewport={{ once: true, margin: '-100px' }} - variants={fadeIn} - className="py-12 sm:py-16 bg-[#FFFEF9]" - > - <div className="container mx-auto px-4 md:px-6"> - <div className="max-w-3xl mx-auto"> - <motion.h2 - className="text-2xl sm:text-3xl font-bold mb-6 text-magazine-navy border-b-2 border-[#D4B062] pb-2 inline-block" - variants={fadeIn} - > - What is Matrix? - </motion.h2> - <motion.div - className="space-y-4 text-base sm:text-lg leading-relaxed" - variants={fadeIn} - > - <p> - Matrix is an open source project that publishes the Matrix - open standard for secure, decentralized, real-time - communication, and its Apache licensed reference - implementations. - </p> - <p> - It defines a set of open APIs for decentralized communication, - suitable for securely publishing, persisting and subscribing - to data over a global open federation of servers with no - single point of control. - </p> - <p> - Matrix can be used for instant messaging, VoIP/WebRTC - signaling, IoT communication, and anywhere you need a standard - HTTP API for publishing and subscribing to data while tracking - the history and the current state. - </p> - </motion.div> - </div> - </div> - </motion.section> - - {/* Matrix Rooms */} - <motion.section - initial="hidden" - whileInView="visible" - viewport={{ once: true, margin: '-100px' }} - variants={staggerContainer} - className="py-12 sm:py-16 md:py-24 bg-[#FFFEF9]" - > - <div className="container mx-auto px-4 md:px-6"> - <motion.div className="text-center mb-8 sm:mb-12" variants={fadeIn}> - <h2 className="text-2xl sm:text-3xl font-bold mb-3 text-magazine-navy"> - Join Our Matrix Rooms - </h2> - <div className="w-16 h-1 bg-[#D4B062] mx-auto rounded-full"></div> - </motion.div> - - <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6 lg:gap-8"> - {matrixLinks.map((link) => ( - <RoomCard key={link.id} link={link} getIcon={getIcon} /> - ))} - </div> - </div> - </motion.section> - - {/* How to Get Started */} - <motion.section - id="get-started" - initial="hidden" - whileInView="visible" - viewport={{ once: true, margin: '-100px' }} - variants={staggerContainer} - className="py-12 sm:py-16 bg-[#FFFEF9]" - > - <div className="container mx-auto px-4 md:px-6"> - <motion.div className="text-center mb-8 sm:mb-12" variants={fadeIn}> - <h2 className="text-2xl sm:text-3xl font-bold mb-3 text-magazine-navy"> - How to Get Started with Matrix - </h2> - <div className="w-16 h-1 bg-[#D4B062] mx-auto rounded-full"></div> - </motion.div> - - <div className="max-w-4xl mx-auto"> - {/* Timeline container */} - <div className="relative"> - <motion.div - className="absolute left-1/2 transform -translate-x-1/2 w-1 bg-orange-500/70 hidden md:block" - variants={lineAnimation} - initial="hidden" - whileInView="visible" - viewport={{ once: true }} - style={{ - background: - 'linear-gradient(to bottom, rgba(212,176,98,0.1), rgba(212,176,98,0.7), rgba(212,176,98,0.1))', - }} - ></motion.div> - - {/* Timeline items */} - <div className="space-y-8 md:space-y-16"> - {timelineSteps.map((step, index) => ( - <TimelineStep - key={index} - step={step.step} - title={step.title} - description={step.description} - icon={step.icon} - isLeft={step.isLeft} - link={step.link} - /> - ))} - </div> - </div> - </div> - </div> - </motion.section> - </main> - <Footer /> - </div> - ); -}; - -export default Matrix; diff --git a/src/pages/More.tsx b/src/pages/More.tsx deleted file mode 100644 index eac4ca39..00000000 --- a/src/pages/More.tsx +++ /dev/null @@ -1,314 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { useParams, useNavigate, Link } from 'react-router-dom'; -import { - getMorePageBySlug, - getMorePagesByCategory, - getDefaultMorePageSlug, -} from '@/utils/more-utils'; -import type { MorePage as MorePageType } from '@/utils/more-utils'; -import { motion } from 'framer-motion'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import MarkdownRenderer from '@/utils/MarkdownRenderer'; - -const MorePage: React.FC = () => { - const { slug } = useParams<{ slug: string }>(); - const navigate = useNavigate(); - const [page, setPage] = useState<MorePageType | null>(null); - const [isLoading, setIsLoading] = useState<boolean>(true); - const [categories, setCategories] = useState<string[]>([]); - const [pagesByCategory, setPagesByCategory] = useState< - Record<string, MorePageType[]> - >({}); - const [activeCategory, setActiveCategory] = useState<string>('All'); - const [notFoundSlug, setNotFoundSlug] = useState<string | null>(null); - const [zoomableImages, setZoomableImages] = useState<HTMLImageElement[]>([]); - const [modalImage, setModalImage] = useState<{ - src: string; - alt: string; - } | null>(null); - - useEffect(() => { - const loadPage = async () => { - setIsLoading(true); - try { - const pagesData = await getMorePagesByCategory(); - setPagesByCategory(pagesData); - setCategories([ - 'All', - ...Object.keys(pagesData).filter((cat) => cat !== 'All'), - ]); - - if (slug) { - const fetchedPage = await getMorePageBySlug(slug); - - if (fetchedPage) { - setPage(fetchedPage); - setNotFoundSlug(null); - document.title = fetchedPage.title + ' - Sugar Labs'; - - if (fetchedPage.category) { - setActiveCategory(fetchedPage.category); - } - } else { - setPage(null); - setNotFoundSlug(slug ?? null); - document.title = 'Page Not Found - Sugar Labs'; - } - } else { - const defaultSlug = await getDefaultMorePageSlug(); - if (defaultSlug) { - navigate(`/more/${defaultSlug}`, { replace: true }); - } - } - } catch (error) { - console.error('Error loading page:', error); - setPage(null); - setNotFoundSlug(slug ?? null); - } finally { - setIsLoading(false); - } - }; - - loadPage(); - }, [slug, navigate]); - - // Handle zoomable images - useEffect(() => { - if (!isLoading && zoomableImages.length > 0) { - const handleClick = (event: Event) => { - const imgElement = event.target as HTMLImageElement; - setModalImage({ - src: imgElement.src, - alt: imgElement.alt || 'Image', - }); - document.body.classList.add('overflow-hidden'); - }; - - zoomableImages.forEach((img) => - img.addEventListener('click', handleClick), - ); - return () => { - zoomableImages.forEach((img) => - img.removeEventListener('click', handleClick), - ); - }; - } - }, [isLoading, zoomableImages]); - - // Handle escape key for modal - useEffect(() => { - const handleEscKey = (e: KeyboardEvent) => { - if (e.key === 'Escape' && modalImage) { - closeImageModal(); - } - }; - - window.addEventListener('keydown', handleEscKey); - return () => window.removeEventListener('keydown', handleEscKey); - }); - - const closeImageModal = () => { - setModalImage(null); - document.body.classList.remove('overflow-hidden'); - }; - - if (isLoading) { - return ( - <div className="container mx-auto px-4 py-16 flex justify-center items-center min-h-screen"> - <div className="animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-600"></div> - </div> - ); - } - - return ( - <> - <Header /> - <div className="container mx-auto px-4 py-8 mt-10"> - {/* Navigation Header */} - <div className="mb-8"> - <Link - to="/" - className="text-blue-600 hover:underline mb-2 inline-block" - > - <motion.button - className="mb-6 px-4 py-2 flex items-center text-blue-600 hover:text-blue-700 transition-colors rounded-md hover:bg-blue-50" - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - > - <svg - xmlns="http://www.w3.org/2000/svg" - className="h-5 w-5 mr-2" - viewBox="0 0 20 20" - fill="currentColor" - > - <path - fillRule="evenodd" - d="M9.707 14.707a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 1.414L7.414 9H15a1 1 0 110 2H7.414l2.293 2.293a1 1 0 010 1.414z" - clipRule="evenodd" - /> - </svg> - Back to Home - </motion.button> - </Link> - <h2 className="text-3xl font-bold border-b-2 border-red-500 pb-2"> - {page ? page.title : 'Page Not Found'} - </h2> - </div> - - <div className="flex flex-col md:flex-row gap-8"> - {/* Sidebar Navigation */} - <div className="md:w-1/4"> - <div className="bg-gray-50 p-4 rounded-lg shadow-md"> - {/* Category Navigation */} - <div className="mb-6"> - <h3 className="font-bold text-xl mb-2">Categories</h3> - <div className="flex flex-wrap gap-2"> - {categories.map((category) => ( - <button - key={category} - onClick={() => setActiveCategory(category)} - className={`px-3 py-1 rounded-full text-sm ${ - activeCategory === category - ? 'bg-blue-600 text-white' - : 'bg-gray-200 text-gray-700 hover:bg-gray-300' - }`} - > - {category} - </button> - ))} - </div> - </div> - - {/* Page Links */} - <h3 className="font-bold text-xl mb-4"> - {activeCategory === 'All' - ? 'All Pages' - : activeCategory + ' Pages'} - </h3> - <ul className="space-y-2"> - {pagesByCategory[activeCategory]?.map((linkPage) => ( - <li key={linkPage.slug}> - <Link - to={`/more/${linkPage.slug}`} - className={`block p-2 rounded hover:bg-gray-100 transition ${ - linkPage.slug === page?.slug - ? 'bg-red-100 text-red-600 font-medium' - : 'text-gray-700' - }`} - > - {linkPage.title} - </Link> - </li> - ))} - </ul> - </div> - </div> - - {/* Main Content */} - <motion.div - className="md:w-3/4" - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - transition={{ duration: 0.5 }} - key={page?.slug} - > - <div className="bg-white rounded-lg shadow-md p-6"> - {page ? ( - <div className="prose prose-lg max-w-none"> - <MarkdownRenderer - content={page.content} - setZoomableImages={setZoomableImages} - frontmatter={{ - title: page.title, - slug: page.slug, - category: page.category ?? null, - }} - /> - </div> - ) : ( - <div className="text-center py-8"> - <div className="mx-auto w-20 h-20 flex items-center justify-center bg-red-100 rounded-full mb-6"> - <svg - xmlns="http://www.w3.org/2000/svg" - className="h-10 w-10 text-red-500" - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" - /> - </svg> - </div> - - <h3 className="text-2xl font-bold mb-4 text-gray-800"> - The page you are looking for has been deleted or is not - present - </h3> - - {notFoundSlug && ( - <p className="mb-4 text-gray-600">Page was not found.</p> - )} - - <div className="mb-8"> - <Link - to="/" - className="inline-block px-6 py-3 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors" - > - Go Back to Home - </Link> - </div> - </div> - )} - </div> - </motion.div> - </div> - </div> - - {/* Image Modal */} - {modalImage && ( - <motion.div - className="fixed inset-0 bg-black bg-opacity-80 z-50 flex items-center justify-center p-4" - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - onClick={(e) => { - if (e.target === e.currentTarget) closeImageModal(); - }} - role="dialog" - aria-modal="true" - aria-labelledby="modal-image-title" - > - <div className="relative max-w-4xl max-h-full"> - <motion.img - src={modalImage.src} - alt={modalImage.alt} - className="max-w-full max-h-[90vh] object-contain" - initial={{ scale: 0.8, opacity: 0 }} - animate={{ scale: 1, opacity: 1 }} - transition={{ type: 'spring', stiffness: 300, damping: 25 }} - id="modal-image-title" - /> - <p className="text-white text-center mt-2 text-sm"> - {modalImage.alt} - </p> - <button - onClick={closeImageModal} - className="absolute top-2 right-2 text-white text-2xl hover:text-gray-300 bg-black bg-opacity-50 rounded-full w-8 h-8 flex items-center justify-center focus:outline-none focus:ring-2 focus:ring-white" - aria-label="Close image" - > - × - </button> - </div> - </motion.div> - )} - - <Footer /> - </> - ); -}; - -export default MorePage; diff --git a/src/pages/News/AuthorPage.tsx b/src/pages/News/AuthorPage.tsx deleted file mode 100644 index 5a1a1462..00000000 --- a/src/pages/News/AuthorPage.tsx +++ /dev/null @@ -1,528 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { useParams, useNavigate } from 'react-router-dom'; -import { motion, AnimatePresence } from 'framer-motion'; -import { - Calendar, - ArrowLeft, - BookOpen, - User, - Building, - Grid, - List, - Search, - ChevronDown, -} from 'lucide-react'; - -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import MarkdownRenderer from '@/utils/MarkdownRenderer'; -import { getAuthorBySlug, Author } from '@/utils/author-utils'; -import { getPostsByAuthor, Post } from '@/utils/posts-utils'; - -const AuthorPage: React.FC = () => { - const { slug } = useParams<{ slug: string }>(); - const navigate = useNavigate(); - - const [author, setAuthor] = useState<Author | null>(null); - const [posts, setPosts] = useState<Post[]>([]); - const [filteredPosts, setFilteredPosts] = useState<Post[]>([]); - const [isLoading, setIsLoading] = useState(true); - const [error, setError] = useState<string | null>(null); - - // UI State - const [displayCount, setDisplayCount] = useState(6); - const [searchTerm, setSearchTerm] = useState(''); - const [selectedCategory, setSelectedCategory] = useState('All'); - const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid'); - const [sortBy, setSortBy] = useState<'date' | 'title'>('date'); - - useEffect(() => { - const loadAuthorData = async () => { - if (!slug) return; - - setIsLoading(true); - try { - const [authorData, authorPosts] = await Promise.all([ - getAuthorBySlug(slug), - getPostsByAuthor(slug), - ]); - - if (!authorData) { - setError('Author not found'); - return; - } - - setAuthor(authorData); - setPosts(authorPosts); - setFilteredPosts(authorPosts); - document.title = `${authorData.name} - SugarLabs`; - } catch (err) { - console.error('Error loading author:', err); - setError('Failed to load author information'); - } finally { - setIsLoading(false); - } - }; - - loadAuthorData(); - }, [slug]); - - // Filter and sort posts - useEffect(() => { - let filtered = [...posts]; - - // Filter by search term - if (searchTerm) { - filtered = filtered.filter( - (post) => - post.title.toLowerCase().includes(searchTerm.toLowerCase()) || - post.excerpt?.toLowerCase().includes(searchTerm.toLowerCase()) || - post.tags.some((tag) => - tag.toLowerCase().includes(searchTerm.toLowerCase()), - ), - ); - } - - // Filter by category - if (selectedCategory !== 'All') { - filtered = filtered.filter((post) => post.category === selectedCategory); - } - - // Sort posts - filtered.sort((a, b) => { - if (sortBy === 'date') { - return new Date(b.date).getTime() - new Date(a.date).getTime(); - } else { - return a.title.localeCompare(b.title); - } - }); - - setFilteredPosts(filtered); - setDisplayCount(6); // Reset display count when filters change - }, [posts, searchTerm, selectedCategory, sortBy]); - - const handlePostClick = (post: Post) => { - const categoryPath = post.category.toLowerCase().replace(/\s+/g, '-'); - navigate(`/news/${categoryPath}/${post.slug}`); - }; - - const handleShowMore = () => { - setDisplayCount((prev) => Math.min(prev + 6, filteredPosts.length)); - }; - - const getUniqueCategories = () => { - const categories = Array.from(new Set(posts.map((post) => post.category))); - return ['All', ...categories.sort()]; - }; - - const visiblePosts = filteredPosts.slice(0, displayCount); - const hasMore = filteredPosts.length > displayCount; - - if (isLoading) { - return ( - <> - <Header /> - <div className="container mx-auto px-4 py-16 flex justify-center items-center min-h-screen"> - <div className="flex flex-col items-center"> - <div className="animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-600 mb-4"></div> - <p className="text-gray-600">Loading author profile...</p> - </div> - </div> - <Footer /> - </> - ); - } - - if (error || !author) { - return ( - <> - <Header /> - <div className="container mx-auto px-4 py-16 text-center min-h-screen flex flex-col justify-center"> - <h1 className="text-3xl font-bold mb-4 text-blue-600"> - Author Not Found - </h1> - <p className="mb-8 text-gray-600"> - The author profile you're looking for doesn't exist. - </p> - <button - onClick={() => navigate('/news')} - className="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors mx-auto" - > - Back to News - </button> - </div> - <Footer /> - </> - ); - } - - return ( - <> - <Header /> - <div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-green-50"> - <div className="container mx-auto px-4 py-8 max-w-7xl"> - {/* Back Button */} - <motion.button - onClick={() => navigate(-1)} - className="mb-6 px-4 py-2 flex items-center text-blue-600 hover:text-blue-700 transition-colors rounded-md hover:bg-blue-50" - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - > - <ArrowLeft className="h-5 w-5 mr-2" /> - Back - </motion.button> - - {/* Author Header */} - <motion.div - className="bg-white rounded-2xl shadow-xl p-4 sm:p-6 lg:p-8 mb-8" - initial={{ opacity: 0, y: 20 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5 }} - > - <div className="flex flex-col sm:flex-row items-center sm:items-start gap-6 lg:gap-8"> - {/* Avatar */} - <div className="flex-shrink-0"> - {author.avatar ? ( - <img - src={author.avatar} - alt={author.name} - className="w-24 h-24 sm:w-28 sm:h-28 lg:w-32 lg:h-32 rounded-full object-cover border-4 border-blue-100" - /> - ) : ( - <div className="w-24 h-24 sm:w-28 sm:h-28 lg:w-32 lg:h-32 bg-blue-100 rounded-full flex items-center justify-center"> - <User className="w-12 h-12 sm:w-14 sm:h-14 lg:w-16 lg:h-16 text-blue-600" /> - </div> - )} - </div> - - {/* Author Info */} - <div className="flex-1 text-center sm:text-left"> - <h1 className="text-2xl sm:text-3xl lg:text-4xl font-bold text-gray-900 mb-2"> - {author.name} - </h1> - <div className="flex flex-col sm:flex-row sm:items-center gap-2 mb-3"> - <span className="text-lg lg:text-xl text-blue-600 font-medium"> - {author.title} - </span> - {author.organization && ( - <> - <span className="hidden sm:inline text-gray-400">at</span> - <div className="flex items-center justify-center sm:justify-start gap-1 text-gray-700"> - <Building className="w-4 h-4" /> - <span className="font-medium"> - {author.organization} - </span> - </div> - </> - )} - </div> - <p className="text-gray-600 text-base lg:text-lg mb-4 max-w-2xl"> - {author.description} - </p> - - {/* Quick Stats */} - <div className="flex flex-wrap justify-center sm:justify-start gap-4 text-sm text-gray-600"> - <div className="flex items-center gap-1 bg-blue-50 px-3 py-1 rounded-full"> - <BookOpen className="w-4 h-4" /> - <span> - {posts.length}{' '} - {posts.length === 1 ? 'Article' : 'Articles'} - </span> - </div> - {author.organization && ( - <div className="flex items-center gap-1 bg-gray-50 px-3 py-1 rounded-full"> - <Building className="w-4 h-4" /> - <span>{author.organization}</span> - </div> - )} - </div> - </div> - </div> - </motion.div> - - <div className="grid grid-cols-1 xl:grid-cols-4 gap-6 lg:gap-8"> - {/* Author Content */} - <motion.div - className="xl:col-span-3 order-2 xl:order-1" - initial={{ opacity: 0, x: -20 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.2 }} - > - {/* About Section */} - <div className="bg-white rounded-2xl shadow-xl p-4 sm:p-6 lg:p-8 mb-6 lg:mb-8"> - <MarkdownRenderer content={author.content} /> - </div> - - {/* Articles Section */} - <div className="bg-white rounded-2xl shadow-xl p-4 sm:p-6 lg:p-8"> - <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6"> - <div className="flex items-center gap-2"> - <BookOpen className="w-5 h-5 text-blue-600" /> - <h3 className="text-xl lg:text-2xl font-bold text-gray-900"> - Articles ({filteredPosts.length}) - </h3> - </div> - - {/* Controls */} - {posts.length > 0 && ( - <div className="flex flex-col sm:flex-row gap-3"> - {/* Search */} - <div className="relative"> - <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" /> - <input - type="text" - placeholder="Search articles..." - value={searchTerm} - onChange={(e) => setSearchTerm(e.target.value)} - className="pl-10 pr-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm w-full sm:w-auto" - /> - </div> - - {/* Category Filter */} - <select - value={selectedCategory} - onChange={(e) => setSelectedCategory(e.target.value)} - className="px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" - > - {getUniqueCategories().map((category) => ( - <option key={category} value={category}> - {category} - </option> - ))} - </select> - - {/* Sort */} - <select - value={sortBy} - onChange={(e) => - setSortBy(e.target.value as 'date' | 'title') - } - className="px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" - > - <option value="date">Sort by Date</option> - <option value="title">Sort by Title</option> - </select> - - {/* View Toggle */} - <div className="flex bg-gray-100 rounded-lg p-1"> - <button - onClick={() => setViewMode('grid')} - className={`p-2 rounded-md transition-colors ${ - viewMode === 'grid' - ? 'bg-white text-blue-600 shadow-sm' - : 'text-gray-600' - }`} - > - <Grid className="w-4 h-4" /> - </button> - <button - onClick={() => setViewMode('list')} - className={`p-2 rounded-md transition-colors ${ - viewMode === 'list' - ? 'bg-white text-blue-600 shadow-sm' - : 'text-gray-600' - }`} - > - <List className="w-4 h-4" /> - </button> - </div> - </div> - )} - </div> - - {/* Articles Display */} - {filteredPosts.length === 0 ? ( - <div className="text-center py-12"> - <div className="text-4xl mb-4"> - {searchTerm || selectedCategory !== 'All' ? '🔍' : '📝'} - </div> - <h4 className="text-lg font-semibold text-gray-700 mb-2"> - {searchTerm || selectedCategory !== 'All' - ? 'No matching articles' - : 'No articles published yet'} - </h4> - <p className="text-gray-600"> - {searchTerm || selectedCategory !== 'All' - ? 'Try adjusting your search or filter criteria' - : 'Articles will appear here when published'} - </p> - {(searchTerm || selectedCategory !== 'All') && ( - <button - onClick={() => { - setSearchTerm(''); - setSelectedCategory('All'); - }} - className="mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors" - > - Clear Filters - </button> - )} - </div> - ) : ( - <> - <motion.div - className={ - viewMode === 'grid' - ? 'grid grid-cols-1 md:grid-cols-2 gap-6' - : 'space-y-4' - } - initial="hidden" - animate="visible" - > - <AnimatePresence> - {visiblePosts.map((post, index) => ( - <motion.article - key={post.slug} - className={` - border border-gray-200 rounded-lg hover:border-blue-300 hover:shadow-md - transition-all duration-300 cursor-pointer group bg-white - ${viewMode === 'list' ? 'flex gap-4 p-4' : 'p-4'} - `} - onClick={() => handlePostClick(post)} - initial={{ opacity: 0, y: 20 }} - animate={{ opacity: 1, y: 0 }} - exit={{ opacity: 0, y: -20 }} - transition={{ duration: 0.3, delay: index * 0.05 }} - whileHover={{ scale: 1.02 }} - > - {viewMode === 'list' && post.image && ( - <div className="w-24 h-24 flex-shrink-0"> - <img - src={post.image} - alt={post.title} - className="w-full h-full object-cover rounded-lg" - /> - </div> - )} - - <div className="flex-1"> - <h4 className="font-semibold text-gray-900 mb-2 line-clamp-2 group-hover:text-blue-600 transition-colors"> - {post.title} - </h4> - <p className="text-sm text-gray-600 mb-3 line-clamp-2"> - {post.excerpt} - </p> - - <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-2 text-xs text-gray-500"> - <div className="flex items-center gap-3"> - <div className="flex items-center gap-1"> - <Calendar className="w-3 h-3" /> - {post.date} - </div> - {post.tags.length > 0 && ( - <div className="flex items-center gap-1"> - <span className="w-1 h-1 bg-gray-400 rounded-full"></span> - <span> - {post.tags.slice(0, 2).join(', ')} - </span> - {post.tags.length > 2 && ( - <span>+{post.tags.length - 2}</span> - )} - </div> - )} - </div> - <span className="px-2 py-1 bg-blue-100 text-blue-600 rounded-full text-xs font-medium"> - {post.category} - </span> - </div> - </div> - </motion.article> - ))} - </AnimatePresence> - </motion.div> - - {/* Load More Button */} - {hasMore && ( - <div className="text-center mt-8"> - <motion.button - onClick={handleShowMore} - className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium flex items-center gap-2 mx-auto" - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - > - Load More Articles - <ChevronDown className="w-4 h-4" /> - <span className="text-xs bg-blue-500 px-2 py-1 rounded-full"> - +{Math.min(6, filteredPosts.length - displayCount)} - </span> - </motion.button> - </div> - )} - </> - )} - </div> - </motion.div> - - {/* Sidebar */} - <motion.div - className="order-1 xl:order-2" - initial={{ opacity: 0, x: 20 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.3 }} - > - {/* Author Stats Card */} - <div className="bg-white rounded-2xl shadow-xl p-6 mb-6"> - <h3 className="text-lg font-bold text-gray-900 mb-4"> - Profile Stats - </h3> - <div className="space-y-3"> - <div className="flex justify-between items-center"> - <span className="text-gray-600">Total Articles</span> - <span className="font-semibold text-blue-600"> - {posts.length} - </span> - </div> - <div className="flex justify-between items-center"> - <span className="text-gray-600">Categories</span> - <span className="font-semibold text-gray-900"> - {getUniqueCategories().length - 1} - </span> - </div> - </div> - </div> - - {/* Categories Card */} - {getUniqueCategories().length > 2 && ( - <div className="bg-white rounded-2xl shadow-xl p-6"> - <h3 className="text-lg font-bold text-gray-900 mb-4"> - Categories - </h3> - <div className="space-y-2"> - {getUniqueCategories() - .slice(1) - .map((category) => { - const count = posts.filter( - (post) => post.category === category, - ).length; - return ( - <button - key={category} - onClick={() => setSelectedCategory(category)} - className={`w-full flex justify-between items-center p-2 rounded-lg transition-colors text-left ${ - selectedCategory === category - ? 'bg-blue-50 text-blue-700' - : 'hover:bg-gray-50' - }`} - > - <span className="text-sm font-medium"> - {category} - </span> - <span className="text-xs bg-gray-100 px-2 py-1 rounded-full"> - {count} - </span> - </button> - ); - })} - </div> - </div> - )} - </motion.div> - </div> - </div> - </div> - <Footer /> - </> - ); -}; - -export default AuthorPage; diff --git a/src/pages/News/NewsDetailPage.tsx b/src/pages/News/NewsDetailPage.tsx deleted file mode 100644 index 9808ef1f..00000000 --- a/src/pages/News/NewsDetailPage.tsx +++ /dev/null @@ -1,433 +0,0 @@ -import React, { useState, useEffect, useCallback } from 'react'; -import ShareModal from '@/components/ShareModal'; -import { Share2 } from 'lucide-react'; -import { useParams, useNavigate } from 'react-router-dom'; -import { getPostBySlug, Post } from '@/utils/posts-utils'; -import { motion } from 'framer-motion'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import MarkdownRenderer from '@/utils/MarkdownRenderer'; - -const NewsDetailPage: React.FC = () => { - const [shareModalOpen, setShareModalOpen] = useState(false); - - const { slug, category } = useParams<{ slug?: string; category?: string }>(); - const navigate = useNavigate(); - const [post, setPost] = useState<Post | null>(null); - const [isLoading, setIsLoading] = useState<boolean>(true); - const [error, setError] = useState<string | null>(null); - const [modalImage, setModalImage] = useState<{ - src: string; - alt: string; - } | null>(null); - const [zoomableImages, setZoomableImages] = useState<HTMLImageElement[]>([]); - - // Load post data when slug changes - useEffect(() => { - if (!slug) return; - - const loadPost = async () => { - setIsLoading(true); - try { - const fetchedPost = await getPostBySlug(slug); - - if (!fetchedPost) { - setError('Post not found'); - setPost(null); - } else { - setPost(fetchedPost); - setError(null); - document.title = fetchedPost.title || 'News Detail'; - } - } catch (err) { - console.error('Error loading post:', err); - setError('Failed to load the post. Please try again later.'); - setPost(null); - } finally { - setIsLoading(false); - } - }; - - loadPost(); - }, [slug]); - - useEffect(() => { - if (!isLoading && zoomableImages.length > 0) { - const handleClick = (event: Event) => { - const imgElement = event.target as HTMLImageElement; - setModalImage({ - src: imgElement.src, - alt: imgElement.alt || 'Image', - }); - document.body.classList.add('overflow-hidden'); - }; - - zoomableImages.forEach((img) => - img.addEventListener('click', handleClick), - ); - return () => { - zoomableImages.forEach((img) => - img.removeEventListener('click', handleClick), - ); - }; - } - }, [isLoading, zoomableImages]); - - useEffect(() => { - const handleEscKey = (e: KeyboardEvent) => { - if (e.key === 'Escape' && modalImage) { - closeImageModal(); - } - }; - - window.addEventListener('keydown', handleEscKey); - return () => window.removeEventListener('keydown', handleEscKey); - }); - - const handleGoBack = useCallback(() => { - if (category) { - navigate(`/news/${category}`); - } else { - navigate('/news/community-news'); - } - }, [navigate, category]); - - const closeImageModal = useCallback(() => { - setModalImage(null); - document.body.classList.remove('overflow-hidden'); - }, []); - - const handleTagClick = useCallback( - (tag: string) => { - navigate(`/tags/${tag}`); - }, - [navigate], - ); - - const handleAuthorClick = useCallback(() => { - if (post?.author?.slug) { - navigate(`/authors/${post.author.slug}`); - } - }, [navigate, post]); - - const handleShareClick = () => { - setShareModalOpen(true); - }; - - if (isLoading && !post) { - return ( - <> - <Header /> - <div className="container mx-auto px-4 py-16 flex justify-center items-center min-h-screen"> - <div className="flex flex-col items-center"> - <div className="animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-600 mb-4"></div> - <p className="text-gray-600">Loading article...</p> - </div> - </div> - <Footer /> - </> - ); - } - - // Error state or post not found - if (error || !post) { - return ( - <> - <Header /> - <div className="container mx-auto px-4 py-16 text-center min-h-screen flex flex-col justify-center"> - <h1 className="text-3xl font-bold mb-4 text-blue-600"> - {error || 'Post Not Found'} - </h1> - <p className="mb-8 text-gray-600"> - The post you're looking for doesn't exist or has been removed. - </p> - <button - onClick={handleGoBack} - className="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors mx-auto focus:outline-none focus:ring-2 focus:ring-blue-400" - > - Back to News - </button> - </div> - <Footer /> - </> - ); - } - - // Successful post rendering - return ( - <> - <Header /> - <div className="container mx-auto px-4 py-8 max-w-4xl bg-white mt-10"> - {/* Back button */} - <motion.button - onClick={handleGoBack} - className="mb-6 px-4 py-2 flex items-center text-blue-600 hover:text-blue-700 transition-colors rounded-md hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-blue-400" - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - aria-label="Back to news list" - > - <svg - xmlns="http://www.w3.org/2000/svg" - className="h-5 w-5 mr-2" - viewBox="0 0 20 20" - fill="currentColor" - aria-hidden="true" - > - <path - fillRule="evenodd" - d="M9.707 14.707a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 1.414L7.414 9H15a1 1 0 110 2H7.414l2.293 2.293a1 1 0 010 1.414z" - clipRule="evenodd" - /> - </svg> - Back to News - </motion.button> - - {/* Article Header */} - <div className="mb-8 border-b border-gray-200 pb-6"> - {post.category && ( - <span className="inline-block px-3 py-1 text-sm font-semibold bg-green-100 text-green-600 mb-4 rounded-full"> - {post.category} - </span> - )} - <div className="flex items-center gap-3 mb-4"> - <h1 className="text-4xl font-bold text-gray-900">{post.title}</h1> - <button - onClick={handleShareClick} - className="p-2 rounded-full bg-gradient-to-r from-blue-600 to-blue-700 text-white shadow hover:from-blue-700 hover:to-green-600 focus:outline-none focus:ring-2 focus:ring-blue-400 transition-all duration-300 cursor-pointer" - title="Share" - type="button" - > - <Share2 size={16} className="text-white" /> - </button> - </div> - <div className="flex flex-wrap items-center text-gray-500 mb-3"> - {post.date && ( - <> - <span className="mr-4 flex items-center"> - <svg - className="w-4 h-4 mr-1" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - xmlns="http://www.w3.org/2000/svg" - aria-hidden="true" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" - /> - </svg> - <time dateTime={post.date}>{post.date}</time> - </span> - {post.author && <span className="mr-4">•</span>} - </> - )} - {post.author && ( - <span - className="flex items-center cursor-pointer hover:text-blue-600 transition-colors" - onClick={handleAuthorClick} - > - <svg - className="w-4 h-4 mr-1" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - xmlns="http://www.w3.org/2000/svg" - aria-hidden="true" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" - /> - </svg> - {post.author.name} - </span> - )} - </div> - {post.tags && post.tags.length > 0 && ( - <div className="flex flex-wrap gap-2 mt-3"> - {post.tags.map((tag, index) => ( - <span - key={index} - onClick={() => handleTagClick(tag)} - className="text-xs bg-gray-100 text-gray-600 px-2 py-1 rounded-md hover:bg-blue-100 hover:text-blue-700 cursor-pointer transition-colors" - > - #{tag} - </span> - ))} - </div> - )} - </div> - - {/* Featured Image */} - {post.image && ( - <motion.div - className="mb-8 rounded-lg overflow-hidden shadow-lg max-w-2xl mx-auto bg-gray-50" - initial={{ opacity: 0, y: -20 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5 }} - > - <img - src={post.image} - alt={post.title} - className="w-full h-auto max-h-80 object-contain mx-auto cursor-pointer hover:scale-105 transition-transform duration-300" - onClick={() => - setModalImage({ - src: post.image, - alt: post.title, - }) - } - data-zoomable="true" - /> - </motion.div> - )} - - {/* Article Content */} - <motion.div - className="mb-12" - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - transition={{ duration: 0.5 }} - key={slug} - > - <MarkdownRenderer - content={post.content} - setZoomableImages={setZoomableImages} - /> - </motion.div> - - {/* Author Bio Section */} - {post.author && ( - <motion.div - className="bg-blue-50 rounded-lg p-6 my-8 flex items-center space-x-4 cursor-pointer hover:bg-blue-100 transition-colors" - onClick={handleAuthorClick} - whileHover={{ scale: 1.02 }} - > - <div className="w-16 h-16 flex-shrink-0"> - {post.author.avatar ? ( - <img - src={post.author.avatar} - alt={post.author.name} - className="w-16 h-16 rounded-full object-cover" - /> - ) : ( - <div className="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center text-blue-600 font-bold text-xl"> - {post.author.name.charAt(0).toUpperCase()} - </div> - )} - </div> - <div className="flex-1"> - <h4 className="font-semibold text-lg text-gray-800 hover:text-blue-600 transition-colors"> - About {post.author.name} - </h4> - <p className="text-gray-600 mt-1">{post.author.description}</p> - <p className="text-sm text-blue-600 mt-2"> - Click to view profile → - </p> - </div> - </motion.div> - )} - - {/* Tags Section */} - {post.tags && post.tags.length > 0 && ( - <div className="border-t border-gray-200 pt-6 mb-8"> - <h3 className="text-xl font-semibold mb-4 text-gray-700">Tags</h3> - <div className="flex flex-wrap gap-2"> - {post.tags.map((tag, index) => ( - <span - key={index} - onClick={() => handleTagClick(tag)} - className="px-3 py-1 bg-gray-100 text-gray-700 rounded-full text-sm hover:bg-blue-100 hover:text-blue-700 cursor-pointer transition-colors" - > - #{tag} - </span> - ))} - </div> - </div> - )} - - {/* Back to Top Button */} - <div className="fixed bottom-8 right-8 z-50"> - <motion.button - onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })} - className="p-3 bg-blue-600 text-white rounded-full shadow-lg hover:bg-blue-700 transition-colors focus:outline-none focus:ring-2 focus:ring-blue-400" - aria-label="Back to top" - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - > - <svg - xmlns="http://www.w3.org/2000/svg" - className="h-6 w-6" - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - aria-hidden="true" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M5 15l7-7 7 7" - /> - </svg> - </motion.button> - </div> - </div> - - {/* Image Modal */} - {modalImage && ( - <motion.div - className="fixed inset-0 bg-black bg-opacity-80 z-50 flex items-center justify-center p-4" - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - onClick={(e) => { - if (e.target === e.currentTarget) closeImageModal(); - }} - role="dialog" - aria-modal="true" - aria-labelledby="modal-image-title" - > - <div className="relative max-w-4xl max-h-full"> - <motion.img - src={modalImage.src} - alt={modalImage.alt} - className="max-w-full max-h-[90vh] object-contain" - initial={{ scale: 0.8, opacity: 0 }} - animate={{ scale: 1, opacity: 1 }} - transition={{ type: 'spring', stiffness: 300, damping: 25 }} - id="modal-image-title" - /> - <p className="text-white text-center mt-2 text-sm"> - {modalImage.alt} - </p> - <button - onClick={closeImageModal} - className="absolute top-2 right-2 text-white text-2xl hover:text-gray-300 bg-black bg-opacity-50 rounded-full w-8 h-8 flex items-center justify-center focus:outline-none focus:ring-2 focus:ring-white" - aria-label="Close image" - > - × - </button> - </div> - </motion.div> - )} - <ShareModal - open={shareModalOpen} - onClose={() => setShareModalOpen(false)} - url={ - post - ? `${window.location.origin}/news/${category || 'all'}/${post.slug}` - : '' - } - title={post?.title || ''} - excerpt={post?.excerpt || ''} - /> - <Footer /> - </> - ); -}; - -export default NewsDetailPage; diff --git a/src/pages/News/NewsPage.tsx b/src/pages/News/NewsPage.tsx deleted file mode 100644 index ff5391f2..00000000 --- a/src/pages/News/NewsPage.tsx +++ /dev/null @@ -1,563 +0,0 @@ -import React, { useState, useEffect, useMemo } from 'react'; -import ShareModal from '@/components/ShareModal'; -import { useNavigate, useParams } from 'react-router-dom'; -import { getAllPosts, groupPostsByCategory, Post } from '@/utils/posts-utils'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import { motion, AnimatePresence } from 'framer-motion'; -import { - fadeIn, - slideInBottom, - bounce, - simpleFadeIn, - floatUpAndFade, -} from '@/styles/Animations'; -import { - CalendarRange, - ArrowRight, - Grid3X3, - List, - Search, - TrendingUp, - Share2, - Sparkles, - Tag, - Info, -} from 'lucide-react'; - -const NewsPage: React.FC = () => { - const [shareModalOpen, setShareModalOpen] = useState(false); - const [sharePostData, setSharePostData] = useState<Post | null>(null); - const navigate = useNavigate(); - const { category: categoryParam } = useParams<{ category?: string }>(); - - const [postsByCategory, setPostsByCategory] = useState< - Record<string, Post[]> - >({}); - const [categories, setCategories] = useState<string[]>([]); - const [activeCategory, setActiveCategory] = useState<string>('All'); - const [displayCount, setDisplayCount] = useState<number>(6); - const [isLoading, setIsLoading] = useState<boolean>(true); - const [error, setError] = useState<string | null>(null); - const [viewMode, setViewMode] = useState<'grid' | 'list' | 'magazine'>( - 'grid', - ); - const [searchTerm, setSearchTerm] = useState<string>(''); - - useEffect(() => { - async function load() { - setIsLoading(true); - try { - const allPosts = await getAllPosts(); - const grouped = groupPostsByCategory(allPosts); - setPostsByCategory(grouped); - setCategories(Object.keys(grouped)); - } catch (err) { - console.error(err); - setError('Failed to load news'); - } finally { - setIsLoading(false); - } - } - load(); - }, []); - - useEffect(() => { - if (categoryParam) { - const formatted = categoryParam.toLowerCase().replace(/-/g, ' ').trim(); - const match = categories.find((cat) => cat.toLowerCase() === formatted); - if (match) { - setActiveCategory(match); - return; - } - } - setActiveCategory('All'); - }, [categoryParam, categories]); - - useEffect(() => { - const pathCat = - activeCategory === 'All' - ? 'all' - : activeCategory.toLowerCase().replace(/\s+/g, '-'); - navigate(`/news/${pathCat}`, { replace: true }); - setDisplayCount(6); - }, [activeCategory, navigate]); - - const sortedCategories = useMemo(() => { - const others = categories - .filter((c) => c !== 'All') - .sort((a, b) => a.localeCompare(b)); - return ['All', ...others]; - }, [categories]); - - const filteredPosts = useMemo(() => { - let posts = postsByCategory[activeCategory] || []; - - // Filter by search term - if (searchTerm) { - posts = posts.filter( - (post) => - post.title.toLowerCase().includes(searchTerm.toLowerCase()) || - post.excerpt?.toLowerCase().includes(searchTerm.toLowerCase()) || - post.category?.toLowerCase().includes(searchTerm.toLowerCase()), - ); - } - - return posts; - }, [postsByCategory, activeCategory, searchTerm]); - - const visiblePosts = useMemo(() => { - return filteredPosts.slice(0, displayCount); - }, [filteredPosts, displayCount]); - - const hasMore = filteredPosts.length > displayCount; - - const handleCategoryClick = (cat: string) => setActiveCategory(cat); - - const handleShowMore = () => { - const total = filteredPosts.length; - setDisplayCount((prev) => Math.min(prev + 6, total)); - }; - - const handlePostClick = (slug: string) => { - const catPath = - activeCategory === 'All' - ? 'all' - : activeCategory.toLowerCase().replace(/\s+/g, '-'); - navigate(`/news/${catPath}/${slug}`); - }; - - const handleShareClick = (post: Post, e: React.MouseEvent) => { - e.stopPropagation(); - setSharePostData(post); - setShareModalOpen(true); - }; - - if (isLoading) { - return ( - <> - <Header /> - <div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-green-50"> - <div className="container mx-auto px-4 py-20"> - <motion.div - className="text-center max-w-2xl mx-auto" - variants={floatUpAndFade} - initial="hidden" - animate="visible" - > - <div className="relative mb-9"> - <h1 className="text-8xl font-bold font-Caveat text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-green-600"> - NEWS - </h1> - <div className="absolute -top-4 -right-5"> - <Sparkles - className="text-yellow-400 animate-pulse" - size={30} - /> - </div> - </div> - - <div className="bg-white rounded-2xl p-8 shadow-xl"> - <div className="animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-600 mx-auto mb-6" /> - <h2 className="text-xl font-semibold text-gray-800 mb-2"> - Loading Latest News - </h2> - <p className="text-gray-600"> - Fetching the most recent stories from Sugar Labs community... - </p> - </div> - </motion.div> - </div> - </div> - <Footer /> - </> - ); - } - - if (error) { - return ( - <> - <Header /> - <div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-green-50"> - <div className="container mx-auto px-4 py-20 text-center"> - <motion.h1 - className="text-8xl font-bold font-Caveat text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-green-600 mb-8" - variants={floatUpAndFade} - initial="hidden" - animate="visible" - > - NEWS - </motion.h1> - <div className="bg-white rounded-2xl p-8 shadow-xl max-w-md mx-auto"> - <div className="text-red-500 mb-4"> - <svg - className="w-16 h-16 mx-auto" - fill="currentColor" - viewBox="0 0 20 20" - > - <path - fillRule="evenodd" - d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" - clipRule="evenodd" - /> - </svg> - </div> - <h2 className="text-xl font-semibold text-gray-800 mb-2"> - Oops! Something went wrong - </h2> - <p className="text-red-600 mb-6">{error}</p> - <button - onClick={() => window.location.reload()} - className="px-6 py-3 bg-blue-600 text-white rounded-xl hover:bg-blue-700 transition-all duration-300 font-medium shadow-lg hover:shadow-xl transform hover:-translate-y-1" - > - Try Again - </button> - </div> - </div> - </div> - <Footer /> - </> - ); - } - - return ( - <> - <Header /> - <div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-green-50"> - {/* Enhanced Hero Section */} - <div className="relative overflow-hidden"> - <div className="absolute inset-0"> - <div className="absolute top-10 left-10 w-32 h-32 bg-blue-200 opacity-20 rounded-full"></div> - <div className="absolute bottom-10 right-10 w-48 h-48 bg-green-200 opacity-15 rounded-full"></div> - <div className="absolute top-1/2 left-1/3 w-24 h-24 bg-blue-300 opacity-10 rounded-full"></div> - </div> - - <div className="relative container mx-auto px-4 py-20"> - <motion.div - className="text-center max-w-4xl mx-auto" - variants={fadeIn} - initial="hidden" - animate="visible" - > - <div className="flex items-center justify-center mb-6"> - <Sparkles - className="text-blue-500 mr-4 animate-pulse" - size={32} - /> - <h1 className="text-8xl font-bold font-Caveat text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-green-600"> - NEWS - </h1> - <TrendingUp - className="text-green-500 ml-4 animate-bounce" - size={32} - /> - </div> - - <p className="text-xl mb-8 text-gray-700 leading-relaxed"> - Discover the latest innovations, community updates, and - educational insights from the Sugar Labs ecosystem - </p> - - <div className="flex flex-wrap justify-center gap-4 text-sm"></div> - </motion.div> - </div> - </div> - - <div className="container mx-auto px-4 py-8"> - {/* Enhanced Filters and Controls */} - <div className="bg-white rounded-2xl shadow-xl p-6 mb-8 border border-gray-100"> - <div className="flex flex-col lg:flex-row gap-6"> - {/* Search Bar */} - <div className="flex-1"> - <div className="relative"> - <Search - className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" - size={20} - /> - <input - type="text" - placeholder="Search articles, topics, or categories..." - value={searchTerm} - onChange={(e) => setSearchTerm(e.target.value)} - className="w-full pl-10 pr-4 py-3 border border-gray-200 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-300" - /> - </div> - </div> - - {/* View Mode Toggle */} - <div className="flex items-center gap-4"> - <div className="flex bg-gray-100 rounded-xl p-1"> - <button - onClick={() => setViewMode('grid')} - className={`p-3 rounded-lg transition-all duration-300 ${ - viewMode === 'grid' - ? 'bg-white text-blue-600 shadow-md' - : 'text-gray-600 hover:text-blue-600' - }`} - title="Grid View" - > - <Grid3X3 size={18} /> - </button> - <button - onClick={() => setViewMode('list')} - className={`p-3 rounded-lg transition-all duration-300 ${ - viewMode === 'list' - ? 'bg-white text-blue-600 shadow-md' - : 'text-gray-600 hover:text-blue-600' - }`} - title="List View" - > - <List size={18} /> - </button> - </div> - </div> - </div> - - {/* Category Filters - Always Visible */} - <div className="mt-6 pt-6 border-t border-gray-200"> - <div className="flex items-center mb-4"> - <Tag className="text-gray-600 mr-2" size={20} /> - <h3 className="text-lg font-semibold text-gray-800"> - Categories - </h3> - </div> - <div className="flex flex-wrap gap-2"> - {sortedCategories.map((cat) => ( - <motion.button - key={cat} - onClick={() => handleCategoryClick(cat)} - className={`px-4 py-2 rounded-full text-sm font-medium transition-all duration-300 ${ - activeCategory === cat - ? 'bg-[#144EEC] text-white shadow-lg' - : 'bg-gray-100 text-gray-700 hover:bg-gray-200 hover:shadow-md' - }`} - whileHover={{ scale: 1.05, cursor: 'pointer' }} - whileTap={{ scale: 0.95 }} - > - {cat} - {activeCategory === cat && ( - <span className="ml-2 text-xs bg-white text-black bg-opacity-30 rounded-full px-2 py-1"> - {(postsByCategory[cat] || []).length} - </span> - )} - </motion.button> - ))} - </div> - </div> - </div> - - {/* Template Category Note */} - {activeCategory.toLowerCase() === 'template' && ( - <motion.div - className="bg-amber-50 border border-amber-200 rounded-2xl p-6 mb-8 shadow-sm" - initial={{ opacity: 0, y: 20 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.3 }} - > - <div className="flex items-start gap-3"> - <Info className="text-amber-600 mt-1 flex-shrink-0" size={20} /> - <div> - <p className="text-amber-800 font-medium"> - <strong>Note:</strong> These are developer templates for - post formatting. - </p> - </div> - </div> - </motion.div> - )} - - {/* Current Category Display */} - <motion.div - className="text-center mb-8" - variants={slideInBottom} - initial="hidden" - animate="visible" - > - <h2 className="text-5xl font-Caveat text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-green-600 mb-2"> - {activeCategory} {searchTerm && `· "${searchTerm}"`} - </h2> - <p className="text-gray-600 flex items-center justify-center gap-2"> - <span>{filteredPosts.length} articles found</span> - {searchTerm && ( - <button - onClick={() => setSearchTerm('')} - className="text-blue-600 hover:text-blue-700 underline text-sm" - > - Clear search - </button> - )} - </p> - </motion.div> - - {/* Posts Display */} - <AnimatePresence mode="wait"> - {visiblePosts.length === 0 ? ( - <motion.div - className="text-center py-20" - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - > - <div className="bg-white rounded-2xl p-12 shadow-xl max-w-md mx-auto"> - <div className="text-6xl mb-6">🔍</div> - <h3 className="text-2xl font-bold text-gray-800 mb-4"> - No articles found - </h3> - <p className="text-gray-600 mb-6"> - {searchTerm - ? `No articles match "${searchTerm}" in this category.` - : 'There are no articles in this category yet.'} - </p> - {searchTerm && ( - <button - onClick={() => setSearchTerm('')} - className="px-6 py-3 bg-blue-600 text-white rounded-xl hover:bg-blue-700 transition-colors" - > - Clear Search - </button> - )} - </div> - </motion.div> - ) : ( - <motion.div - className={`mb-12 ${ - viewMode === 'grid' - ? 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8' - : viewMode === 'list' - ? 'space-y-8' - : 'grid grid-cols-1 lg:grid-cols-2 gap-8' - }`} - initial="hidden" - animate="visible" - > - {visiblePosts.map((post, index) => ( - <motion.article - key={post.slug} - className={`bg-white rounded-2xl shadow-lg hover:shadow-2xl transition-all duration-500 cursor-pointer overflow-hidden group ${ - viewMode === 'list' ? 'flex' : '' - }`} - onClick={() => handlePostClick(post.slug)} - variants={simpleFadeIn} - custom={index} - layout - whileHover={{ y: -5 }} - > - <div - className={`${viewMode === 'list' ? 'w-1/3' : ''} relative`} - > - <div - className={`${viewMode === 'list' ? 'h-full' : 'h-56'} overflow-hidden`} - > - {post.image ? ( - <img - src={post.image} - alt={post.title} - className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700" - /> - ) : ( - <div className="w-full h-full bg-gradient-to-br from-blue-100 via-purple-50 to-green-100 flex items-center justify-center"> - <div className="text-6xl opacity-50">📰</div> - </div> - )} - </div> - - {post.category && ( - <span className="absolute top-4 left-4 px-3 py-1 text-xs font-bold bg-green-500 text-white rounded-full shadow-lg"> - {post.category} - </span> - )} - - <div className="absolute top-4 right-4 flex gap-2"> - <button - onClick={(e) => handleShareClick(post, e)} - className="p-2 rounded-full bg-gradient-to-r from-blue-600 to-blue-700 text-white shadow hover:from-blue-700 hover:to-green-600 focus:outline-none focus:ring-2 focus:ring-blue-400 transition-all duration-300 cursor-pointer" - title="Share" - type="button" - > - <Share2 size={16} className="text-white" /> - </button> - </div> - </div> - - <div - className={`${viewMode === 'list' ? 'w-2/3' : ''} p-6 flex flex-col justify-between`} - > - <div> - <h3 - className={`font-bold text-gray-800 mb-3 line-clamp-2 group-hover:text-blue-600 transition-colors ${ - viewMode === 'list' ? 'text-xl' : 'text-lg' - }`} - > - {post.title} - </h3> - <p className="text-gray-600 text-sm line-clamp-3 mb-4 leading-relaxed"> - {post.excerpt} - </p> - </div> - - <div className="flex items-center justify-between"> - {post.date && ( - <div className="flex items-center text-sm text-gray-500"> - <CalendarRange size={14} className="mr-2" /> - {post.date} - </div> - )} - <div className="flex items-center text-blue-600 text-sm font-medium group-hover:text-blue-700"> - Read more - <ArrowRight - size={14} - className="ml-1 group-hover:translate-x-1 transition-transform duration-300" - /> - </div> - </div> - </div> - </motion.article> - ))} - </motion.div> - )} - </AnimatePresence> - - {/* Enhanced Load More Button */} - {hasMore && ( - <div className="flex justify-center"> - <motion.button - onClick={handleShowMore} - className="relative px-8 py-4 bg-gradient-to-r from-blue-600 to-green-600 text-white hover:from-blue-700 hover:to-green-700 cursor-pointer transition-all duration-300 rounded-2xl shadow-lg hover:shadow-2xl font-medium flex items-center gap-3 group overflow-hidden" - variants={bounce} - initial="hidden" - animate="visible" - whileHover="hover" - whileTap="tap" - > - <div className="absolute inset-0 bg-white opacity-0 group-hover:opacity-10 transition-opacity duration-300"></div> - <span className="relative z-10">Load More Articles</span> - <ArrowRight - size={18} - className="relative z-10 group-hover:translate-x-1 transition-transform duration-300" - /> - <div className="absolute -top-1 -right-1 w-6 h-6 bg-yellow-400 rounded-full flex items-center justify-center"> - <span className="text-xs font-bold text-gray-800"> - {Math.min(6, filteredPosts.length - displayCount)} - </span> - </div> - </motion.button> - </div> - )} - </div> - </div> - <ShareModal - open={shareModalOpen} - onClose={() => setShareModalOpen(false)} - url={ - sharePostData - ? `${window.location.origin}/news/${activeCategory === 'All' ? 'all' : activeCategory.toLowerCase().replace(/\s+/g, '-')}/${sharePostData.slug}` - : '' - } - title={sharePostData?.title || ''} - excerpt={sharePostData?.excerpt || ''} - /> - <Footer /> - </> - ); -}; - -export default NewsPage; diff --git a/src/pages/News/TagPage.tsx b/src/pages/News/TagPage.tsx deleted file mode 100644 index 80c5a569..00000000 --- a/src/pages/News/TagPage.tsx +++ /dev/null @@ -1,605 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { useParams, useNavigate } from 'react-router-dom'; -import { motion, AnimatePresence } from 'framer-motion'; -import { - ArrowLeft, - Tag, - Calendar, - User, - Search, - Grid, - List, - Filter, - ChevronDown, - BookOpen, - TrendingUp, -} from 'lucide-react'; - -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import { getPostsByTag, Post, getAllTags } from '@/utils/posts-utils'; - -const TagPage: React.FC = () => { - const { tag } = useParams<{ tag: string }>(); - const navigate = useNavigate(); - - const [posts, setPosts] = useState<Post[]>([]); - const [filteredPosts, setFilteredPosts] = useState<Post[]>([]); - const [, setAllTags] = useState<string[]>([]); - const [isLoading, setIsLoading] = useState(true); - const [error, setError] = useState<string | null>(null); - - // UI State - const [displayCount, setDisplayCount] = useState(8); - const [searchTerm, setSearchTerm] = useState(''); - const [selectedCategory, setSelectedCategory] = useState('All'); - const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid'); - const [sortBy, setSortBy] = useState<'date' | 'title' | 'relevance'>('date'); - - useEffect(() => { - const loadTagData = async () => { - if (!tag) return; - - setIsLoading(true); - try { - const [tagPosts, tags] = await Promise.all([ - getPostsByTag(tag), - getAllTags(), - ]); - - setPosts(tagPosts); - setFilteredPosts(tagPosts); - setAllTags(tags); - document.title = `#${tag} - SugarLabs`; - } catch (err) { - console.error('Error loading tag posts:', err); - setError('Failed to load posts'); - } finally { - setIsLoading(false); - } - }; - - loadTagData(); - }, [tag]); - - // Filter and sort posts - useEffect(() => { - let filtered = [...posts]; - - // Filter by search term - if (searchTerm) { - filtered = filtered.filter( - (post) => - post.title.toLowerCase().includes(searchTerm.toLowerCase()) || - post.excerpt?.toLowerCase().includes(searchTerm.toLowerCase()), - ); - } - - // Filter by category - if (selectedCategory !== 'All') { - filtered = filtered.filter((post) => post.category === selectedCategory); - } - - // Sort posts - filtered.sort((a, b) => { - switch (sortBy) { - case 'date': - return new Date(b.date).getTime() - new Date(a.date).getTime(); - case 'title': - return a.title.localeCompare(b.title); - case 'relevance': { - const aTagCount = a.tags.filter((t) => - t.toLowerCase().includes(tag?.toLowerCase() || ''), - ).length; - const bTagCount = b.tags.filter((t) => - t.toLowerCase().includes(tag?.toLowerCase() || ''), - ).length; - return bTagCount - aTagCount; - } - default: - return 0; - } - }); - - setFilteredPosts(filtered); - setDisplayCount(8); - }, [posts, searchTerm, selectedCategory, sortBy, tag]); - - const handlePostClick = (post: Post) => { - const categoryPath = post.category.toLowerCase().replace(/\s+/g, '-'); - navigate(`/news/${categoryPath}/${post.slug}`); - }; - - const handleTagClick = (clickedTag: string) => { - if (clickedTag !== tag) { - navigate(`/tags/${clickedTag}`); - } - }; - - const handleShowMore = () => { - setDisplayCount((prev) => Math.min(prev + 8, filteredPosts.length)); - }; - - const getUniqueCategories = () => { - const categories = Array.from(new Set(posts.map((post) => post.category))); - return ['All', ...categories.sort()]; - }; - - const getRelatedTags = () => { - const tagFrequency: Record<string, number> = {}; - posts.forEach((post) => { - post.tags.forEach((postTag) => { - if (postTag !== tag) { - tagFrequency[postTag] = (tagFrequency[postTag] || 0) + 1; - } - }); - }); - - return Object.entries(tagFrequency) - .sort(([, a], [, b]) => b - a) - .slice(0, 8) - .map(([tagName]) => tagName); - }; - - const visiblePosts = filteredPosts.slice(0, displayCount); - const hasMore = filteredPosts.length > displayCount; - const relatedTags = getRelatedTags(); - - if (isLoading) { - return ( - <> - <Header /> - <div className="container mx-auto px-4 py-16 flex justify-center items-center min-h-screen"> - <div className="flex flex-col items-center"> - <div className="animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-600 mb-4"></div> - <p className="text-gray-600">Loading posts...</p> - </div> - </div> - <Footer /> - </> - ); - } - - if (error) { - return ( - <> - <Header /> - <div className="container mx-auto px-4 py-16 text-center min-h-screen flex flex-col justify-center"> - <h1 className="text-3xl font-bold mb-4 text-red-600"> - Error Loading Posts - </h1> - <p className="mb-8 text-gray-600">{error}</p> - <button - onClick={() => navigate('/news')} - className="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors mx-auto" - > - Back to News - </button> - </div> - <Footer /> - </> - ); - } - - return ( - <> - <Header /> - <div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-green-50"> - <div className="container mx-auto px-4 py-8 max-w-7xl"> - {/* Back Button */} - <motion.button - onClick={() => navigate(-1)} - className="mb-6 px-4 py-2 flex items-center text-blue-600 hover:text-blue-700 transition-colors rounded-md hover:bg-blue-50" - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - > - <ArrowLeft className="h-5 w-5 mr-2" /> - Back - </motion.button> - - {/* Tag Header */} - <motion.div - className="bg-white rounded-2xl shadow-xl p-6 sm:p-8 mb-8" - initial={{ opacity: 0, y: 20 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5 }} - > - <div className="text-center"> - <div className="flex items-center justify-center gap-3 mb-4"> - <div className="p-3 bg-blue-100 rounded-full"> - <Tag className="w-8 h-8 text-blue-600" /> - </div> - <h1 className="text-3xl sm:text-4xl lg:text-5xl font-bold text-gray-900"> - #{tag} - </h1> - </div> - <p className="text-gray-600 text-lg mb-6"> - {posts.length} {posts.length === 1 ? 'article' : 'articles'}{' '} - tagged with #{tag} - </p> - - {/* Stats */} - <div className="flex flex-wrap justify-center gap-4 text-sm"> - <div className="flex items-center gap-2 bg-blue-50 px-4 py-2 rounded-full"> - <BookOpen className="w-4 h-4 text-blue-600" /> - <span className="font-medium">{posts.length} Articles</span> - </div> - <div className="flex items-center gap-2 bg-green-50 px-4 py-2 rounded-full"> - <TrendingUp className="w-4 h-4 text-green-600" /> - <span className="font-medium"> - {getUniqueCategories().length - 1} Categories - </span> - </div> - <div className="flex items-center gap-2 bg-purple-50 px-4 py-2 rounded-full"> - <Tag className="w-4 h-4 text-purple-600" /> - <span className="font-medium"> - {relatedTags.length} Related Tags - </span> - </div> - </div> - </div> - </motion.div> - - <div className="grid grid-cols-1 xl:grid-cols-4 gap-6 lg:gap-8"> - {/* Main Content */} - <div className="xl:col-span-3"> - {/* Controls */} - {posts.length > 0 && ( - <motion.div - className="bg-white rounded-2xl shadow-xl p-4 sm:p-6 mb-6" - initial={{ opacity: 0, y: 20 }} - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.5, delay: 0.1 }} - > - <div className="flex flex-col lg:flex-row lg:items-center justify-between gap-4"> - <div className="flex items-center gap-2"> - <Filter className="w-5 h-5 text-gray-600" /> - <span className="font-medium text-gray-900"> - Showing {filteredPosts.length} of {posts.length}{' '} - articles - </span> - </div> - - <div className="flex flex-col sm:flex-row gap-3"> - {/* Search */} - <div className="relative"> - <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" /> - <input - type="text" - placeholder="Search in results..." - value={searchTerm} - onChange={(e) => setSearchTerm(e.target.value)} - className="pl-10 pr-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm w-full sm:w-auto" - /> - </div> - - {/* Category Filter */} - <select - value={selectedCategory} - onChange={(e) => setSelectedCategory(e.target.value)} - className="px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" - > - {getUniqueCategories().map((category) => ( - <option key={category} value={category}> - {category} - </option> - ))} - </select> - - {/* Sort */} - <select - value={sortBy} - onChange={(e) => - setSortBy( - e.target.value as 'date' | 'title' | 'relevance', - ) - } - className="px-3 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" - > - <option value="date">Latest First</option> - <option value="title">A-Z</option> - <option value="relevance">Most Relevant</option> - </select> - - {/* View Toggle */} - <div className="flex bg-gray-100 rounded-lg p-1"> - <button - onClick={() => setViewMode('grid')} - className={`p-2 rounded-md transition-colors ${ - viewMode === 'grid' - ? 'bg-white text-blue-600 shadow-sm' - : 'text-gray-600' - }`} - > - <Grid className="w-4 h-4" /> - </button> - <button - onClick={() => setViewMode('list')} - className={`p-2 rounded-md transition-colors ${ - viewMode === 'list' - ? 'bg-white text-blue-600 shadow-sm' - : 'text-gray-600' - }`} - > - <List className="w-4 h-4" /> - </button> - </div> - </div> - </div> - </motion.div> - )} - - {/* Posts Display */} - {filteredPosts.length === 0 ? ( - <motion.div - className="bg-white rounded-2xl shadow-xl p-12 text-center" - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - > - <div className="text-6xl mb-6"> - {searchTerm || selectedCategory !== 'All' ? '🔍' : '🏷️'} - </div> - <h3 className="text-2xl font-bold text-gray-800 mb-4"> - {searchTerm || selectedCategory !== 'All' - ? 'No matching articles' - : 'No articles found'} - </h3> - <p className="text-gray-600 mb-6"> - {searchTerm || selectedCategory !== 'All' - ? 'Try adjusting your search or filter criteria' - : `No articles are tagged with #${tag} yet.`} - </p> - {(searchTerm || selectedCategory !== 'All') && ( - <button - onClick={() => { - setSearchTerm(''); - setSelectedCategory('All'); - }} - className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors" - > - Clear Filters - </button> - )} - </motion.div> - ) : ( - <> - <motion.div - className={ - viewMode === 'grid' - ? 'grid grid-cols-1 md:grid-cols-2 gap-6 mb-8' - : 'space-y-6 mb-8' - } - initial="hidden" - animate="visible" - > - <AnimatePresence> - {visiblePosts.map((post, index) => ( - <motion.article - key={post.slug} - className={` - bg-white rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 - cursor-pointer overflow-hidden group - ${viewMode === 'list' ? 'flex' : ''} - `} - onClick={() => handlePostClick(post)} - initial={{ opacity: 0, y: 20 }} - animate={{ opacity: 1, y: 0 }} - exit={{ opacity: 0, y: -20 }} - transition={{ duration: 0.3, delay: index * 0.05 }} - whileHover={{ y: -5 }} - > - <div - className={ - viewMode === 'list' ? 'w-1/3 sm:w-1/4' : '' - } - > - {post.image ? ( - <img - src={post.image} - alt={post.title} - className={`w-full object-cover ${ - viewMode === 'list' - ? 'h-full' - : 'h-48 sm:h-56' - }`} - /> - ) : ( - <div - className={`w-full bg-gradient-to-br from-blue-100 to-purple-100 flex items-center justify-center ${ - viewMode === 'list' - ? 'h-full' - : 'h-48 sm:h-56' - }`} - > - <div className="text-4xl opacity-50">📰</div> - </div> - )} - </div> - - <div - className={`p-4 sm:p-6 ${viewMode === 'list' ? 'w-2/3 sm:w-3/4' : ''}`} - > - <div className="flex items-center gap-2 mb-3"> - <span className="px-3 py-1 text-xs font-bold bg-green-500 text-white rounded-full"> - {post.category} - </span> - </div> - - <h2 - className={`font-bold text-gray-900 mb-3 group-hover:text-blue-600 transition-colors line-clamp-2 ${ - viewMode === 'list' ? 'text-lg' : 'text-xl' - }`} - > - {post.title} - </h2> - - <p className="text-gray-600 mb-4 line-clamp-2 text-sm"> - {post.excerpt} - </p> - - <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3"> - <div className="flex items-center gap-4 text-sm text-gray-500"> - {post.date && ( - <div className="flex items-center gap-1"> - <Calendar className="w-4 h-4" /> - <span>{post.date}</span> - </div> - )} - {post.author && ( - <div className="flex items-center gap-1"> - <User className="w-4 h-4" /> - <span>{post.author.name}</span> - </div> - )} - </div> - - <div className="flex flex-wrap gap-1"> - {post.tags.slice(0, 3).map((postTag) => ( - <button - key={postTag} - onClick={(e) => { - e.stopPropagation(); - handleTagClick(postTag); - }} - className={`px-2 py-1 text-xs rounded-full transition-colors ${ - postTag === tag - ? 'bg-blue-100 text-blue-600 font-semibold' - : 'bg-gray-100 text-gray-600 hover:bg-blue-50 hover:text-blue-600' - }`} - > - #{postTag} - </button> - ))} - {post.tags.length > 3 && ( - <span className="px-2 py-1 text-xs bg-gray-100 text-gray-500 rounded-full"> - +{post.tags.length - 3} - </span> - )} - </div> - </div> - </div> - </motion.article> - ))} - </AnimatePresence> - </motion.div> - - {/* Load More Button */} - {hasMore && ( - <div className="text-center"> - <motion.button - onClick={handleShowMore} - className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium flex items-center gap-2 mx-auto" - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - > - Load More Articles - <ChevronDown className="w-4 h-4" /> - <span className="text-xs bg-blue-500 px-2 py-1 rounded-full"> - +{Math.min(8, filteredPosts.length - displayCount)} - </span> - </motion.button> - </div> - )} - </> - )} - </div> - - {/* Sidebar */} - <motion.div - className="space-y-6" - initial={{ opacity: 0, x: 20 }} - animate={{ opacity: 1, x: 0 }} - transition={{ duration: 0.5, delay: 0.2 }} - > - {/* Related Tags */} - {relatedTags.length > 0 && ( - <div className="bg-white rounded-2xl shadow-xl p-6"> - <h3 className="text-lg font-bold text-gray-900 mb-4"> - Related Tags - </h3> - <div className="flex flex-wrap gap-2"> - {relatedTags.map((relatedTag) => ( - <button - key={relatedTag} - onClick={() => handleTagClick(relatedTag)} - className="px-3 py-1 text-sm bg-gray-100 text-gray-700 rounded-full hover:bg-blue-100 hover:text-blue-700 transition-colors" - > - #{relatedTag} - </button> - ))} - </div> - </div> - )} - - {/* Tag Stats */} - <div className="bg-white rounded-2xl shadow-xl p-6"> - <h3 className="text-lg font-bold text-gray-900 mb-4"> - Tag Statistics - </h3> - <div className="space-y-3"> - <div className="flex justify-between items-center"> - <span className="text-gray-600">Total Articles</span> - <span className="font-semibold text-blue-600"> - {posts.length} - </span> - </div> - <div className="flex justify-between items-center"> - <span className="text-gray-600">Categories</span> - <span className="font-semibold text-gray-900"> - {getUniqueCategories().length - 1} - </span> - </div> - <div className="flex justify-between items-center"> - <span className="text-gray-600">Related Tags</span> - <span className="font-semibold text-gray-900"> - {relatedTags.length} - </span> - </div> - </div> - </div> - - {/* Popular in Category */} - {getUniqueCategories().length > 2 && ( - <div className="bg-white rounded-2xl shadow-xl p-6"> - <h3 className="text-lg font-bold text-gray-900 mb-4"> - Categories - </h3> - <div className="space-y-2"> - {getUniqueCategories() - .slice(1) - .map((category) => { - const count = posts.filter( - (post) => post.category === category, - ).length; - return ( - <button - key={category} - onClick={() => setSelectedCategory(category)} - className={`w-full flex justify-between items-center p-2 rounded-lg transition-colors text-left ${ - selectedCategory === category - ? 'bg-blue-50 text-blue-700' - : 'hover:bg-gray-50' - }`} - > - <span className="text-sm font-medium"> - {category} - </span> - <span className="text-xs bg-gray-100 px-2 py-1 rounded-full"> - {count} - </span> - </button> - ); - })} - </div> - </div> - )} - </motion.div> - </div> - </div> - </div> - <Footer /> - </> - ); -}; - -export default TagPage; diff --git a/src/pages/NotFoundPage.tsx b/src/pages/NotFoundPage.tsx deleted file mode 100644 index 76f17fb9..00000000 --- a/src/pages/NotFoundPage.tsx +++ /dev/null @@ -1,360 +0,0 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; -import { motion } from 'framer-motion'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import { ArrowLeft, Home, AlertCircle } from 'lucide-react'; -import { - fadeIn, - slideInBottom, - slideInRight, - slideInLeft, - bounce, - dividerVariants, - staggerContainer, - statCard, - decorativeElement, - buttonAnimation, - subtleRise, - cardFadeIn, -} from '@/styles/Animations'; - -const NotFoundPage: React.FC = () => { - return ( - <div className="min-h-screen flex flex-col font-sans bg-[#FFFEF9]"> - <Header /> - <main className="flex-grow"> - {/* Hero Section */} - <motion.section - initial="hidden" - animate="visible" - variants={fadeIn} - className="relative py-5 md:py-15 overflow-hidden bg-gradient-to-b from-black via-gray-800 to-white" - > - <div className="absolute inset-0 z-0 overflow-hidden"> - <div className="absolute inset-0 opacity-10"></div> - <div - className="absolute inset-0" - style={{ - backgroundImage: - 'radial-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1px)', - backgroundSize: '20px 20px', - }} - ></div> - </div> - <div className="container mx-auto px-4 md:px-6"> - <div className="flex flex-col items-center text-center z-10 relative"> - <motion.div - className="flex items-center justify-center mb-6" - variants={decorativeElement} - initial="hidden" - animate="visible" - > - <div className="bg-[#D4B062] p-4 rounded-full border-4 border-white/20"> - <AlertCircle className="h-12 w-12 text-white" /> - </div> - </motion.div> - <motion.h1 - className="font-black text-5xl md:text-6xl lg:text-7xl mb-6 text-white" - variants={slideInBottom} - initial="hidden" - animate="visible" - > - <span className="text-[#D4B062]">Page Not Found</span> - </motion.h1> - <motion.div - className="w-20 h-1 bg-[#D4B062] mb-6" - variants={dividerVariants} - initial="hidden" - animate="visible" - ></motion.div> - <motion.p - className="text-lg md:text-xl mb-10 text-gray-300 max-w-2xl leading-relaxed" - variants={fadeIn} - initial="hidden" - animate="visible" - transition={{ delay: 0.3 }} - > - Oops! It looks like the page you were looking for doesn't exist - or has been moved. - </motion.p> - <motion.a - href="#solutions" - className="bg-[#D4B062] hover:bg-white hover:text-black text-black font-medium px-8 py-3 rounded-full transition-all duration-300 shadow-lg hover:shadow-xl" - variants={bounce} - initial="hidden" - animate="visible" - whileHover="hover" - whileTap="tap" - > - Find Solutions - </motion.a> - </div> - </div> - </motion.section> - - {/* Main Content */} - <motion.section - initial="hidden" - whileInView="visible" - viewport={{ once: true, margin: '-100px' }} - variants={fadeIn} - className="py-16 bg-[#FFFEF9]" - > - <div className="container mx-auto px-4 md:px-6 max-w-4xl"> - <div className="bg-white rounded-xl shadow-lg overflow-hidden border border-gray-100 p-8"> - <div className="flex flex-col lg:flex-row items-center justify-center"> - <motion.div - className="w-full lg:w-1/2 flex justify-center mb-8 lg:mb-0" - variants={slideInLeft} - transition={{ duration: 0.5 }} - > - <div className="relative w-64 h-64 flex items-center justify-center"> - {[...Array(4)].map((_, i) => ( - <motion.div - key={i} - className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-[#D4B062]/30" - style={{ - width: `${(i + 1) * 50}px`, - height: `${(i + 1) * 50}px`, - }} - animate={{ - scale: [1, 1.5, 1], - opacity: [0, 0.5, 0], - }} - transition={{ - duration: 2, - delay: i * 0.5, - repeat: Infinity, - }} - ></motion.div> - ))} - - <motion.div - className="absolute z-10" - animate={{ - y: [0, -10, 0], - rotate: [0, -2, 0], - }} - transition={{ - duration: 3, - repeat: Infinity, - repeatType: 'reverse', - }} - > - <div className="relative"> - <svg - width="120" - height="120" - viewBox="0 0 120 120" - fill="none" - xmlns="http://www.w3.org/2000/svg" - > - <circle cx="60" cy="60" r="60" fill="#D4B062" /> - <text - x="60" - y="65" - textAnchor="middle" - dominantBaseline="middle" - fill="white" - fontSize="32" - fontWeight="bold" - style={{ fontFamily: 'Arial, sans-serif' }} - > - 404 - </text> - </svg> - <motion.div - className="absolute inset-0 rounded-full border-4 border-[#D4B062]" - animate={{ - scale: [1, 1.15, 1], - opacity: [0.7, 0.3, 0.7], - }} - transition={{ - duration: 2, - repeat: Infinity, - }} - ></motion.div> - </div> - </motion.div> - </div> - </motion.div> - - {/* Right side - Connection Status */} - <motion.div - variants={slideInRight} - className="w-full lg:w-1/2 lg:pl-8" - transition={{ duration: 0.5, delay: 0.2 }} - > - <h3 className="font-bold text-2xl text-magazine-navy mb-4 border-b-2 border-[#D4B062] pb-2 inline-block"> - Connection Status - </h3> - - <div className="space-y-4"> - <motion.div - className="flex items-center" - whileHover={{ x: 5 }} - > - <div className="w-3 h-3 bg-red-500 rounded-full mr-3 animate-pulse"></div> - <p className="text-gray-700">Resource not found</p> - </motion.div> - - <motion.div - className="flex items-center" - whileHover={{ x: 5 }} - > - <div className="w-3 h-3 bg-green-500 rounded-full mr-3"></div> - <p className="text-gray-700">Server connection: Active</p> - </motion.div> - - <motion.div className="mt-6" variants={bounce}> - <Link to="/"> - <motion.button - className="w-full py-2.5 bg-[#D4B062] hover:bg-magazine-navy text-white font-medium rounded-lg transition-all duration-300 shadow hover:shadow-lg flex items-center justify-center" - variants={buttonAnimation} - whileHover="whileHover" - whileTap="whileTap" - > - <Home className="h-5 w-5 mr-2" /> - Return to Homepage - </motion.button> - </Link> - </motion.div> - </div> - </motion.div> - </div> - </div> - </div> - </motion.section> - - {/* Solutions Section */} - <motion.section - id="solutions" - initial="hidden" - whileInView="visible" - viewport={{ once: true, margin: '-100px' }} - variants={staggerContainer} - className="py-16 bg-[#FFFEF9]" - > - <div className="container mx-auto px-4 md:px-6"> - <motion.h2 - variants={subtleRise} - className="text-3xl font-bold mb-12 text-center text-magazine-navy border-b-2 border-[#D4B062] pb-2 inline-block mx-auto" - > - What Happened? - </motion.h2> - - <div className="max-w-4xl mx-auto mb-16"> - <motion.div - variants={fadeIn} - className="bg-white p-6 rounded-xl shadow-md border border-gray-100" - > - <p className="text-gray-600 mb-6 leading-relaxed"> - The page you're looking for might have been removed, had its - name changed, or is temporarily unavailable. This could be due - to: - </p> - - <div className="space-y-4 pl-4"> - {[ - 'A mistyped URL', - 'An outdated link from another website', - 'A page that has been moved during a website redesign', - 'A deleted or unpublished page', - ].map((reason, index) => ( - <motion.div - key={index} - className="flex items-start" - custom={index} - variants={cardFadeIn} - > - <div className="mr-3 mt-1 text-[#D4B062]">•</div> - <p className="text-gray-700">{reason}</p> - </motion.div> - ))} - </div> - </motion.div> - </div> - - <motion.h2 - variants={subtleRise} - className="text-3xl font-bold mb-12 text-center text-magazine-navy" - > - What You Can Do - </motion.h2> - - <div className="max-w-3xl mx-auto"> - <div className="grid grid-cols-1 md:grid-cols-2 gap-8"> - {[ - { - icon: <ArrowLeft className="h-6 w-6" />, - title: 'Go Back', - description: - 'Return to the previous page you were viewing.', - action: () => window.history.back(), - actionText: 'Previous Page', - }, - { - icon: <Home className="h-6 w-6" />, - title: 'Homepage', - description: - 'Visit our homepage to start fresh and find what you need.', - link: '/', - actionText: 'Back to Home', - }, - ].map((item, index) => ( - <motion.div - key={index} - custom={index} - variants={statCard} - whileHover="hover" - className="bg-white rounded-xl shadow-md overflow-hidden border border-gray-100" - > - <div className="p-6"> - <div className="flex items-center gap-4 mb-5"> - <div className="bg-[#D4B062] p-3 rounded-full border-2 border-[#D4B062] text-white"> - {item.icon} - </div> - <h3 className="font-bold text-xl text-magazine-navy"> - {item.title} - </h3> - </div> - <p className="text-gray-600 mb-6 leading-relaxed"> - {item.description} - </p> - {item.action ? ( - <motion.button - onClick={item.action} - className="inline-flex items-center bg-[#D4B062] hover:bg-magazine-navy text-white px-4 py-2 rounded-lg transition-colors font-medium" - variants={buttonAnimation} - whileHover="whileHover" - whileTap="whileTap" - > - {item.actionText} - </motion.button> - ) : ( - <Link to={item.link || '/'}> - <motion.button - className="inline-flex items-center bg-[#D4B062] hover:bg-magazine-navy text-white px-4 py-2 rounded-lg transition-colors font-medium" - variants={buttonAnimation} - whileHover="whileHover" - whileTap="whileTap" - > - {item.actionText} - </motion.button> - </Link> - )} - </div> - </motion.div> - ))} - </div> - </div> - </div> - </motion.section> - </main> - <Footer /> - </div> - ); -}; - -export default NotFoundPage; diff --git a/src/pages/Products.tsx b/src/pages/Products.tsx deleted file mode 100644 index a05bf568..00000000 --- a/src/pages/Products.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { motion } from 'framer-motion'; -import { - fadeInUpAnimation, - zoomInAnimation, - staggerContainer, -} from '@/styles/Animations.ts'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import Product from '@/components/Product'; - -const ProductsPage = () => { - return ( - <div> - <Header /> - <main className="container mx-auto px-4 sm:px-6 md:px-8 py-6"> - {/* Parent container to control animation sequence */} - <motion.div - variants={staggerContainer} - initial="initial" - animate="animate" - > - <motion.h2 - className="text-6xl sm:text-7xl md:text-8xl lg:text-9xl font-extralight text-center mb-6 font-[Oswald] tracking-wide py-8" - variants={fadeInUpAnimation} - > - <span className="text-black">OUR</span>{' '} - <span className="text-red-500">MERCHANDISE</span> - </motion.h2> - <motion.div variants={zoomInAnimation}> - <Product /> - </motion.div> - </motion.div> - </main> - <Footer /> - </div> - ); -}; - -export default ProductsPage; diff --git a/src/pages/TryNow/BootableSoas.tsx b/src/pages/TryNow/BootableSoas.tsx deleted file mode 100644 index e3453d61..00000000 --- a/src/pages/TryNow/BootableSoas.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import FeatureSection from '@/components/TryNow/FeatureSection'; -import { motion } from 'framer-motion'; -import { zoomFadeInAnimation } from '@/styles/Animations'; -import { - bootableSoasData, - mockupImage, -} from '@/constants/TryNowData/bootableSoasData'; -import StepsToUse from '@/components/TryNow/StepsToUse'; - -const BootableSoasPage = () => { - return ( - <div> - <Header /> - <main className="container mx-auto px-4 sm:px-6 md:px-8 py-6"> - <FeatureSection data={bootableSoasData} /> - - <motion.img - src={mockupImage.path} - alt="BootableSoasMockup" - variants={zoomFadeInAnimation} - initial="initial" - animate="animate" - className="w-[80%] mx-auto" - /> - - <StepsToUse /> - <motion.div> - <p className="justify-self-center mt-4 text-2xl text-gray-700"> - Cut to the chase and get your pre-installed Sugar on a Stick{' '} - <a - className="text-blue-700 hover:underline font-semibold" - href={'/Products'} - > - now! - </a> - </p> - </motion.div> - </main> - <Footer /> - </div> - ); -}; - -export default BootableSoasPage; diff --git a/src/pages/TryNow/FlatHub.tsx b/src/pages/TryNow/FlatHub.tsx deleted file mode 100644 index a819c320..00000000 --- a/src/pages/TryNow/FlatHub.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import { motion } from 'framer-motion'; -import { fadeInUpAnimation } from '@/styles/Animations.ts'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import FeatureSection from '@/components/TryNow/FeatureSection'; -import Paragraph from '@/components/TryNow/Paragraph'; -import LogoCards from '@/components/TryNow/LogoCards'; -import NumberedCard from '@/components/TryNow/NumberedCard'; -import { - flathubData, - flathubSections, - flathubLogoCards, - numberedCards1, - numberedCards2, -} from '@/constants/TryNowData/flathubData'; - -const FlatHubPage = () => { - return ( - <div className="relative"> - {/* Floating SVGs */} - <motion.div - className="absolute top-[10vh] md:top-[15vh] left-[5vw] md:left-[35vw] z-[-1] pointer-events-none" - variants={fadeInUpAnimation} - initial="initial" - animate="animate" - > - <img - src="assets/FloatingSVGs/flathub-1.svg" - alt="Flathub SVG 1" - className="w-[clamp(100px,10vw,150px)]" - /> - </motion.div> - - <motion.div - className="absolute top-[10vh] sm:top-[65vh] right-[5vw] xs:right-[50vw] z-[-1] pointer-events-none" - variants={fadeInUpAnimation} - initial="initial" - animate="animate" - > - <img - src="assets/FloatingSVGs/flathub-2.svg" - alt="Flathub SVG 2" - className="w-[clamp(40px,9vw,16px)]" - /> - </motion.div> - - <Header /> - - <main className="container mx-auto px-4 sm:px-6 md:px-8 py-6"> - <FeatureSection data={flathubData} /> - - {flathubSections.map((section, index) => ( - <Paragraph - key={index} - title={section.title} - content={section.content} - button={section.button} - buttonLink={section.buttonLink} - /> - ))} - - <h2 className="text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mt-10"> - What can you do with <span className="text-[#68A6F7]">Flatpak</span>? - </h2> - - <div className="flex justify-center"> - <LogoCards data={flathubLogoCards} /> - </div> - - <div className="flex flex-col md:flex-row justify-center space-y-4 md:space-y-0 md:space-x-4 my-8"> - <div className="w-full md:w-1/2"> - <h2 className="text-2xl font-semibold mb-4 text-center font-Caveat"> - Getting Started - </h2> - <div className="grid grid-cols-1 gap-4 mt-6 p-4"> - {numberedCards1.map((card, index) => ( - <NumberedCard - key={index} - number={card.number} - title={card.title} - description={card.description} - borderColor={card.borderColor} - link={card.link} - /> - ))} - </div> - </div> - <div className="w-full md:w-1/2"> - <h2 className="text-2xl font-semibold mb-4 text-center font-[Caveat]"> - Next Steps - </h2> - <div className="grid grid-cols-1 gap-4 mt-6 p-4"> - {numberedCards2.map((card, index) => ( - <NumberedCard - key={index} - number={card.number} - title={card.title} - description={card.description} - borderColor={card.borderColor} - /> - ))} - </div> - </div> - </div> - - {/* New Developer Section */} - <div className="my-12 p-6 bg-gray-50 rounded-lg shadow-sm"> - <h2 className="text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mb-6"> - For <span className="text-blue-600">Developers</span> - </h2> - <div className="max-w-3xl mx-auto"> - <p className="text-lg mb-4"> - Looking to package and distribute Sugar activities using Flatpak? - Our comprehensive guide walks you through the entire process of - creating, building, and publishing Flatpak applications. - </p> - <div className="flex justify-center mt-6"> - <a - href="https://github.com/tchx84/sugarapp/blob/master/flatpak-guide.md" - target="_blank" - rel="noopener noreferrer" - className="flex items-center justify-center px-6 py-3 rounded-xl font-semibold - text-white bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 - hover:to-blue-800 transition-all duration-300" - > - <span className="mr-2">View Developer Guide</span> - </a> - </div> - </div> - </div> - </main> - - <Footer /> - </div> - ); -}; - -export default FlatHubPage; diff --git a/src/pages/TryNow/MusicBlocks.tsx b/src/pages/TryNow/MusicBlocks.tsx deleted file mode 100644 index e2d64b91..00000000 --- a/src/pages/TryNow/MusicBlocks.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import { motion } from 'framer-motion'; -import { fadeInUpAnimation, zoomFadeInAnimation } from '@/styles/Animations.ts'; -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import FeatureSection from '@/components/TryNow/FeatureSection'; -import Paragraph from '@/components/TryNow/Paragraph'; -import LogoCards from '@/components/TryNow/LogoCards'; -import TeamSection from '@/components/TryNow/TeamSection'; -import NumberedCard from '@/components/TryNow/NumberedCard'; -import { - musicBlocksData, - mockupImage, - musicblockstext, - musicBlocksSections, - foundabug, - musicBlocksLogoCards, - teamMembers, - numberedCards1, - numberedCards2, -} from '@/constants/TryNowData/musicBlocksData'; - -const MusicBlocksPage = () => { - return ( - <div className="relative"> - {/* Floating SVGs */} - <motion.div - className="absolute top-[10vh] left-[5vw] sm:left-[30vw] z-[-1] pointer-events-none" - variants={fadeInUpAnimation} - initial="initial" - animate="animate" - > - <img - src="assets/FloatingSVGs/music-block-1.svg" - alt="Music Block 1" - className="w-[clamp(100px,10vw,180px)]" - /> - </motion.div> - - <motion.div - className="absolute top-[65vh] right-[5vw] sm:right-[50vw] z-[-1] pointer-events-none" - variants={fadeInUpAnimation} - initial="initial" - animate="animate" - > - <img - src="assets/FloatingSVGs/music-block-2.svg" - alt="Music Block 2" - className="w-[clamp(80px,9vw,160px)]" - /> - </motion.div> - - <motion.div - className="absolute top-[10vh] right-[10vw] sm:right-[15vw] z-[-1] pointer-events-none" - variants={fadeInUpAnimation} - initial="initial" - animate="animate" - > - <img - src="assets/FloatingSVGs/music-block-3.svg" - alt="Music Block 3" - className="w-[clamp(90px,10vw,170px)]" - /> - </motion.div> - - {/* Main Content */} - <Header /> - <main className="container mx-auto px-4 sm:px-6 md:px-8 py-6"> - <FeatureSection data={musicBlocksData} /> - - <p className="flex justify-center"> - <span className="text-[#436EA6]">Learn music</span> - <span>,</span> - <span className="text-[#FEC613]">math</span> - <span>, and</span> - <span className="text-[#AB486A]">programming</span> - together. - </p> - - <div className="w-[80%] mx-auto flex justify-center"> - <img - src={musicblockstext.path} - alt="Music Blocks" - className="w-[60%] max-w-xs" - /> - </div> - - <div className="w-[80%] mx-auto flex justify-center"> - <motion.img - src={mockupImage.path} - alt="MusicBlocksMockup" - variants={zoomFadeInAnimation} - initial="initial" - animate="animate" - className="w-[80%] mx-auto" - /> - </div> - - <p className="w-[80%] mx-auto flex justify-center"> - Music Blocks is an American-made educational software that teaches - music, math, and programming all at once. By combining blocks that - indicate instruments and rhythms, and by changing the pitch values, - children can create music from scratch, even if they are not familiar - with music, are not good at math, or are new to programming. It is a - groundbreaking software that allows children to learn these things. - </p> - - {/* Render Paragraph components dynamically */} - {musicBlocksSections.map((section, index) => ( - <Paragraph - key={index} - title={section.title} - content={section.content} - button={section.button} - links={section.links} - /> - ))} - - <h2 className="text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mt-10"> - What can you do with{' '} - <span className="text-[#68A6F7]">Music Blocks</span>?? - </h2> - - <LogoCards data={musicBlocksLogoCards} /> - - <h2 className="text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mt-10"> - How <span className="text-[#68A6F7]">Music Blocks</span> help your - child's education?? - </h2> - - {/* Card Grid */} - <div className="grid md:grid-cols-3 gap-8 mt-12"> - {numberedCards1.map((card, index) => ( - <NumberedCard - key={index} - number={card.number} - title={card.title} - description={card.description} - image={card.image} - borderColor={card.borderColor} - /> - ))} - </div> - - {/* Card Grid */} - <div className="grid md:grid-cols-3 gap-8 mt-12"> - {numberedCards2.map((card, index) => ( - <NumberedCard - key={index} - number={card.number} - title={card.title} - description={card.description} - image={card.image} - borderColor={card.borderColor} - /> - ))} - </div> - - <div> - <TeamSection members={teamMembers} /> - </div> - - {/* Render Paragraph components dynamically */} - {foundabug.map((section, index) => ( - <Paragraph - key={index} - title={section.title} - content={section.content} - button={section.button} - links={section.links} - /> - ))} - </main> - <Footer /> - </div> - ); -}; - -export default MusicBlocksPage; diff --git a/src/pages/TryNow/Raspberry.tsx b/src/pages/TryNow/Raspberry.tsx deleted file mode 100644 index 8ceb748c..00000000 --- a/src/pages/TryNow/Raspberry.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import FeatureSection from '@/components/TryNow/FeatureSection'; -import Paragraph from '@/components/TryNow/Paragraph'; -import LogoCards from '@/components/TryNow/LogoCards'; -import { - raspberrydata, - raspberrySections, - raspberryLogoCards, -} from '@/constants/TryNowData/raspberryPiData'; - -const RaspberryPiPage = () => { - return ( - <div> - <Header /> - <main className="container mx-auto px-4 sm:px-6 md:px-8 py-6"> - <FeatureSection data={raspberrydata} /> - - {/* Render Paragraph components dynamically */} - {raspberrySections.map((section, index) => ( - <Paragraph - key={index} - title={section.title} - content={section.content} - button={section.button} - links={section.links} - /> - ))} - <LogoCards data={raspberryLogoCards} /> - </main> - <Footer /> - </div> - ); -}; - -export default RaspberryPiPage; diff --git a/src/pages/TryNow/Sugarizer.tsx b/src/pages/TryNow/Sugarizer.tsx deleted file mode 100644 index d5f7177b..00000000 --- a/src/pages/TryNow/Sugarizer.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import FeatureSection from '@/components/TryNow/FeatureSection'; -import LogoCards from '@/components/TryNow/LogoCards'; -import { motion } from 'framer-motion'; -import { fadeInUpAnimation, zoomFadeInAnimation } from '@/styles/Animations.ts'; -import { - logoCardsData, - sugarizerData, - mockupImage, -} from '@/constants/TryNowData/sugarizerData'; - -const SugarizerPage = () => { - return ( - <div> - <Header /> - <main className="container mx-auto px-4 sm:px-6 md:px-8 py-6"> - <FeatureSection data={sugarizerData} /> - - {/* Floating SVGs */} - <motion.div - className="absolute top-[28vh] left-[5vw] sm:left-[30vw] z-[-1] pointer-events-none" - variants={fadeInUpAnimation} - initial="initial" - animate="animate" - > - <img - src="assets/FloatingSVGs/sugarizer-1.svg" - alt="Sugarizer 1" - className="w-[clamp(100px,10vw,180px)]" - /> - </motion.div> - - <motion.img - src={mockupImage.path} - alt="SugarizerMockup" - variants={zoomFadeInAnimation} - initial="initial" - animate="animate" - className="w-[80%] mx-auto" - /> - - <h2 className="text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mt-10"> - Try it now! - </h2> - {/* Logo Cards Section */} - <LogoCards data={logoCardsData} /> - </main> - <Footer /> - </div> - ); -}; - -export default SugarizerPage; diff --git a/src/pages/TryNow/Trisquel.tsx b/src/pages/TryNow/Trisquel.tsx deleted file mode 100644 index 6afa6093..00000000 --- a/src/pages/TryNow/Trisquel.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import FeatureSection from '@/components/TryNow/FeatureSection'; -import Paragraph from '@/components/TryNow/Paragraph'; -import LogoCards from '@/components/TryNow/LogoCards'; -import { - trisquelSections, - trisquelData, - trisquelLogoCards, -} from '@/constants/TryNowData/trisquelData'; - -const TrisquelPage = () => { - return ( - <div> - <Header /> - <main className="container mx-auto px-4 sm:px-6 md:px-8 py-6"> - <FeatureSection data={trisquelData} /> - - {/* Render Paragraph components dynamically */} - {trisquelSections.map((section, index) => ( - <Paragraph - key={index} - title={section.title} - content={section.content} - button={section.button} - /> - ))} - - <h2 className="text-3xl sm:text-4xl font-semibold border-b-2 border-gray-300 pb-2 font-[Caveat] text-center mx-auto w-fit mt-10"> - Learn and Try! - </h2> - - <LogoCards data={trisquelLogoCards} /> - </main> - <Footer /> - </div> - ); -}; - -export default TrisquelPage; diff --git a/src/pages/TryNow/TurtleBlocks.tsx b/src/pages/TryNow/TurtleBlocks.tsx deleted file mode 100644 index 1d965bc0..00000000 --- a/src/pages/TryNow/TurtleBlocks.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import FeatureSection from '@/components/TryNow/FeatureSection'; -import Paragraph from '@/components/TryNow/Paragraph'; -import { motion } from 'framer-motion'; -import { fadeInUpAnimation, zoomFadeInAnimation } from '@/styles/Animations.ts'; -import { - turtleBlocksData, - turtleBlocksSections, - mockupImage, -} from '@/constants/TryNowData/turtleBlocksData'; - -const TurtleBlocksPage = () => { - return ( - <div> - <Header /> - <main className="container mx-auto px-4 sm:px-6 md:px-8 py-6"> - {/* Floating SVGs */} - <motion.div - className="absolute top-[10vh] left-[5vw] sm:left-[35vw] z-[-1] pointer-events-none" - variants={fadeInUpAnimation} - initial="initial" - animate="animate" - > - <img - src="assets/FloatingSVGs/turtle-blocks-1.svg" - alt="Turtle Blocks 1" - className="w-[clamp(100px,10vw,180px)]" - /> - </motion.div> - - <motion.div - className="absolute top-[60vh] right-[5vw] sm:right-[50vw] z-[-1] pointer-events-none" - variants={fadeInUpAnimation} - initial="initial" - animate="animate" - > - <img - src="assets/FloatingSVGs/turtle-blocks-2.svg" - alt="Turtle Blocks 2" - className="w-[clamp(80px,9vw,160px)]" - /> - </motion.div> - - <FeatureSection data={turtleBlocksData} /> - - <p className="w-[80%] mx-auto flex justify-center font-bold"> - Note: Turtle Blocks JS closely parallels the Python version of Turtle - Blocks, the version included in the Sugar distribution. Sugar users - probably want to use Turtle Blocks rather than Turtle Blocks JS. - </p> - - <motion.img - src={mockupImage.path} - alt="TurtleMockup" - variants={zoomFadeInAnimation} - initial="initial" - animate="animate" - className="w-[80%] mx-auto" - /> - - {/* Render Paragraph components dynamically */} - {turtleBlocksSections.map((section, index) => ( - <Paragraph - key={index} - title={section.title} - content={section.content} - button={section.button} - links={section.links} - /> - ))} - </main> - <Footer /> - </div> - ); -}; - -export default TurtleBlocksPage; diff --git a/src/pages/TrySugar.tsx b/src/pages/TrySugar.tsx deleted file mode 100644 index 7f6d4709..00000000 --- a/src/pages/TrySugar.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import Try from '@/components/Try'; - -const TrySugar = () => { - return ( - <div className="min-h-screen flex flex-col"> - <Header /> - <main className="flex-grow bg-[#F6DEC9] p-4"> - <div className="max-w-6xl mx-auto space-y-8"> - <Try /> - </div> - </main> - <Footer /> - </div> - ); -}; - -export default TrySugar; diff --git a/src/pages/Volunteer.tsx b/src/pages/Volunteer.tsx deleted file mode 100644 index de902b9b..00000000 --- a/src/pages/Volunteer.tsx +++ /dev/null @@ -1,246 +0,0 @@ -import Header from '@/sections/Header'; -import Footer from '@/sections/Footer'; -import JoinToggle from '@/components/JoinToggle'; -import { roleCards } from '@/constants/VolunteerAndDev/RoleCards'; -import groupimage from '/assets/Volunteer/volunteer-group.png'; -import { motion } from 'framer-motion'; -import { developerLinks } from '@/constants/VolunteerAndDev/Links'; -import { - slideInLeft, - slideInRight, - slideInBottom, - cardFadeIn, -} from '@/styles/Animations'; -import { Link } from 'react-router-dom'; - -const Volunteer = () => { - const matrixLink = - developerLinks.find((link) => link.name.includes('Matrix'))?.url || - 'https://matrix.to/#/#sugar:matrix.org'; - const mailLink = - developerLinks.find((link) => link.name.includes('Mailing'))?.url || - 'https://lists.sugarlabs.org/'; - - const handleGetInvolved = () => { - const gettingInvolvedSection = document.getElementById('volunteer-cards'); - if (gettingInvolvedSection) { - gettingInvolvedSection.scrollIntoView({ behavior: 'smooth' }); - } - }; - - return ( - <div> - <Header /> - <main className="container mx-auto flex flex-col items-center justify-center min-h-screen p-6"> - <JoinToggle /> - - {/* Content Section */} - <div className="mt-12 flex flex-col md:flex-row items-center gap-8 max-w-5xl"> - {/* Left Side Text */} - <motion.div - className="max-w-lg text-center md:text-left" - variants={slideInLeft} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <h2 className="text-4xl font-bold"> - Become a <span className="text-red-500">Volunteer</span> - </h2> - <p className="text-lg text-gray-700 mt-4"> - By bringing together people with diverse skills from around the - globe to work toward our mission in education, volunteers in the - Sugar Labs community have ample opportunities to grow their skills - and learn from one another. - </p> - <button - className="mt-6 bg-red-500 text-white text-lg font-semibold px-6 py-3 rounded-full hover:cursor-pointer" - onClick={handleGetInvolved} - > - Get Involved - </button> - </motion.div> - - {/* Right Side Image */} - <motion.div - className="w-full md:w-1/2 flex justify-center" - variants={slideInRight} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <img - src={groupimage} - alt="Volunteers working together" - className="w-full max-w-md rounded-lg shadow-lg" - /> - </motion.div> - </div> - - {/* Getting Involved Section */} - <motion.div - className="mt-20 max-w-4xl text-center px-4" - variants={slideInBottom} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <h2 className="text-5xl font-bold font-[Caveat]"> - Getting Involved as a Volunteer - </h2> - <hr className="w-32 border-t-2 border-gray-400 mx-auto mt-2" /> - - <p className="text-lg text-gray-700 font-[Inter] mt-6 leading-relaxed"> - Sugar Labs is seeking volunteer assistance in the roles of - education, communication, advocacy, research, and technical. - Sustained, committed help in any of these areas will help us grow as - an organization. If you are passionate or curious to learn more - about any of these roles, and are able to commit the time necessary, - then we encourage you to apply. - </p> - - <p className="text-lg text-gray-700 font-[Inter] mt-4 leading-relaxed"> - Send a notification of your interest to - <a - href="mailto:info@sugarlabs.org" - className="text-blue-500 underline" - > - {' '} - info@sugarlabs.org - </a> - , including some information about yourself, what interests you - about the volunteer role, and what experience/qualities make you a - good candidate. - </p> - </motion.div> - - {/* Volunteer Roles */} - <div className="mt-16 max-w-6xl px-4" id="volunteer-cards"> - <motion.h2 - className="text-5xl font-[Caveat] font-bold text-center" - variants={slideInBottom} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - Volunteer Roles - </motion.h2> - <hr className="w-32 border-t-2 border-gray-400 mx-auto mt-2" /> - - {/* Role Cards */} - <div className="mt-10 grid grid-cols-1 md:grid-cols-3 gap-6"> - {roleCards.map((role, index) => ( - <motion.div - key={index} - className="border p-6 rounded-lg shadow-lg bg-white text-center" - variants={cardFadeIn} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.2 }} - > - <h3 className="text-2xl font-bold">{role.title}</h3> - <hr className="w-16 border-t-2 border-gray-400 mx-auto mt-2" /> - <p className="text-gray-700 mt-4">{role.description}</p> - <ul className="text-gray-600 text-left mt-3 space-y-2"> - {role.points?.map((point, idx) => ( - <li key={idx} className="flex items-start"> - <span className="text-red-500 font-bold mr-2">•</span> - {point} - </li> - ))} - </ul> - {role.extra && ( - <p className="text-gray-700 text-sm mt-3"> - {role.extra}{' '} - {role.link && ( - <a href={role.link} className="text-blue-500 underline"> - {role.link} - </a> - )} - </p> - )} - </motion.div> - ))} - </div> - </div> - - {/* Get Involved Section */} - <motion.div - className="mt-20 max-w-4xl text-center px-4" - variants={slideInBottom} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <h2 className="text-5xl font-bold font-[Caveat]"> - Ways to Get <span className="text-red-500">Involved</span> - </h2> - <hr className="w-32 border-t-2 border-gray-400 mx-auto mt-2" /> - - <p className="text-lg text-gray-700 font-[Inter] mt-6 leading-relaxed"> - There are multiple ways to get involved, whether as a developer, - educator, advocate, or communicator. Each role plays a vital part in - helping us achieve our mission. - </p> - - {/* Embedded YouTube Video */} - <div className="mt-8 w-full flex justify-center"> - <div className="w-full max-w-3xl aspect-video"> - <iframe - className="w-full h-full rounded-lg" - src="https://www.youtube.com/embed/W5ZLFBZkE34" - title="YouTube Video" - frameBorder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" - allowFullScreen - ></iframe> - </div> - </div> - </motion.div> - - {/* Contact Section */} - <motion.div - className="mt-20 max-w-4xl text-center px-4" - variants={slideInBottom} - initial="hidden" - whileInView="visible" - viewport={{ once: true, amount: 0.5 }} - > - <h2 className="text-5xl font-bold font-[Caveat]"> - Interested in Helping Out? - </h2> - <hr className="w-32 border-t-2 border-gray-400 mx-auto mt-2" /> - - <p className="text-lg text-gray-700 font-[Inter] mt-6 leading-relaxed"> - Feel free to reach out to express your interest in volunteering via{' '} - <a - href={mailLink} - className="text-blue-500 hover:underline" - target="_blank" - rel="noopener noreferrer" - > - email - </a>{' '} - or{' '} - <a - href={matrixLink} - className="text-blue-500 hover:underline" - target="_blank" - rel="noopener noreferrer" - > - Matrix - </a> - . Alternatively, you may send{' '} - <Link to="/contact-us" className="text-blue-600 hover:underline"> - direct message - </Link>{' '} - to one of our social media channels. - </p> - </motion.div> - </main> - <Footer /> - </div> - ); -}; - -export default Volunteer; diff --git a/src/redirects.tsx b/src/redirects.tsx deleted file mode 100644 index 0600caa2..00000000 --- a/src/redirects.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Navigate } from 'react-router-dom'; -import type { RouteObject } from 'react-router-dom'; - -export const redirectMap: Record<string, string> = { - '/go/Sugar_Labs/Donate': '/donate', - '/booting-soas': '/bootablesoas', - - // Example redirects: - // '/old-path-1': '/new-path-1', - // '/old-section/*': '/new-section', // wildcard redirect -}; - -export const redirectRoutes: RouteObject[] = Object.entries(redirectMap).map( - ([from, to]) => ({ - path: from, - element: <Navigate to={to} replace />, - }), -); diff --git a/src/routes.tsx b/src/routes.tsx deleted file mode 100644 index edef466c..00000000 --- a/src/routes.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { createBrowserRouter } from 'react-router-dom'; -import { redirectRoutes } from '@/redirects'; -import MainPage from '@/pages/MainPage'; -import AboutUs from '@/pages/About/AboutUs'; -import Leadership from '@/pages/About/Leadership'; -import ContactUs from '@/pages/About/ContactUs'; -import FAQs from '@/pages/About/FAQs'; -import TrySugar from '@/pages/TrySugar'; -import JoinDevelopment from '@/pages/JoinDevelopment'; -import Volunteer from '@/pages/Volunteer'; -import Donate from '@/pages/Donate'; -import Products from '@/pages/Products'; -import NewsPage from '@/pages/News/NewsPage'; -import NewsDetailPage from '@/pages/News/NewsDetailPage'; -import AuthorPage from '@/pages/News/AuthorPage'; -import TagPage from '@/pages/News/TagPage'; -import MorePage from '@/pages/More'; -import TurtleBlocksPage from '@/pages/TryNow/TurtleBlocks'; -import SugarizerPage from '@/pages/TryNow/Sugarizer'; -import BootableSoasPage from '@/pages/TryNow/BootableSoas'; -import TrisquelPage from '@/pages/TryNow/Trisquel'; -import RaspberryPiPage from '@/pages/TryNow/Raspberry'; -import MusicBlocksPage from '@/pages/TryNow/MusicBlocks'; -import FlatHubPage from '@/pages/TryNow/FlatHub'; -import Matrix from '@/pages/Matrix'; -import NotFoundPage from '@/pages/NotFoundPage'; -import Contributors from '@/pages/Contributors'; - -const router = createBrowserRouter([ - ...redirectRoutes, - { path: '/', element: <MainPage /> }, - { path: '/about-us', element: <AboutUs /> }, - { path: '/leadership', element: <Leadership /> }, - { path: '/contact-us', element: <ContactUs /> }, - { path: '/faqs', element: <FAQs /> }, - { path: '/news', element: <NewsPage /> }, - { path: '/news/:category', element: <NewsPage /> }, - { path: '/news/:category/:slug', element: <NewsDetailPage /> }, - { path: '/authors/:slug', element: <AuthorPage /> }, - { path: '/tags/:tag', element: <TagPage /> }, - { path: '/more', element: <MorePage /> }, - { path: '/more/:slug', element: <MorePage /> }, - { path: '/try-sugar', element: <TrySugar /> }, - { path: '/join-development', element: <JoinDevelopment /> }, - { path: '/volunteer', element: <Volunteer /> }, - { path: '/donate', element: <Donate /> }, - { path: '/products', element: <Products /> }, - { path: '/turtleblocks', element: <TurtleBlocksPage /> }, - { path: '/sugarizer', element: <SugarizerPage /> }, - { path: '/bootablesoas', element: <BootableSoasPage /> }, - { path: '/trisquel', element: <TrisquelPage /> }, - { path: '/raspberry', element: <RaspberryPiPage /> }, - { path: '/musicblocks', element: <MusicBlocksPage /> }, - { path: '/flathub', element: <FlatHubPage /> }, - { path: '/contact-us/:matrix', element: <Matrix /> }, - { path: '/profiles', element: <Contributors /> }, - { path: '*', element: <NotFoundPage /> }, -]); - -export default router; diff --git a/src/sections/Banner.tsx b/src/sections/Banner.tsx deleted file mode 100644 index 8919de26..00000000 --- a/src/sections/Banner.tsx +++ /dev/null @@ -1,253 +0,0 @@ -import React, { useState, useEffect, useCallback } from 'react'; -import { motion, AnimatePresence } from 'framer-motion'; -import { themeConfig } from '@/components/Banner/Theme'; -import { PromoIcon } from '@/components/Banner/Icon'; -import { Link } from 'react-router-dom'; -import { BannerConfig } from '@/constants/Banner'; - -interface PromoBannerProps { - bannerConfigs: Record<string, BannerConfig>; - autoRotateInterval?: number; -} - -const PromoBanner: React.FC<PromoBannerProps> = ({ - bannerConfigs, - autoRotateInterval = 4000, -}) => { - const [isVisible, setIsVisible] = useState(true); - const bannerConfigsArray = Object.values(bannerConfigs); - const [currentBannerIndex, setCurrentBannerIndex] = useState(0); - const [isPaused, setIsPaused] = useState(false); - const [direction, setDirection] = useState(0); - - const currentBanner = bannerConfigsArray[currentBannerIndex]; - const styles = themeConfig[currentBanner.theme || 'primary']; - - const totalBanners = bannerConfigsArray.length; - const shouldRotate = totalBanners > 1; - - const prevBanner = useCallback(() => { - if (!shouldRotate) return; - setDirection(-1); - setCurrentBannerIndex((prevIndex) => - prevIndex === 0 ? totalBanners - 1 : prevIndex - 1, - ); - }, [shouldRotate, totalBanners]); - - // Navigate to next banner - const nextBanner = useCallback(() => { - if (!shouldRotate) return; - setDirection(1); - setCurrentBannerIndex((prevIndex) => (prevIndex + 1) % totalBanners); - }, [shouldRotate, totalBanners]); - - // Auto-rotate banners - useEffect(() => { - if (!shouldRotate || isPaused) return; - - const intervalId = setInterval(() => { - nextBanner(); - }, autoRotateInterval); - - return () => clearInterval(intervalId); - }, [nextBanner, autoRotateInterval, isPaused, shouldRotate]); - - const closeBanner = () => { - setIsVisible(false); - }; - - const buttonClasses = `inline-flex items-center justify-center px-3.5 py-1.5 sm:px-5 sm:py-2 border border-transparent rounded-full shadow-sm sm:text-l font-medium text-white bg-gradient-to-r ${styles.button} transition-all duration-200 whitespace-nowrap`; - const buttonAnimationProps = { - whileHover: { scale: 1.03 }, - whileTap: { scale: 0.97 }, - }; - - const bannerVariants = { - enter: (direction: number) => ({ - x: direction > 0 ? '100%' : '-100%', - opacity: 0, - }), - center: { - x: 0, - opacity: 1, - }, - exit: (direction: number) => ({ - x: direction < 0 ? '100%' : '-100%', - opacity: 0, - }), - }; - - const renderButton = () => { - if (!currentBanner.buttonText || !currentBanner.buttonLink) return null; - - if (currentBanner.isExternalLink) { - return ( - <motion.a - {...buttonAnimationProps} - href={currentBanner.buttonLink} - target="_blank" - rel="noopener noreferrer" - className={buttonClasses} - > - {currentBanner.buttonText} - </motion.a> - ); - } else { - return ( - <motion.div {...buttonAnimationProps}> - <Link to={currentBanner.buttonLink} className={buttonClasses}> - {currentBanner.buttonText} - </Link> - </motion.div> - ); - } - }; - - return ( - <AnimatePresence> - {isVisible && ( - <div - className={`w-full bg-gradient-to-r ${styles.background} border-b ${styles.border} shadow-sm overflow-hidden`} - > - <div className="max-w-7xl mx-auto px-3 py-6 sm:px-6 md:px-8 relative"> - <AnimatePresence initial={false} custom={direction} mode="wait"> - <motion.div - key={currentBannerIndex} - custom={direction} - variants={bannerVariants} - initial="enter" - animate="center" - exit="exit" - transition={{ - type: 'tween', - duration: 0.5, - ease: 'easeInOut', - }} - className="w-full" - onMouseEnter={() => setIsPaused(true)} - onMouseLeave={() => setIsPaused(false)} - > - <div className="flex flex-col sm:flex-row items-center justify-between gap-y-3 sm:gap-y-0"> - <div className="flex items-center w-full sm:w-auto"> - {shouldRotate && ( - <motion.button - whileHover={{ - scale: 1.1, - backgroundColor: 'rgba(255, 255, 255, 0.4)', - cursor: 'pointer', - }} - whileTap={{ scale: 0.95 }} - onClick={prevBanner} - className={`hidden sm:flex p-1.5 rounded-full hover:bg-white/30 focus:outline-none focus:ring-2 focus:ring-white/50 transition-all ${styles.text} touch-manipulation mr-2`} - aria-label="Previous banner" - > - <svg - className="h-5 w-5" - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M15 19l-7-7 7-7" - /> - </svg> - </motion.button> - )} - - <div - className={`flex p-2 sm:p-2.5 rounded-full bg-white/40 backdrop-blur-sm ${styles.border} shadow-sm shrink-0`} - > - <span className={styles.icon}> - <PromoIcon theme={currentBanner.theme || 'primary'} /> - </span> - </div> - - <div className="ml-3 sm:ml-3.5 pr-2 flex-1"> - <p - className={`font-medium ${styles.text} text-sm sm:text-base leading-tight`} - > - {currentBanner.title} - </p> - {currentBanner.description && ( - <p - className={`text-xs sm:text-sm ${styles.text} opacity-80 mt-0.5 line-clamp-2 sm:line-clamp-none`} - > - {currentBanner.description} - </p> - )} - </div> - - {shouldRotate && ( - <motion.button - whileHover={{ - scale: 1.1, - backgroundColor: 'rgba(255, 255, 255, 0.4)', - cursor: 'pointer', - }} - whileTap={{ scale: 0.95 }} - onClick={nextBanner} - className={`hidden sm:flex p-1.5 rounded-full hover:bg-white/30 focus:outline-none focus:ring-2 focus:ring-white/50 transition-all ${styles.text} touch-manipulation ml-2`} - aria-label="Next banner" - > - <svg - className="h-5 w-5" - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M9 5l7 7-7 7" - /> - </svg> - </motion.button> - )} - </div> - - <div className="flex items-center space-x-3 mt-2 sm:mt-0 self-end sm:self-auto"> - {renderButton()} - - <motion.button - whileHover={{ - scale: 1.1, - backgroundColor: 'rgba(255, 255, 255, 0.4)', - }} - whileTap={{ scale: 0.95 }} - onClick={closeBanner} - className={`flex p-1.5 rounded-full hover:bg-white/30 focus:outline-none focus:ring-2 focus:ring-white/50 transition-all ${styles.text} touch-manipulation`} - aria-label="Dismiss" - > - <svg - className="h-4 w-4 sm:h-5 sm:w-5" - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M6 18L18 6M6 6l12 12" - /> - </svg> - </motion.button> - </div> - </div> - </motion.div> - </AnimatePresence> - </div> - </div> - )} - </AnimatePresence> - ); -}; - -export default PromoBanner; diff --git a/src/sections/Footer.tsx b/src/sections/Footer.tsx deleted file mode 100644 index 98aa6df6..00000000 --- a/src/sections/Footer.tsx +++ /dev/null @@ -1,184 +0,0 @@ -import { Link } from 'react-router-dom'; -import GithubIcon from '/assets/social/github.svg'; -import { - socialLinks, - resourceLinks, - developmentLinks, - quickLinks, -} from '@/constants/Footer'; - -const Footer = () => { - return ( - <> - <footer className="bg-gradient-to-b from-gray-900 to-gray-950 text-gray-300 py-10 sm:py-16 px-4 sm:px-6 relative"> - {/* Decorative top border */} - <div className="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500"></div> - - <div className="max-w-7xl mx-auto"> - {/* Main Footer Content */} - <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-12 gap-8 sm:gap-10 mb-8 sm:mb-12"> - {/* Resources Section */} - <div className="lg:col-span-3"> - <h2 className="text-lg sm:text-xl font-bold mb-4 sm:mb-6 text-white relative inline-block"> - Resources - <span className="absolute -bottom-2 left-0 w-8 sm:w-12 h-1 bg-blue-500"></span> - </h2> - <ul className="space-y-2 sm:space-y-3"> - {resourceLinks.map((link) => ( - <li key={link.to}> - <Link - to={`${link.to}`} - className="hover:text-white transition-all duration-300 flex items-center group" - > - <span className="w-0 group-hover:w-2 h-2 bg-blue-500 rounded-full mr-0 group-hover:mr-2 transition-all duration-300"></span> - {link.text} - </Link> - </li> - ))} - </ul> - </div> - - {/* Development Section */} - <div className="lg:col-span-3"> - <h2 className="text-lg sm:text-xl font-bold mb-4 sm:mb-6 text-white relative inline-block"> - Development - <span className="absolute -bottom-2 left-0 w-8 sm:w-12 h-1 bg-purple-500"></span> - </h2> - <ul className="space-y-2 sm:space-y-3"> - {developmentLinks.map((link) => ( - <li key={link.to || link.href}> - {link.href ? ( - <a - href={link.href} - target="_blank" - rel="noopener noreferrer" - className="hover:text-white transition-all duration-300 flex items-center group" - > - <span className="w-0 group-hover:w-2 h-2 bg-purple-500 rounded-full mr-0 group-hover:mr-2 transition-all duration-300"></span> - {link.text} - </a> - ) : ( - <Link - to={`${link.to}`} - className="hover:text-white transition-all duration-300 flex items-center group" - > - <span className="w-0 group-hover:w-2 h-2 bg-purple-500 rounded-full mr-0 group-hover:mr-2 transition-all duration-300"></span> - {link.text} - </Link> - )} - </li> - ))} - </ul> - </div> - - {/* Social Links & Contribute Section */} - <div className="sm:col-span-2 lg:col-span-6"> - <h2 className="text-lg sm:text-xl font-bold mb-4 sm:mb-6 text-white relative inline-block"> - Connect With Us - <span className="absolute -bottom-2 left-0 w-8 sm:w-12 h-1 bg-pink-500"></span> - </h2> - - {/* Social Links */} - <div className="flex flex-wrap items-center gap-3 sm:gap-4 md:gap-6 mb-6 sm:mb-8"> - {socialLinks.map((social) => ( - <a - key={social.href} - href={social.href} - target="_blank" - rel="noopener noreferrer" - aria-label={`Visit our ${social.name} page`} - className="group relative flex items-center justify-center w-10 h-10 sm:w-12 sm:h-12 - bg-gray-800/30 hover:bg-gray-700 rounded-xl - transition-all duration-300 ease-in-out - hover:scale-110 - before:absolute before:inset-0 before:rounded-xl - before:bg-gradient-to-r before:from-blue-500/20 before:to-purple-500/20 - before:opacity-0 before:transition-opacity before:duration-300 - hover:before:opacity-100 hover:shadow-lg hover:shadow-blue-500/10" - > - <img - src={social.icon} - alt={social.name} - width={18} - height={18} - className="relative z-10 transition-transform duration-300 - filter brightness-0 invert opacity-90 - group-hover:opacity-100 group-hover:scale-110 - sm:w-5 sm:h-5" - /> - <span - className="absolute -bottom-6 left-1/2 -translate-x-1/2 - whitespace-nowrap text-xs sm:text-sm opacity-0 group-hover:opacity-100 - transition-opacity duration-300 pointer-events-none" - > - {social.name} - </span> - </a> - ))} - </div> - - {/* Contribute Link */} - <a - href="https://github.com/sugarlabs/www-v2" - target="_blank" - rel="noopener noreferrer" - className="inline-flex items-center gap-2 sm:gap-3 px-4 sm:px-6 py-2.5 sm:py-3 bg-gray-800/50 hover:bg-gray-700 - rounded-lg transition-all duration-300 transform hover:-translate-y-1 - hover:shadow-lg hover:shadow-gray-800/30 mb-6 sm:mb-8 text-sm sm:text-base" - > - <img - src={GithubIcon} - alt="GitHub" - width={18} - className="filter brightness-0 invert" - /> - <span className="text-white">Contribute to this website</span> - </a> - - {/* Organization Info */} - <div className="p-4 sm:p-6 bg-gray-800/30 rounded-lg backdrop-blur-sm"> - <p className="text-xs sm:text-sm leading-relaxed"> - Sugar Labs is a registered USA 501(c)(3) tax-exempt, - not-for-profit organization, supported by our generous - contributors and sponsors. - </p> - </div> - </div> - </div> - - {/* Bottom Navigation */} - <div className="grid grid-cols-1 xs:grid-cols-2 sm:grid-cols-3 md:grid-cols-5 gap-3 sm:gap-4 py-6 sm:py-8 border-t border-gray-800"> - {quickLinks.map((link) => ( - <Link - key={link.to} - to={`${link.to}`} - className="hover:text-white transition-all duration-300 text-xs sm:text-sm" - > - {link.text} - </Link> - ))} - </div> - - {/* Copyright */} - <div className="text-xs sm:text-sm text-gray-500 pt-4 sm:pt-6 border-t border-gray-800 flex flex-col sm:flex-row justify-between items-center gap-3 sm:gap-4"> - <p>Copyright © {new Date().getFullYear()} Sugar Labs (R)</p> - <p className="text-center sm:text-right"> - Available under the{' '} - <a - href="https://creativecommons.org/licenses/by-sa/4.0/" - target="_blank" - rel="noopener noreferrer" - className="text-gray-400 hover:text-white transition-colors duration-300 underline decoration-dotted" - > - Creative Commons Attribution-ShareAlike 4.0 International - License (CC BY-SA) - </a> - </p> - </div> - </div> - </footer> - </> - ); -}; - -export default Footer; diff --git a/src/sections/Header.tsx b/src/sections/Header.tsx deleted file mode 100644 index df5bc290..00000000 --- a/src/sections/Header.tsx +++ /dev/null @@ -1,294 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { Link } from 'react-router-dom'; -import { AnimatePresence, motion } from 'framer-motion'; -import logo from '/assets/Icons/logo.svg'; -import NavDropdown from '@/sections/NavDropdown'; -import { navigationData } from '@/constants/Header'; - -const Header: React.FC = () => { - const [isScrolled, setIsScrolled] = useState(false); - const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); - const [activeDropdown, setActiveDropdown] = useState<string | null>(null); - - // Handle scroll effect - useEffect(() => { - const handleScroll = () => setIsScrolled(window.scrollY > 20); - window.addEventListener('scroll', handleScroll); - return () => window.removeEventListener('scroll', handleScroll); - }, []); - - // Handle body scroll lock when mobile menu is open - useEffect(() => { - if (isMobileMenuOpen) { - document.body.style.overflow = 'hidden'; - } else { - document.body.style.overflow = ''; - } - return () => { - document.body.style.overflow = ''; - }; - }, [isMobileMenuOpen]); - - // Close dropdown and menu on escape key - useEffect(() => { - const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === 'Escape') { - setActiveDropdown(null); - setIsMobileMenuOpen(false); - } - }; - window.addEventListener('keydown', handleKeyDown); - return () => window.removeEventListener('keydown', handleKeyDown); - }, []); - - // Close everything when navigating - const handleNavigation = () => { - setIsMobileMenuOpen(false); - setActiveDropdown(null); - }; - - return ( - <> - <header - className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${ - isScrolled ? 'backdrop-blur-md bg-white/90 shadow-lg' : 'bg-white' - }`} - > - <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> - <div className="flex justify-between items-center h-16 md:h-20"> - {/* Logo */} - <Link - to="/" - className="flex-shrink-0 flex items-center" - onClick={handleNavigation} - > - <img - src={logo} - alt="Sugar Labs" - className="h-8 md:h-12 w-auto transition-transform hover:scale-105" - /> - </Link> - - {/* Mobile menu toggle button */} - <button - className="md:hidden relative w-10 h-10 focus:outline-none z-50" - onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)} - aria-label="Toggle menu" - aria-expanded={isMobileMenuOpen} - > - <div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"> - <span - className={`block w-6 h-0.5 bg-gray-600 transition-all duration-300 ${ - isMobileMenuOpen - ? 'rotate-45 translate-y-1.5' - : 'translate-y-[-4px]' - }`} - /> - <span - className={`block w-6 h-0.5 bg-gray-600 transition-all duration-300 mt-1 ${ - isMobileMenuOpen ? 'opacity-0' : '' - }`} - /> - <span - className={`block w-6 h-0.5 bg-gray-600 transition-all duration-300 mt-1 ${ - isMobileMenuOpen - ? '-rotate-45 -translate-y-1.5' - : 'translate-y-[4px]' - }`} - /> - </div> - </button> - - {/* Desktop Navigation */} - <nav className="hidden md:flex md:items-center md:space-x-4 lg:space-x-8"> - {/* Dropdown menus */} - {Object.entries(navigationData.dropdowns).map( - ([key, dropdown]) => ( - <NavDropdown - key={key} - id={key} - label={dropdown.label} - items={dropdown.items} - isActive={activeDropdown === key} - setActive={setActiveDropdown} - onNavigate={handleNavigation} - /> - ), - )} - - {/* Regular links */} - {navigationData.links.map((link) => ( - <Link - key={link.label} - to={link.path} - className="px-2 lg:px-3 py-2 text-gray-700 hover:text-blue-600 font-medium rounded-md - transition-all duration-200 hover:bg-gray-50 text-sm lg:text-base" - onClick={handleNavigation} - > - {link.label} - </Link> - ))} - - {/* CTA Button */} - <Link - to="/try-sugar" - className="inline-flex items-center px-4 lg:px-6 py-2 lg:py-2.5 rounded-full font-semibold text-white - bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 hover:to-blue-800 - transition-all duration-300 transform hover:scale-105 hover:shadow-lg - focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 text-sm lg:text-base" - onClick={handleNavigation} - > - TRY NOW - </Link> - </nav> - </div> - </div> - </header> - - {/* Mobile Navigation Overlay */} - <AnimatePresence> - {isMobileMenuOpen && ( - <motion.div - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - exit={{ opacity: 0 }} - transition={{ duration: 0.2 }} - className="fixed inset-0 bg-black/30 md:hidden z-40" - onClick={() => setIsMobileMenuOpen(false)} - /> - )} - </AnimatePresence> - - {/* Mobile Navigation Drawer */} - <MobileNavDrawer - isOpen={isMobileMenuOpen} - activeDropdown={activeDropdown} - setActiveDropdown={setActiveDropdown} - onClose={handleNavigation} - /> - - {/* Space holder to prevent content from being hidden under fixed header */} - <div className="h-16 md:h-20" /> - </> - ); -}; - -// Mobile Navigation Drawer component to keep the main component cleaner -const MobileNavDrawer: React.FC<{ - isOpen: boolean; - activeDropdown: string | null; - setActiveDropdown: (id: string | null) => void; - onClose: () => void; -}> = ({ isOpen, activeDropdown, setActiveDropdown, onClose }) => { - return ( - <AnimatePresence> - {isOpen && ( - <motion.div - initial={{ opacity: 0, x: '100%' }} - animate={{ opacity: 1, x: 0 }} - exit={{ opacity: 0, x: '100%' }} - transition={{ type: 'tween', duration: 0.3 }} - className="fixed md:hidden top-0 right-0 bottom-0 w-[80%] max-w-sm bg-white shadow-xl z-40 - flex flex-col h-full" - > - <div className="flex flex-col h-full"> - {/* Space to avoid overlay with main header */} - <div className="h-16" /> - - {/* Scrollable content area */} - <div className="flex-1 overflow-y-auto py-2"> - <div className="space-y-4"> - {/* Dropdown menus */} - {Object.entries(navigationData.dropdowns).map( - ([key, dropdown]) => ( - <div key={key} className="space-y-1 px-2"> - <button - onClick={() => - setActiveDropdown(activeDropdown === key ? null : key) - } - className="flex items-center justify-between w-full text-left px-2 py-2 - text-gray-700 font-medium rounded-lg hover:bg-gray-50" - aria-expanded={activeDropdown === key} - > - <span>{dropdown.label}</span> - <svg - className={`w-5 h-5 transition-transform duration-200 ${ - activeDropdown === key ? 'rotate-180' : '' - }`} - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M19 9l-7 7-7-7" - /> - </svg> - </button> - - <AnimatePresence> - {activeDropdown === key && ( - <motion.div - initial={{ height: 0, opacity: 0 }} - animate={{ height: 'auto', opacity: 1 }} - exit={{ height: 0, opacity: 0 }} - transition={{ duration: 0.2 }} - className="overflow-hidden" - > - <div className="pl-4 space-y-1 pb-2"> - {dropdown.items.map((item) => ( - <Link - key={item.path} - to={item.path} - onClick={onClose} - className="flex items-center px-4 py-2 text-sm text-gray-600 - rounded-lg hover:bg-gray-50 hover:text-blue-600" - > - {item.label} - </Link> - ))} - </div> - </motion.div> - )} - </AnimatePresence> - </div> - ), - )} - - {/* Regular links */} - {navigationData.links.map((link) => ( - <Link - key={link.label} - to={link.path} - onClick={onClose} - className="block px-4 py-2 text-gray-700 font-medium rounded-lg - hover:bg-gray-50 hover:text-blue-600" - > - {link.label} - </Link> - ))} - </div> - </div> - - {/* CTA button footer */} - <div className="p-4 border-t border-gray-200 sticky bottom-0 bg-white"> - <Link - to="/try-sugar" - onClick={onClose} - className="flex items-center justify-center px-6 py-3 rounded-xl font-semibold - text-white bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 - hover:to-blue-800 transition-all duration-300 w-full" - > - TRY NOW - </Link> - </div> - </div> - </motion.div> - )} - </AnimatePresence> - ); -}; - -export default Header; diff --git a/src/sections/NavDropdown.tsx b/src/sections/NavDropdown.tsx deleted file mode 100644 index 66c2a7ce..00000000 --- a/src/sections/NavDropdown.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; -import { motion, AnimatePresence } from 'framer-motion'; - -type NavDropdownProps = { - id: string; - label: string; - items: { label: string; path: string }[]; - isActive: boolean; - setActive: (id: string | null) => void; - onNavigate: () => void; -}; - -const NavDropdown: React.FC<NavDropdownProps> = ({ - id, - label, - items, - isActive, - setActive, - onNavigate, -}) => { - return ( - <div - className="relative" - onMouseEnter={() => setActive(id)} - onMouseLeave={() => setActive(null)} - > - <button - className={`px-2 lg:px-3 py-2 text-gray-700 hover:text-blue-600 font-medium rounded-md - transition-all duration-200 hover:bg-gray-50 flex items-center space-x-1 - ${isActive ? 'text-blue-600' : ''}`} - aria-expanded={isActive} - > - <span>{label}</span> - <svg - className={`w-4 h-4 transition-transform duration-200 ${isActive ? 'rotate-180' : ''}`} - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth={2} - d="M19 9l-7 7-7-7" - /> - </svg> - </button> - - <AnimatePresence> - {isActive && ( - <motion.div - initial={{ opacity: 0, y: 10 }} - animate={{ opacity: 1, y: 0 }} - exit={{ opacity: 0, y: 10 }} - transition={{ duration: 0.2 }} - className="absolute left-0 mt-2 w-56 rounded-xl bg-white shadow-xl ring-1 ring-black ring-opacity-5 overflow-hidden" - > - <div className="py-2"> - {items.map((item) => ( - <Link - key={item.path} - to={item.path} - onClick={onNavigate} - className="group flex items-center px-4 py-3 text-sm text-gray-700 hover:bg-gray-50 - transition-all duration-200 hover:text-blue-600" - > - <span - className="w-2 h-2 rounded-full bg-blue-600 opacity-0 group-hover:opacity-100 - transition-all duration-200 mr-2 transform scale-0 group-hover:scale-100" - /> - {item.label} - </Link> - ))} - </div> - </motion.div> - )} - </AnimatePresence> - </div> - ); -}; - -export default NavDropdown; diff --git a/src/styles/Animations.ts b/src/styles/Animations.ts deleted file mode 100644 index 5aa688b5..00000000 --- a/src/styles/Animations.ts +++ /dev/null @@ -1,1158 +0,0 @@ -import { Variants, Easing } from 'framer-motion'; - -// Define proper easing functions -const easeOut: Easing = [0.22, 1, 0.36, 1]; -const easeInOut: Easing = [0.4, 0, 0.2, 1]; -const backOut: Easing = [0.175, 0.885, 0.32, 1.275]; - -export const fadeIn: Variants = { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { duration: 0.6, ease: easeOut }, - }, -}; - -export const slideInLeft: Variants = { - hidden: { x: -100, opacity: 0 }, - visible: { - x: 0, - opacity: 1, - transition: { duration: 0.6, ease: easeOut }, - }, -}; - -export const slideInRight: Variants = { - hidden: { x: 100, opacity: 0 }, - visible: { - x: 0, - opacity: 1, - transition: { duration: 0.6, ease: easeOut }, - }, -}; - -export const slideInBottom: Variants = { - hidden: { y: 100, opacity: 0 }, - visible: { - y: 0, - opacity: 1, - transition: { duration: 0.6, ease: easeOut }, - }, -}; - -export const bounce: Variants = { - hidden: { scale: 0.9, opacity: 0 }, - visible: { - scale: 1, - opacity: 1, - transition: { - type: 'spring' as const, - stiffness: 400, - damping: 10, - }, - }, - hover: { - scale: 1.05, - transition: { - type: 'spring' as const, - stiffness: 400, - damping: 10, - }, - }, - tap: { scale: 0.95 }, -}; - -export const staggerContainer: Variants = { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { - staggerChildren: 0.1, - delayChildren: 0.2, - }, - }, -}; - -export const floatingCircle: Variants = { - hidden: { - opacity: 0, - scale: 0.8, - }, - visible: { - opacity: 0.8, - scale: 1, - transition: { - duration: 1.5, - repeat: Infinity, - repeatType: 'reverse', - }, - }, -}; - -export const simpleFadeIn: Variants = { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { duration: 0.8, ease: easeOut }, - }, -}; - -export const subtleRise: Variants = { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.7, ease: easeOut }, - }, -}; - -export const simpleGridContainer: Variants = { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { - staggerChildren: 0.15, - delayChildren: 0.1, - }, - }, -}; - -export const numberCounter: Variants = { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { - duration: 0.6, - ease: easeOut, - }, - }, -}; - -export const statCard: Variants = { - hidden: { - opacity: 0, - y: 30, - scale: 0.95, - }, - visible: { - opacity: 1, - y: 0, - scale: 1, - transition: { - duration: 0.5, - ease: easeOut, - }, - }, - hover: { - scale: 1.05, - y: -5, - transition: { - duration: 0.3, - }, - }, -}; - -export const statGrid: Variants = { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { - staggerChildren: 0.12, - delayChildren: 0.1, - }, - }, -}; - -export const headerReveal: Variants = { - hidden: { - opacity: 0, - y: 20, - }, - visible: { - opacity: 1, - y: 0, - transition: { - duration: 0.7, - ease: easeOut, - }, - }, -}; - -export const imageReveal: Variants = { - hidden: { - opacity: 0, - scale: 1.1, - }, - visible: { - opacity: 1, - scale: 1, - transition: { - delay: 0.2, - duration: 0.5, - }, - }, -}; - -export const testimonialCard: Variants = { - hidden: { - opacity: 0, - y: 20, - scale: 0.97, - }, - visible: { - opacity: 1, - y: 0, - scale: 1, - transition: { - duration: 0.5, - ease: easeOut, - }, - }, - hover: { - y: -8, - boxShadow: - '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', - transition: { - type: 'spring' as const, - stiffness: 400, - damping: 15, - }, - }, -}; - -export const testimonialHeading: Variants = { - hidden: { - opacity: 0, - scale: 0.95, - }, - visible: { - opacity: 1, - scale: 1, - transition: { - duration: 0.7, - ease: easeOut, - }, - }, -}; - -export const decorativeElement: Variants = { - hidden: { - opacity: 0, - scale: 0, - rotate: -10, - }, - visible: { - opacity: 1, - scale: 1, - rotate: 0, - transition: { - type: 'spring' as const, - stiffness: 300, - damping: 15, - }, - }, - float: { - y: [0, -7, 0], - transition: { - duration: 3, - repeat: Infinity, - repeatType: 'reverse', - ease: easeInOut, - }, - }, -}; - -export const testimonialText: Variants = { - hidden: { - opacity: 0, - }, - visible: { - opacity: 1, - transition: { - delay: 0.2, - duration: 0.5, - }, - }, -}; - -export const avatarReveal: Variants = { - hidden: { - scale: 0.5, - opacity: 0, - }, - visible: { - scale: 1, - opacity: 1, - transition: { - type: 'spring' as const, - stiffness: 400, - damping: 15, - }, - }, -}; - -export const marqueeContainer: Variants = { - hidden: { - opacity: 0, - }, - visible: { - opacity: 1, - transition: { - staggerChildren: 0.08, - delayChildren: 0.1, - }, - }, -}; - -export const container = { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { - staggerChildren: 0.2, - delayChildren: 0.3, - }, - }, -}; - -export const item = { - hidden: { y: 20, opacity: 0 }, - visible: { - y: 0, - opacity: 1, - transition: { - duration: 0.8, - ease: easeOut, - }, - }, - hover: { - scale: 1.02, - boxShadow: '0 10px 30px rgba(0,0,0,0.1)', - transition: { duration: 0.3 }, - }, -}; - -export const goalSectionAnimations = { - goalItem: slideInLeft, - progressBar: { - hidden: { width: 0 }, - visible: (percent: number) => ({ - width: `${percent}%`, - transition: { duration: 1, ease: easeOut }, - }), - }, - flowContainer: subtleRise, - statCard: statCard, - insightsBox: subtleRise, - overallProgressBar: { - hidden: { width: 0 }, - visible: (percent: number) => ({ - width: `${percent}%`, - transition: { duration: 1.5, ease: easeOut }, - }), - }, -}; - -export const heroAnimations = { - container: { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { duration: 1 }, - }, - }, - letterAnimation: { - hidden: { opacity: 0, y: 50 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.6, ease: easeOut }, - }, - }, - decoration: { - hidden: { scale: 0, opacity: 0 }, - visible: { - scale: 1, - opacity: 1, - transition: { duration: 0.8, ease: backOut }, - }, - }, - subtitle: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { delay: 1.5, duration: 0.8 }, - }, - }, - underline: { - hidden: { width: 0, opacity: 0 }, - visible: { - width: '100%', - opacity: 1, - transition: { delay: 1.2, duration: 0.8 }, - }, - }, - hoverText: { - initial: {}, - hover: { - scale: 1.05, - transition: { type: 'spring' as const, stiffness: 300 }, - }, - }, - mouseFollow: { - hidden: { opacity: 0 }, - visible: { - opacity: 0.2, - transition: { duration: 0.3 }, - }, - hover: { - scale: 1.2, - transition: { duration: 0.3 }, - }, - }, -}; - -export const missionSectionAnimations = { - // Container animations for staggered children - containerVariants: { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { - staggerChildren: 0.2, - delayChildren: 0.1, - }, - }, - }, - - // Individual item animations - itemVariants: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { - duration: 0.5, - ease: easeOut, - }, - }, - }, - - // Main image animations - mainImageVariants: { - initial: { opacity: 0, scale: 0.95 }, - whileInView: { opacity: 1, scale: 1 }, - transition: { duration: 0.6, ease: easeOut }, - hover: { - scale: 1.03, - transition: { duration: 0.4 }, - }, - }, - - // Underline animation for title - titleUnderlineVariants: { - hidden: { width: 0 }, - visible: { - width: '100%', - transition: { delay: 0.5, duration: 0.4 }, - }, - }, - - // Image hover animations - imageHoverVariants: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { - duration: 0.5, - }, - }, - hover: { - scale: 1.05, - boxShadow: '0 10px 25px rgba(0,0,0,0.2)', - transition: { - duration: 0.4, - }, - }, - }, - - // Image scale animation - imageScaleVariants: { - initial: { scale: 1 }, - hover: { - scale: 1.15, - transition: { duration: 0.4 }, - }, - }, -}; - -// Principles Section animations -export const principlesSectionAnimations = { - container: { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { staggerChildren: 0.1 }, - }, - }, - - card: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.5 }, - }, - }, - - title: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.5 }, - }, - }, - - description: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { delay: 0.3, duration: 0.5 }, - }, - }, - - featureImage: { - hidden: { opacity: 0, scale: 0.95 }, - visible: { - opacity: 1, - scale: 1, - transition: { duration: 0.5 }, - }, - hover: { - scale: 1.05, - translateY: -10, - transition: { duration: 0.3 }, - }, - }, - - overlay: { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { duration: 0.3 }, - }, - }, - - cardImage: { - hidden: { opacity: 0.9 }, - hover: { - scale: 1.05, - transition: { duration: 0.3 }, - }, - }, -}; - -// Projects Section animations -export const projectsSectionAnimations = { - container: { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { - staggerChildren: 0.15, - delayChildren: 0.1, - }, - }, - }, - - projectCard: { - hidden: { opacity: 0, y: 20 }, - visible: (i: number) => ({ - opacity: 1, - y: 0, - transition: { - delay: i * 0.1, - duration: 0.5, - ease: easeOut, - }, - }), - hover: { - y: -8, - boxShadow: - '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', - transition: { duration: 0.3 }, - }, - }, - - learnMoreButton: { - hidden: { opacity: 0.9 }, - hover: { - x: 5, - transition: { duration: 0.2 }, - }, - }, - - title: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.5, delay: 0.1 }, - }, - }, - - imageContainer: { - hidden: { opacity: 0, scale: 0.95 }, - visible: { - opacity: 1, - scale: 1, - transition: { duration: 0.4 }, - }, - }, -}; - -export const roadmapSectionAnimations = { - // Line connecting roadmap items - connectingLine: { - hidden: { width: 0 }, - visible: { - width: '100%', - transition: { duration: 1.2, ease: easeInOut }, - }, - }, - - // Individual roadmap items/cards - roadmapCard: { - hidden: { opacity: 0, y: 20 }, - visible: (i: number) => ({ - opacity: 1, - y: 0, - transition: { - duration: 0.6, - delay: i * 0.3, - }, - }), - }, - - // Section title - title: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.5 }, - }, - }, - - // Description paragraph - description: { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { delay: 0.8, duration: 0.5 }, - }, - }, - - // Number indicator - stepNumber: { - hidden: { scale: 0 }, - visible: (i: number) => ({ - scale: 1, - transition: { - type: 'spring' as const, - stiffness: 300, - damping: 10, - delay: i * 0.3 + 0.3, - }, - }), - }, - - // Card hover effect - cardHover: { - scale: 1.03, - boxShadow: - '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', - transition: { duration: 0.3 }, - }, -}; - -export const dividerVariants = { - hidden: { width: 0, opacity: 0 }, - visible: { - width: '6rem', - opacity: 1, - transition: { - duration: 0.8, - delay: 0.3, - ease: easeOut, - }, - }, -}; - -export const faqPageAnimations = { - // Page section animations - pageSection: { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { duration: 0.6, ease: easeOut }, - }, - }, - - // Text content animations - headingText: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.7, ease: easeOut }, - }, - }, - - paragraphText: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.7, ease: easeOut, delay: 0.2 }, - }, - }, - - // Hero image animation - heroImage: { - hidden: { opacity: 0, x: 100 }, - visible: { - opacity: 1, - x: 0, - transition: { duration: 0.6, ease: easeOut }, - }, - hover: { - scale: 1.03, - transition: { duration: 0.3 }, - }, - }, - - // Quick answers grid container - quickAnswersContainer: { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { - staggerChildren: 0.15, - delayChildren: 0.1, - }, - }, - }, - - // Quick answer card animation - quickAnswerCard: { - hidden: { scale: 0.9, opacity: 0 }, - visible: { - scale: 1, - opacity: 1, - transition: { - type: 'spring' as const, - stiffness: 400, - damping: 10, - }, - }, - hover: { - scale: 1.05, - transition: { - type: 'spring' as const, - stiffness: 400, - damping: 10, - }, - }, - tap: { scale: 0.95 }, - }, - - // Icon in quick answer cards - quickAnswerIcon: { - hidden: { rotate: -10, scale: 0.9 }, - visible: (index: number) => ({ - rotate: 0, - scale: 1, - transition: { - duration: 0.5, - delay: index * 0.1, - }, - }), - }, - - // FAQ container - faqContainer: { - hidden: { opacity: 0 }, - visible: { - opacity: 1, - transition: { - staggerChildren: 0.2, - delayChildren: 0.3, - }, - }, - }, - - // FAQ item animation - faqItem: { - hidden: { y: 20, opacity: 0 }, - visible: (index: number) => ({ - y: 0, - opacity: 1, - transition: { - duration: 0.8, - delay: index * 0.1, - ease: easeOut, - }, - }), - }, - - // FAQ question button hover - faqQuestionButton: { - initial: {}, - hover: { - x: 5, - transition: { - type: 'spring' as const, - stiffness: 300, - }, - }, - }, - - // FAQ toggle icon animation - faqToggleIcon: (isOpen: boolean): Variants => ({ - initial: { rotate: 0 }, - animate: { - rotate: isOpen ? 180 : 0, - transition: { duration: 0.3 }, - }, - }), - - // FAQ answer animation - faqAnswer: (isOpen: boolean): Variants => ({ - initial: { height: 0, opacity: 0 }, - animate: { - height: isOpen ? 'auto' : 0, - opacity: isOpen ? 1 : 0, - transition: { duration: 0.3 }, - }, - }), -}; - -export const teamSectionAnimations = { - section: { - hidden: { opacity: 0, y: 50 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.8, ease: easeOut }, - }, - }, - - heading: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.6, ease: easeOut, delay: 0.2 }, - }, - }, - - memberCard: { - hidden: { opacity: 0, scale: 0.9 }, - visible: { - opacity: 1, - scale: 1, - transition: { duration: 0.6, ease: easeOut }, - }, - }, - - memberImage: { - hidden: { opacity: 0, scale: 0.8 }, - visible: { - opacity: 1, - scale: 1, - transition: { duration: 0.6, ease: easeOut, delay: 0.3 }, - }, - }, -}; - -export const paragraphAnimations = { - section: { - hidden: { opacity: 0, y: 50 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.6, ease: easeOut }, - }, - }, - - text: { - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.4, ease: easeOut }, - }, - }, - - listItem: (index: number) => ({ - hidden: { opacity: 0, y: 20 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.4, delay: index * 0.1 }, - }, - }), - - button: { - hover: { - scale: 1.05, - transition: { duration: 0.3 }, - }, - }, -}; - -export const numberedCardAnimations = { - card: { - hidden: { opacity: 0, y: 50 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.6, ease: easeOut }, - }, - hover: { - scale: 1.05, - boxShadow: '0px 10px 20px rgba(0, 0, 0, 0.2)', - transition: { duration: 0.3 }, - }, - }, - - numberCircle: { - hover: { - rotate: 10, - transition: { duration: 0.3 }, - }, - }, - - image: { - hover: { - scale: 1.02, - transition: { duration: 0.3 }, - }, - }, -}; - -export const logoCardAnimations = { - card: { - hidden: { opacity: 0, y: 50 }, - visible: (index: number) => ({ - opacity: 1, - y: 0, - transition: { duration: 0.6, ease: easeOut, delay: index * 0.15 }, - }), - hover: { - scale: 1.05, - boxShadow: '0px 10px 20px rgba(0, 0, 0, 0.2)', - transition: { duration: 0.3 }, - }, - }, - - logoContainer: { - hover: { - rotate: 10, - transition: { duration: 0.3 }, - }, - }, - - button: { - hover: { scale: 1.1, transition: { duration: 0.2 } }, - tap: { scale: 0.95 }, - }, -}; - -export const featureSectionAnimations = { - section: { - hidden: { opacity: 0, y: 50 }, - visible: { - opacity: 1, - y: 0, - transition: { duration: 0.8, ease: easeOut }, - }, - }, - - textContainer: { - hidden: { opacity: 0, x: -50 }, - visible: { - opacity: 1, - x: 0, - transition: { duration: 0.8, ease: easeOut }, - }, - }, - - imageContainer: { - hidden: { opacity: 0, x: 50 }, - visible: { - opacity: 1, - x: 0, - transition: { duration: 0.8, ease: easeOut }, - }, - }, - - image: { - hidden: { opacity: 0, scale: 0.8 }, - visible: { - opacity: 1, - scale: 1, - transition: { duration: 0.5, ease: easeOut }, - }, - hover: { scale: 1.05, transition: { duration: 0.3 } }, - }, - - button: { - hover: { - scale: 1.3, - transition: { type: 'spring' as const, stiffness: 300 }, - }, - }, - - note: { - hidden: { opacity: 0 }, - visible: { opacity: 1, transition: { delay: 0.3, duration: 0.5 } }, - }, -}; - -export const buttonAnimation: Variants = { - whileHover: { - scale: 1.05, - transition: { type: 'spring' as const, stiffness: 400, damping: 10 }, - }, - whileTap: { - scale: 0.95, - transition: { type: 'spring' as const, stiffness: 400, damping: 10 }, - }, -}; - -export const fadeInUpAnimation: Variants = { - initial: { opacity: 0, y: 30 }, - animate: { - opacity: 1, - y: 0, - transition: { - delay: 0.2, - duration: 1.5, - ease: easeOut, - }, - }, -}; - -export const zoomFadeInAnimation: Variants = { - initial: { opacity: 0, scale: 0.9 }, - animate: { - opacity: 1, - scale: 1, - transition: { - delay: 1, - duration: 1.5, - ease: easeOut, - }, - }, -}; - -export const zoomInAnimation = { - initial: { scale: 0.8, opacity: 0 }, - animate: { - scale: 1, - opacity: 1, - transition: { duration: 0.8, ease: easeOut }, - }, -}; - -export const fadeInDelayed = { - initial: { opacity: 0, y: 50 }, - animate: { - opacity: 1, - y: 0, - transition: { duration: 0.8, ease: easeOut, delay: 0.5 }, - }, -}; - -export const cardFadeIn = { - hidden: { opacity: 0, y: 40 }, - visible: (index: number) => ({ - opacity: 1, - y: 0, - transition: { duration: 0.6, ease: easeOut, delay: index * 0.2 }, - }), -}; - -export const lineAnimation = { - hidden: { height: 0 }, - visible: { - height: '100%', - transition: { duration: 1.5, ease: easeInOut }, - }, -}; - -export const floatUpAndFade = { - hidden: { - opacity: 0, - y: 60, - scale: 0.8, - }, - visible: { - opacity: 1, - y: 0, - scale: 1, - transition: { - duration: 1.2, - ease: easeOut, - type: 'spring' as const, - damping: 25, - stiffness: 100, - }, - }, -}; - -export const floatUpAndFadeDelayed = { - hidden: { - opacity: 0, - y: 40, - scale: 0.9, - }, - visible: { - opacity: 1, - y: 0, - scale: 1, - transition: { - duration: 1.0, - ease: easeOut, - delay: 0.3, - type: 'spring' as const, - damping: 20, - stiffness: 120, - }, - }, -}; - -export const iconFloat = { - hidden: { - opacity: 0, - y: 30, - rotate: -10, - }, - visible: { - opacity: 1, - y: 0, - rotate: 0, - transition: { - duration: 0.8, - ease: easeOut, - delay: 0.6, - }, - }, -}; diff --git a/src/styles/globals.css b/src/styles/globals.css deleted file mode 100644 index 20193442..00000000 --- a/src/styles/globals.css +++ /dev/null @@ -1,178 +0,0 @@ -@font-face { - font-family: 'Caveat'; - src: url('/fonts/Caveat-Regular.ttf'); -} - -@plugin 'tailwindcss-animate'; - -@custom-variant dark (&:is(.dark *)); -@font-face { - font-family: 'Roboto'; - src: url('/fonts/Roboto-Regular.ttf'); -} -@font-face { - font-family: 'Pacifico'; - src: url('/fonts/Pacifico-Regular.ttf'); -} -@font-face { - font-family: 'AnonymousPro'; - src: url('/fonts/AnonymousPro-Regular.ttf'); -} -@font-face { - font-family: 'Inter'; - src: url('/fonts/Inter_28pt-Regular.ttf'); -} -@font-face { - font-family: 'Oswald'; - src: url('/fonts/Oswald-Regular.ttf'); -} - -@import 'tailwindcss'; - -@theme { - --font-Caveat: 'Caveat', sans-serif; - --font-Roboto: 'Roboto', sans-serif; - --font-Pacifico: 'Pacifico', sans-serif; - --font-AnonymousPro: 'AnonymousPro', sans-serif; - --font-Inter: 'Inter', sans-serif; - --font-Oswald: 'Oswald', sans-serif; -} - -:root { - --background: oklch(1 0 0); - --foreground: oklch(0.141 0.005 285.823); - --card: oklch(1 0 0); - --card-foreground: oklch(0.141 0.005 285.823); - --popover: oklch(1 0 0); - --popover-foreground: oklch(0.141 0.005 285.823); - --primary: oklch(0.21 0.006 285.885); - --primary-foreground: oklch(0.985 0 0); - --secondary: oklch(0.967 0.001 286.375); - --secondary-foreground: oklch(0.21 0.006 285.885); - --muted: oklch(0.967 0.001 286.375); - --muted-foreground: oklch(0.552 0.016 285.938); - --accent: oklch(0.967 0.001 286.375); - --accent-foreground: oklch(0.21 0.006 285.885); - --destructive: oklch(0.577 0.245 27.325); - --destructive-foreground: oklch(0.577 0.245 27.325); - --border: oklch(0.92 0.004 286.32); - --input: oklch(0.92 0.004 286.32); - --ring: oklch(0.871 0.006 286.286); - --chart-1: oklch(0.646 0.222 41.116); - --chart-2: oklch(0.6 0.118 184.704); - --chart-3: oklch(0.398 0.07 227.392); - --chart-4: oklch(0.828 0.189 84.429); - --chart-5: oklch(0.769 0.188 70.08); - --radius: 0.625rem; - --sidebar: oklch(0.985 0 0); - --sidebar-foreground: oklch(0.141 0.005 285.823); - --sidebar-primary: oklch(0.21 0.006 285.885); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.967 0.001 286.375); - --sidebar-accent-foreground: oklch(0.21 0.006 285.885); - --sidebar-border: oklch(0.92 0.004 286.32); - --sidebar-ring: oklch(0.871 0.006 286.286); -} - -.dark { - --background: oklch(0.141 0.005 285.823); - --foreground: oklch(0.985 0 0); - --card: oklch(0.141 0.005 285.823); - --card-foreground: oklch(0.985 0 0); - --popover: oklch(0.141 0.005 285.823); - --popover-foreground: oklch(0.985 0 0); - --primary: oklch(0.985 0 0); - --primary-foreground: oklch(0.21 0.006 285.885); - --secondary: oklch(0.274 0.006 286.033); - --secondary-foreground: oklch(0.985 0 0); - --muted: oklch(0.274 0.006 286.033); - --muted-foreground: oklch(0.705 0.015 286.067); - --accent: oklch(0.274 0.006 286.033); - --accent-foreground: oklch(0.985 0 0); - --destructive: oklch(0.396 0.141 25.723); - --destructive-foreground: oklch(0.637 0.237 25.331); - --border: oklch(0.274 0.006 286.033); - --input: oklch(0.274 0.006 286.033); - --ring: oklch(0.442 0.017 285.786); - --chart-1: oklch(0.488 0.243 264.376); - --chart-2: oklch(0.696 0.17 162.48); - --chart-3: oklch(0.769 0.188 70.08); - --chart-4: oklch(0.627 0.265 303.9); - --chart-5: oklch(0.645 0.246 16.439); - --sidebar: oklch(0.21 0.006 285.885); - --sidebar-foreground: oklch(0.985 0 0); - --sidebar-primary: oklch(0.488 0.243 264.376); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.274 0.006 286.033); - --sidebar-accent-foreground: oklch(0.985 0 0); - --sidebar-border: oklch(0.274 0.006 286.033); - --sidebar-ring: oklch(0.442 0.017 285.786); -} - -@theme inline { - --color-background: var(--background); - --color-foreground: var(--foreground); - --color-card: var(--card); - --color-card-foreground: var(--card-foreground); - --color-popover: var(--popover); - --color-popover-foreground: var(--popover-foreground); - --color-primary: var(--primary); - --color-primary-foreground: var(--primary-foreground); - --color-secondary: var(--secondary); - --color-secondary-foreground: var(--secondary-foreground); - --color-muted: var(--muted); - --color-muted-foreground: var(--muted-foreground); - --color-accent: var(--accent); - --color-accent-foreground: var(--accent-foreground); - --color-destructive: var(--destructive); - --color-destructive-foreground: var(--destructive-foreground); - --color-border: var(--border); - --color-input: var(--input); - --color-ring: var(--ring); - --color-chart-1: var(--chart-1); - --color-chart-2: var(--chart-2); - --color-chart-3: var(--chart-3); - --color-chart-4: var(--chart-4); - --color-chart-5: var(--chart-5); - --radius-sm: calc(var(--radius) - 4px); - --radius-md: calc(var(--radius) - 2px); - --radius-lg: var(--radius); - --radius-xl: calc(var(--radius) + 4px); - --color-sidebar: var(--sidebar); - --color-sidebar-foreground: var(--sidebar-foreground); - --color-sidebar-primary: var(--sidebar-primary); - --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); - --color-sidebar-accent: var(--sidebar-accent); - --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); - --color-sidebar-border: var(--sidebar-border); - --color-sidebar-ring: var(--sidebar-ring); - --animate-marquee: marquee var(--duration) infinite linear; - --animate-marquee-vertical: marquee-vertical var(--duration) linear infinite; - - @keyframes marquee { - from { - transform: translateX(0); - } - to { - transform: translateX(calc(-100% - var(--gap))); - } - } - - @keyframes marquee-vertical { - from { - transform: translateY(0); - } - to { - transform: translateY(calc(-100% - var(--gap))); - } - } -} - -@layer base { - * { - @apply border-border outline-ring/50; - } - body { - @apply bg-background text-foreground; - } -} diff --git a/src/utils/MarkdownRenderer.tsx b/src/utils/MarkdownRenderer.tsx deleted file mode 100644 index 0ff8d601..00000000 --- a/src/utils/MarkdownRenderer.tsx +++ /dev/null @@ -1,662 +0,0 @@ -import { useEffect, useMemo, useCallback } from 'react'; -import React, { Children } from 'react'; -import ReactMarkdown, { Components } from 'react-markdown'; -import remarkGfm from 'remark-gfm'; -import remarkSupersub from 'remark-supersub'; -import remarkFrontmatter from 'remark-frontmatter'; -import rehypeRaw from 'rehype-raw'; -import rehypeSlug from 'rehype-slug'; -import rehypeAutolinkHeadings from 'rehype-autolink-headings'; -import rehypeSanitize, { defaultSchema } from 'rehype-sanitize'; -import { h } from 'hastscript'; - -// Type definitions -interface MarkdownRendererProps { - content: string; - setZoomableImages?: (images: HTMLImageElement[]) => void; - frontmatter?: Record<string, string | number | boolean | null>; -} - -// Constants -const EMOJI_MAP: Record<string, string> = { - ':smile:': '😊', - ':heart:': '❤️', - ':thumbsup:': '👍', - ':thumbsdown:': '👎', - ':rocket:': '🚀', - ':star:': '⭐', - ':fire:': '🔥', - ':warning:': '⚠️', - ':info:': 'ℹ️', - ':check:': '✅', - ':x:': '❌', - ':eyes:': '👀', - ':tada:': '🎉', - ':bug:': '🐛', - ':sparkles:': '✨', - ':wrench:': '🔧', - ':gear:': '⚙️', - ':bulb:': '💡', - ':package:': '📦', - ':memo:': '📝', - ':link:': '🔗', - ':lock:': '🔒', - ':unlock:': '🔓', - ':zap:': '⚡', - ':boom:': '💥', - ':computer:': '💻', - ':phone:': '📱', - ':email:': '📧', - ':calendar:': '📅', - ':clock:': '🕐', - ':house:': '🏠', - ':car:': '🚗', - ':plane:': '✈️', - ':coffee:': '☕', - ':pizza:': '🍕', -}; - -const ALERT_TYPES = { - note: { - icon: 'ℹ️', - bg: 'bg-blue-50', - border: 'border-blue-200', - text: 'text-blue-800', - }, - tip: { - icon: '💡', - bg: 'bg-green-50', - border: 'border-green-200', - text: 'text-green-800', - }, - important: { - icon: '❗', - bg: 'bg-purple-50', - border: 'border-purple-200', - text: 'text-purple-800', - }, - warning: { - icon: '⚠️', - bg: 'bg-yellow-50', - border: 'border-yellow-200', - text: 'text-yellow-800', - }, - caution: { - icon: '🚨', - bg: 'bg-red-50', - border: 'border-red-200', - text: 'text-red-800', - }, -}; - -const CUSTOM_SANITIZE_SCHEMA = { - ...defaultSchema, - tagNames: [ - ...(defaultSchema.tagNames || []), - 'mark', - 'iframe', - 'details', - 'summary', - 'kbd', - 'del', - 'ins', - 'figure', - 'figcaption', - ], - attributes: { - ...defaultSchema.attributes, - mark: ['class', 'data-*'], - iframe: [ - 'src', - 'allow', - 'allowfullscreen', - 'frameborder', - 'title', - 'style', - 'width', - 'height', - 'loading', - 'class', - ], - details: ['open', 'class'], - summary: ['class'], - kbd: ['class'], - figure: ['class'], - figcaption: ['class'], - div: ['class', 'style'], - '*': [ - ...(defaultSchema.attributes?.['*'] || []), - 'className', - 'data-*', - 'aria-*', - ], - }, - protocols: { ...defaultSchema.protocols, src: ['http', 'https', 'data'] }, -}; - -// Utility functions -const processMarkdownContent = (content: string): string => { - let processed = content; - - // Replace emoji shortcodes - Object.entries(EMOJI_MAP).forEach(([code, emoji]) => { - processed = processed.replace( - new RegExp(code.replace(/[-\\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), - emoji, - ); - }); - - // GitHub-style highlighting - processed = processed.replace( - /==([\s\S]*?)==/g, - '<mark class="bg-yellow-200 px-1 rounded">$1</mark>', - ); - - // Keyboard shortcuts - processed = processed.replace( - /\[\[([^\]]+)\]\]/g, - '<kbd class="px-2 py-1 text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-300 rounded-lg shadow-sm">$1</kbd>', - ); - - // Strikethrough - processed = processed.replace( - /~~([\s\S]*?)~~/g, - '<del class="line-through text-gray-500">$1</del>', - ); - - // Collapsible sections - processed = processed.replace( - /:::details\s+(.*?)\n([\s\S]*?):::/gim, - '<details class="my-4 border border-gray-200 rounded-lg overflow-hidden bg-white">' + - '<summary class="bg-gray-50 px-4 py-3 cursor-pointer font-medium text-gray-800 hover:bg-gray-100 transition-colors border-b border-gray-200">$1</summary>' + - '<div class="px-4 py-3 text-gray-700">$2</div></details>', - ); - - // GitHub-style alerts - processed = processed.replace( - /:::(\w+)\s*(.*?)\n([\s\S]*?):::/gim, - (_, type, title, content) => { - const alert = - ALERT_TYPES[type as keyof typeof ALERT_TYPES] || ALERT_TYPES.note; - return `<div class="my-4 p-4 border-l-4 ${alert.border} ${alert.bg} rounded-r-lg"> - <div class="flex items-center mb-2"> - <span class="mr-2 text-lg">${alert.icon}</span> - <strong class="${alert.text} font-semibold uppercase text-sm tracking-wide">${type}${title ? `: ${title}` : ''}</strong> - </div> - <div class="${alert.text}">${content}</div> - </div>`; - }, - ); - - // YouTube embeds - processed = processed.replace( - /\[youtube:\s*([\w-]+)\]/gim, - (_, videoId) => - `<div class="my-8 mx-auto max-w-4xl"><div class="relative rounded-xl shadow-lg overflow-hidden bg-black" style="aspect-ratio: 16/9;"> - <iframe src="https://www.youtube.com/embed/${videoId}?autoplay=0&rel=0&modestbranding=1" class="absolute inset-0 w-full h-full border-0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen loading="lazy" title="YouTube video player"></iframe></div></div>`, - ); - - return processed; -}; - -const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({ - content, - setZoomableImages, - frontmatter, -}) => { - const processedContent = useMemo( - () => processMarkdownContent(content), - [content], - ); - - const scrollToAnchor = useCallback(() => { - const hash = window.location.hash; - if (hash && hash.length > 1) { - const id = hash.substring(1); - setTimeout(() => { - const targetElement = document.getElementById(id); - if (targetElement) { - targetElement.scrollIntoView({ - behavior: 'smooth', - block: 'start', - }); - } - }, 100); - } - }, []); - - const handleCopyClick = useCallback(async (e: MouseEvent) => { - const button = (e.target as HTMLElement).closest( - '.copy-code-btn', - ) as HTMLButtonElement | null; - if (!button) return; - - const code = button.getAttribute('data-code') || ''; - - try { - await navigator.clipboard.writeText(code); - const successMessage = button.nextElementSibling as HTMLElement; - if (successMessage) { - successMessage.classList.remove('hidden'); - successMessage.classList.add('flex'); - setTimeout(() => { - successMessage.classList.add('hidden'); - successMessage.classList.remove('flex'); - }, 2000); - } - } catch { - const textArea = document.createElement('textarea'); - textArea.value = code; - textArea.style.cssText = 'position:fixed;opacity:0;'; - document.body.appendChild(textArea); - textArea.select(); - document.execCommand('copy'); - document.body.removeChild(textArea); - } - }, []); - - const handleAnchorClick = useCallback((e: MouseEvent) => { - const target = e.target as HTMLElement; - - if (target.closest('.copy-code-btn')) { - return; - } - - const anchorLink = target.closest('a[href^="#"]') as HTMLAnchorElement; - if (anchorLink) { - e.preventDefault(); - const href = anchorLink.getAttribute('href'); - if (href && href.startsWith('#')) { - const id = href.substring(1); - const targetElement = document.getElementById(id); - - if (targetElement) { - const currentUrl = window.location.pathname + window.location.search; - window.history.pushState(null, '', `${currentUrl}${href}`); - targetElement.scrollIntoView({ behavior: 'smooth' }); - } - } - } - }, []); - - useEffect(() => { - document.addEventListener('click', handleCopyClick); - document.addEventListener('click', handleAnchorClick); - return () => { - document.removeEventListener('click', handleCopyClick); - document.removeEventListener('click', handleAnchorClick); - }; - }, [handleCopyClick, handleAnchorClick]); - - useEffect(() => { - if (setZoomableImages) { - const images = document.querySelectorAll('img[data-zoomable="true"]'); - setZoomableImages(Array.from(images) as HTMLImageElement[]); - } - }, [processedContent, setZoomableImages]); - - useEffect(() => { - scrollToAnchor(); - const handlePopState = () => { - scrollToAnchor(); - }; - - window.addEventListener('popstate', handlePopState); - - return () => { - window.removeEventListener('popstate', handlePopState); - }; - }, [processedContent, scrollToAnchor]); - - // Component definitions with shared styles - const headingClasses = { - h1: 'text-3xl font-bold my-6 text-gray-900 group flex items-center border-b border-gray-200 pb-2', - h2: 'text-2xl font-semibold my-5 text-gray-900 group flex items-center border-b border-gray-200 pb-1', - h3: 'text-xl font-semibold my-4 text-gray-900 group flex items-center', - h4: 'text-lg font-semibold my-3 text-gray-900', - h5: 'text-base font-semibold my-3 text-gray-900', - h6: 'text-sm font-semibold my-3 text-gray-600 uppercase tracking-wide', - }; - - const createHeading = - (level: keyof typeof headingClasses) => - ({ - children, - ...props - }: React.HTMLAttributes<HTMLHeadingElement> & { - children?: React.ReactNode; - }) => { - const Tag = level; - return ( - <Tag {...props} className={headingClasses[level]}> - {children} - </Tag> - ); - }; - - const components: Components = { - h1: createHeading('h1'), - h2: createHeading('h2'), - h3: createHeading('h3'), - h4: createHeading('h4'), - h5: createHeading('h5'), - h6: createHeading('h6'), - - p: ({ children, ...props }) => ( - <p {...props} className="my-4 text-gray-700 leading-relaxed"> - {children} - </p> - ), - - blockquote: ({ children, ...props }) => ( - <blockquote - {...props} - className="border-l-3 border-blue-500 bg-blue-50 pl-5 pr-5 py-2 my-4 italic text-blue-800 rounded-r-2xl shadow-sm hover:shadow-md transition-shadow duration-200 " - > - <div className="relative z-10">{children}</div> - </blockquote> - ), - - code: ({ - inline, - className, - children, - ...props - }: { - inline?: boolean; - className?: string; - children?: React.ReactNode; - }) => { - const isInlineCode = - inline === true || (!className && typeof children === 'string'); - - if (isInlineCode) { - return ( - <code - {...props} - className="bg-gray-100 text-pink-600 px-2 py-1 rounded-md text-sm font-mono border border-gray-200 shadow-sm" - > - {children} - </code> - ); - } - - const codeText = Children.toArray(children).reduce( - (acc, child) => (typeof child === 'string' ? acc + child : acc), - '', - ); - const language = className?.replace('language-', '') || 'text'; - - return ( - <div className="relative rounded-xl overflow-hidden shadow-lg border border-gray-800 bg-gray-900 my-6 group"> - {/* Header with language and copy button */} - <div className="flex items-center justify-between px-6 py-3 bg-gray-200 border-b border-gray-200"> - <div className="flex items-center space-x-2"> - <div className="w-3 h-3 rounded-full bg-red-500"></div> - <div className="w-3 h-3 rounded-full bg-yellow-500"></div> - <div className="w-3 h-3 rounded-full bg-green-500"></div> - <span className="text-xs font-semibold text-gray-600 uppercase"> - {language} - </span> - </div> - <div className="flex items-center space-x-2"> - <button - className="copy-code-btn bg-gray-200 hover:bg-gray-300 text-gray-700 text-xs px-4 py-2 rounded-lg transition-all duration-200 flex items-center space-x-2 hover:scale-105 shadow-sm hover:shadow-md" - data-code={codeText} - aria-label="Copy code to clipboard" - > - <svg - className="w-4 h-4" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth="2" - d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" - /> - </svg> - <span className="font-medium">Copy</span> - </button> - <div className="copy-success-message hidden items-center space-x-2 bg-green-100 text-green-800 text-xs px-4 py-2 rounded-lg border border-green-200"> - <span className="font-medium">Copied!</span> - </div> - </div> - </div> - <div className="overflow-x-auto"> - <pre className="p-6 bg-gray-50 text-sm leading-relaxed"> - <code - className={`${className || ''} text-gray-800 font-mono block whitespace-pre`} - > - {children} - </code> - </pre> - </div> - </div> - ); - }, - - img: ({ src = '', alt = '', title, ...props }) => { - const imageSrc = - src === '' && frontmatter?.image ? String(frontmatter.image) : src; - return ( - <figure className="flex flex-col items-center my-6"> - <div className="overflow-hidden rounded-lg shadow-md hover:shadow-lg transition-all duration-300 border border-gray-200"> - <img - {...props} - src={imageSrc} - alt={alt} - title={title || alt || ''} - className="max-w-full h-auto rounded-lg object-contain hover:scale-105 transition-transform duration-300" - data-zoomable="true" - loading="lazy" - onError={(e) => { - (e.target as HTMLImageElement).src = - '/assets/Images/SugarNewsLogo.png'; - }} - /> - </div> - {(title || alt) && ( - <figcaption className="text-center text-sm text-gray-600 mt-3 italic"> - {title || alt} - </figcaption> - )} - </figure> - ); - }, - - table: ({ children, ...props }) => ( - <div className="overflow-x-auto my-6 rounded-lg shadow-sm border border-gray-200"> - <table {...props} className="min-w-full divide-y divide-gray-200"> - {children} - </table> - </div> - ), - - thead: ({ children, ...props }) => ( - <thead {...props} className="bg-gray-50"> - {children} - </thead> - ), - tbody: ({ children, ...props }) => ( - <tbody {...props} className="bg-white divide-y divide-gray-200"> - {children} - </tbody> - ), - tr: ({ children, ...props }) => ( - <tr {...props} className="hover:bg-gray-50 transition-colors"> - {children} - </tr> - ), - th: ({ children, ...props }) => ( - <th - {...props} - className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider border-r last:border-r-0 border-gray-200" - > - {children} - </th> - ), - td: ({ children, ...props }) => ( - <td - {...props} - className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 border-r last:border-r-0 border-gray-200" - > - {children} - </td> - ), - - ul: ({ children, ...props }) => ( - <ul {...props} className="list-disc pl-6 my-4 space-y-1"> - {children} - </ul> - ), - ol: ({ children, ...props }) => ( - <ol {...props} className="list-decimal pl-6 my-4 space-y-1"> - {children} - </ol> - ), - li: ({ children, ...props }) => ( - <li {...props} className="text-gray-700 leading-relaxed"> - {children} - </li> - ), - - a: ({ href = '#', children, ...props }) => { - const isExternal = href?.startsWith('http'); - const isAnchor = href?.startsWith('#'); - - return ( - <a - href={href} - {...props} - className="text-blue-600 hover:text-blue-800 hover:underline transition-colors font-medium" - target={isExternal ? '_blank' : undefined} - rel={isExternal ? 'noopener noreferrer' : undefined} - data-anchor-link={isAnchor ? 'true' : undefined} - > - {children} - {isExternal && ( - <svg - className="inline w-3 h-3 ml-1" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - strokeLinecap="round" - strokeLinejoin="round" - strokeWidth="2" - d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" - /> - </svg> - )} - </a> - ); - }, - - strong: ({ children, ...props }) => ( - <strong {...props} className="font-semibold text-gray-900"> - {children} - </strong> - ), - em: ({ children, ...props }) => ( - <em {...props} className="italic text-gray-700"> - {children} - </em> - ), - del: ({ children, ...props }) => ( - <del {...props} className="line-through text-gray-500"> - {children} - </del> - ), - hr: ({ ...props }) => ( - <hr {...props} className="my-8 border-t border-gray-300" /> - ), - input: ({ ...props }) => ( - <input - {...props} - disabled - className="form-checkbox h-4 w-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 mr-2" - /> - ), - - sub: ({ children }) => <sub className="text-xs">{children}</sub>, - sup: ({ children }) => <sup className="text-xs">{children}</sup>, - mark: ({ children }) => ( - <mark className="bg-yellow-200 px-1 rounded">{children}</mark> - ), - kbd: ({ children }) => ( - <kbd className="px-2 py-1 text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-300 rounded-lg shadow-sm"> - {children} - </kbd> - ), - details: ({ children, ...props }) => ( - <details - className="my-4 border border-gray-200 rounded-lg overflow-hidden bg-white" - {...props} - > - {children} - </details> - ), - summary: ({ children }) => ( - <summary className="bg-gray-50 px-4 py-3 cursor-pointer font-medium text-gray-800 hover:bg-gray-100 transition-colors border-b border-gray-200"> - {children} - </summary> - ), - }; - - return ( - <div className="prose prose-lg max-w-none"> - <ReactMarkdown - remarkPlugins={[remarkFrontmatter, remarkGfm, remarkSupersub]} - rehypePlugins={[ - rehypeRaw, - [rehypeSanitize, CUSTOM_SANITIZE_SCHEMA], - rehypeSlug, - [ - rehypeAutolinkHeadings, - { - behavior: 'append', - properties: { - className: [ - 'ml-2', - 'text-blue-600', - 'opacity-0', - 'group-hover:opacity-100', - 'transition-opacity', - 'no-underline', - ], - ariaLabel: 'Permalink to section', - title: 'Permalink to section', - }, - content: h( - 'svg', - { - className: 'w-4 h-4', - fill: 'currentColor', - viewBox: '0 0 20 20', - }, - [ - h('path', { - d: 'M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5z', - }), - h('path', { - d: 'M7.414 15.414a2 2 0 01-2.828-2.828l3-3a2 2 0 012.828 0 1 1 0 001.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5z', - }), - ], - ), - }, - ], - ]} - components={components} - > - {processedContent} - </ReactMarkdown> - </div> - ); -}; - -export default MarkdownRenderer; diff --git a/src/utils/author-utils.ts b/src/utils/author-utils.ts deleted file mode 100644 index c37f45bf..00000000 --- a/src/utils/author-utils.ts +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Author utility functions - * Clean and simple version - */ - -import { parseFrontmatter } from '@/utils/posts-utils'; - -export interface Author { - slug: string; - name: string; - title: string; - organization: string; - description: string; - avatar?: string; - content: string; -} - -export interface AuthorReference { - name: string; - description: string; - slug: string; - avatar?: string; -} - -/** - * Convert frontmatter value to string with fallback - */ -const frontmatterToString = ( - value: string | string[] | undefined, - fallback = '', -): string => - Array.isArray(value) ? value.join(' ').trim() : value?.trim() || fallback; - -/** - * Fetch and parse all author markdown files - */ -export const fetchAllAuthors = async (): Promise<Author[]> => { - try { - const authorFiles = import.meta.glob( - '@/constants/MarkdownFiles/authors/*.md', - { - query: '?raw', - import: 'default', - }, - ); - - const allAuthors: Author[] = []; - - for (const [filePath, importFn] of Object.entries(authorFiles)) { - try { - const fileContent = await importFn(); - const { frontmatter, content } = parseFrontmatter( - fileContent as string, - ); - - const author: Author = { - slug: frontmatterToString(frontmatter.slug), - name: frontmatterToString(frontmatter.name), - title: frontmatterToString(frontmatter.title), - organization: frontmatterToString(frontmatter.organization), - description: frontmatterToString(frontmatter.description), - avatar: frontmatterToString(frontmatter.avatar), - content, - }; - - allAuthors.push(author); - } catch (error) { - console.error(`Error processing author file ${filePath}:`, error); - } - } - - return allAuthors.sort((a, b) => a.name.localeCompare(b.name)); - } catch (error) { - console.error('Error fetching authors:', error); - return []; - } -}; - -/** - * Get author by slug - */ -export const getAuthorBySlug = async (slug: string): Promise<Author | null> => { - const authors = await fetchAllAuthors(); - return authors.find((author) => author.slug === slug) || null; -}; - -/** - * Parse author reference from post frontmatter - * Supports both old format (string) and new format (file path) - */ -export const parseAuthorReference = async ( - authorField: string | undefined, - descriptionField: string | undefined, -): Promise<AuthorReference | null> => { - if (!authorField) return null; - - // Check if it's a file path reference - if (authorField.includes('.md')) { - try { - const authorSlug = authorField.split('/').pop()?.replace('.md', '') || ''; - const author = await getAuthorBySlug(authorSlug); - - if (author) { - return { - name: author.name, - description: author.description, - slug: author.slug, - avatar: author.avatar, - }; - } - } catch (error) { - console.error('Error loading author from file:', error); - } - } - - // Fallback to old format - return { - name: authorField, - description: descriptionField || 'Author at SugarLabs', - slug: authorField.toLowerCase().replace(/\s+/g, '-'), - }; -}; - -/** - * Get all authors referenced in posts - */ -export const getAuthorsUsedInPosts = async (): Promise<AuthorReference[]> => { - return []; -}; diff --git a/src/utils/copy-code.ts b/src/utils/copy-code.ts deleted file mode 100644 index a2733e87..00000000 --- a/src/utils/copy-code.ts +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copy code functionality for code blocks - * Simplified and optimized version - */ - -/** - * Handle click on copy button with unified clipboard handling - */ -function handleCopyClick(event: Event): void { - event.preventDefault(); - event.stopPropagation(); - - const button = event.currentTarget as HTMLElement; - const codeContent = button.getAttribute('data-code'); - - if (!codeContent) { - console.error('No code content found to copy'); - return; - } - - copyToClipboard(codeContent, button); -} - -/** - * Unified clipboard copy with fallback - */ -async function copyToClipboard( - text: string, - button: HTMLElement, -): Promise<void> { - try { - await navigator.clipboard.writeText(text); - showSuccessMessage(button); - } catch { - // Fallback for older browsers - const textarea = document.createElement('textarea'); - textarea.value = text; - textarea.style.cssText = - 'position:fixed;left:-999999px;top:-999999px;opacity:0;'; - - document.body.appendChild(textarea); - textarea.select(); - - const success = document.execCommand('copy'); - document.body.removeChild(textarea); - - if (success) showSuccessMessage(button); - } -} - -/** - * Show success message - */ -function showSuccessMessage(button: HTMLElement): void { - const successMessage = button.nextElementSibling as HTMLElement; - if (successMessage?.classList.contains('copy-success-message')) { - successMessage.classList.remove('hidden'); - setTimeout(() => successMessage.classList.add('hidden'), 2000); - } -} - -/** - * Initialize copy code functionality - */ -export function initCodeCopy(): void { - document.querySelectorAll('.copy-code-btn').forEach((button) => { - if (button instanceof HTMLElement) { - button.removeEventListener('click', handleCopyClick); - button.addEventListener('click', handleCopyClick); - } - }); -} - -// Auto-initialize when available -if (typeof window !== 'undefined') { - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initCodeCopy); - } else { - initCodeCopy(); - } - - // Re-initialize for dynamic content - let timeoutId: number; - document.addEventListener('click', () => { - clearTimeout(timeoutId); - timeoutId = window.setTimeout(initCodeCopy, 100); - }); -} diff --git a/src/utils/more-utils.ts b/src/utils/more-utils.ts deleted file mode 100644 index e6d1dce0..00000000 --- a/src/utils/more-utils.ts +++ /dev/null @@ -1,108 +0,0 @@ -/** - * More page utility functions - * Optimized version using shared utilities - */ - -import { parseFrontmatter } from '@/utils/posts-utils'; - -export interface MorePage { - id: string; - title: string; - content: string; - slug: string; - editUrl?: string; - lastUpdated?: string; - lastUpdatedBy?: string; - category?: string; -} - -/** - * Convert frontmatter value to string - */ -const frontmatterToString = ( - value: string | string[] | undefined, - fallback = '', -): string => - Array.isArray(value) ? value.join(' ').trim() : value?.trim() || fallback; - -/** - * Fetch and parse all markdown files for more pages - */ -export const fetchMorePages = async (): Promise<MorePage[]> => { - try { - const markdownFiles = import.meta.glob( - '@/constants/MarkdownFiles/more/*.md', - { - query: '?raw', - import: 'default', - }, - ); - - const allPages: MorePage[] = []; - - for (const [filePath, importFn] of Object.entries(markdownFiles)) { - try { - const fileContent = await importFn(); - const { frontmatter, content } = parseFrontmatter( - fileContent as string, - ); - const fileName = filePath.split('/').pop()?.replace('.md', '') || ''; - - const page: MorePage = { - id: fileName, - title: frontmatterToString(frontmatter.title, 'Untitled'), - content, - slug: frontmatterToString(frontmatter.slug, fileName), - category: frontmatterToString(frontmatter.category, 'Uncategorized'), - }; - - allPages.push(page); - } catch (error) { - console.error(`Error processing ${filePath}:`, error); - } - } - - return allPages.sort((a, b) => a.title.localeCompare(b.title)); - } catch (error) { - console.error('Error fetching more pages:', error); - return []; - } -}; - -/** - * Get a single more page by its slug - */ -export const getMorePageBySlug = async ( - slug: string, -): Promise<MorePage | null> => { - const allPages = await fetchMorePages(); - return allPages.find((page) => page.slug === slug) || null; -}; - -/** - * Group more pages by categories - */ -export const getMorePagesByCategory = async (): Promise< - Record<string, MorePage[]> -> => { - const allPages = await fetchMorePages(); - const pagesByCategory: Record<string, MorePage[]> = { All: allPages }; - - allPages.forEach((page) => { - const category = page.category || 'Uncategorized'; - if (!pagesByCategory[category]) { - pagesByCategory[category] = []; - } - pagesByCategory[category].push(page); - }); - - return pagesByCategory; -}; - -/** - * Get default page slug (first page alphabetically) - */ -export const getDefaultMorePageSlug = async (): Promise<string | null> => { - const allPages = await fetchMorePages(); - return allPages.length > 0 ? allPages[0].slug : null; -}; diff --git a/src/utils/posts-utils.ts b/src/utils/posts-utils.ts deleted file mode 100644 index 0561117d..00000000 --- a/src/utils/posts-utils.ts +++ /dev/null @@ -1,209 +0,0 @@ -/** - * Blog post utility functions - Updated with author support - */ - -import { parseAuthorReference, AuthorReference } from '@/utils/author-utils'; - -export interface Post { - id: string; - title: string; - excerpt: string; - content: string; - category: string; - date: string; - slug: string; - author: AuthorReference | null; - tags: string[]; - image: string; -} - -/** - * Parse frontmatter from markdown content - */ -export const parseFrontmatter = ( - content: string, -): { - frontmatter: Record<string, string | string[]>; - content: string; -} => { - const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/; - const match = frontmatterRegex.exec(content); - - if (!match) return { frontmatter: {}, content }; - - const [, frontmatterString, mainContent] = match; - const frontmatter: Record<string, string | string[]> = {}; - - frontmatterString.split('\n').forEach((line) => { - const colonIndex = line.indexOf(':'); - if (colonIndex === -1) return; - - const key = line.slice(0, colonIndex).trim(); - let value = line.slice(colonIndex + 1).trim(); - - if ( - (value.startsWith('"') && value.endsWith('"')) || - (value.startsWith("'") && value.endsWith("'")) - ) { - value = value.slice(1, -1); - } - - frontmatter[key] = - key === 'tags' && value - ? value.split(',').map((tag) => tag.trim()) - : value; - }); - - return { frontmatter, content: mainContent }; -}; - -/** - * Convert frontmatter value to string with fallback - */ -const frontmatterToString = ( - value: string | string[] | undefined, - fallback = '', -): string => - Array.isArray(value) ? value.join(' ').trim() : value?.trim() || fallback; - -/** - * Process image URL with validation and fallback - */ -const processImageUrl = (imageValue: string | string[] | undefined): string => { - let imageUrl = frontmatterToString( - imageValue, - '/assets/Images/SugarNewsLogo.png', - ); - - if ( - imageUrl !== '/assets/Images/SugarNewsLogo.png' && - !/^https?:\/\//.test(imageUrl) - ) { - imageUrl = '/' + imageUrl.replace(/^\/+/, ''); - } - - return imageUrl; -}; - -/** - * Fetch and parse all markdown blog posts with author support - */ -export const fetchMarkdownPosts = async ( - category?: string, -): Promise<Post[]> => { - try { - const markdownFiles = import.meta.glob( - '@/constants/MarkdownFiles/posts/*.md', - { - query: '?raw', - import: 'default', - }, - ); - - const allPosts: Post[] = []; - - for (const [filePath, importFn] of Object.entries(markdownFiles)) { - try { - const fileContent = await importFn(); - const { frontmatter, content } = parseFrontmatter( - fileContent as string, - ); - const fileName = filePath.split('/').pop()?.replace('.md', '') || ''; - - // Parse author reference - const author = await parseAuthorReference( - frontmatterToString(frontmatter.author), - frontmatterToString(frontmatter.description), - ); - - const post: Post = { - id: fileName, - title: frontmatterToString(frontmatter.title, 'Untitled'), - excerpt: frontmatterToString(frontmatter.excerpt), - content, - category: frontmatterToString(frontmatter.category, 'UNCATEGORIZED'), - date: frontmatterToString(frontmatter.date, 'No date'), - slug: frontmatterToString(frontmatter.slug, fileName), - author, - tags: Array.isArray(frontmatter.tags) - ? frontmatter.tags - : frontmatter.tags - ? [frontmatter.tags] - : [], - image: processImageUrl(frontmatter.image), - }; - - allPosts.push(post); - } catch (error) { - console.error(`Error processing ${filePath}:`, error); - } - } - - const sortedPosts = allPosts.sort((a, b) => { - const dateA = new Date(a.date).getTime() || 0; - const dateB = new Date(b.date).getTime() || 0; - return dateB - dateA; - }); - - return category - ? sortedPosts.filter((post) => post.category === category) - : sortedPosts; - } catch (error) { - console.error('Error fetching markdown posts:', error); - return []; - } -}; - -/** - * Get posts by author slug - */ -export const getPostsByAuthor = async (authorSlug: string): Promise<Post[]> => { - const allPosts = await fetchMarkdownPosts(); - return allPosts.filter((post) => post.author?.slug === authorSlug); -}; - -/** - * Get posts by tag - */ -export const getPostsByTag = async (tag: string): Promise<Post[]> => { - const allPosts = await fetchMarkdownPosts(); - return allPosts.filter((post) => - post.tags.some((postTag) => postTag.toLowerCase() === tag.toLowerCase()), - ); -}; - -/** - * Get all unique tags from posts - */ -export const getAllTags = async (): Promise<string[]> => { - const allPosts = await fetchMarkdownPosts(); - const tagSet = new Set<string>(); - - allPosts.forEach((post) => { - post.tags.forEach((tag) => tagSet.add(tag)); - }); - - return Array.from(tagSet).sort(); -}; - -// ... rest of the existing functions remain the same -export const getPostBySlug = async (slug: string): Promise<Post | null> => { - const allPosts = await fetchMarkdownPosts(); - return allPosts.find((post) => post.slug === slug) || null; -}; - -export const getAllPosts = async (): Promise<Post[]> => fetchMarkdownPosts(); - -export const groupPostsByCategory = (posts: Post[]): Record<string, Post[]> => { - const categoryMap: Record<string, Post[]> = { All: posts }; - - posts.forEach((post) => { - const category = post.category || 'UNCATEGORIZED'; - if (!categoryMap[category]) { - categoryMap[category] = []; - } - categoryMap[category].push(post); - }); - - return categoryMap; -}; diff --git a/src/utils/renderlinks-utils.ts b/src/utils/renderlinks-utils.ts deleted file mode 100644 index 21ccd816..00000000 --- a/src/utils/renderlinks-utils.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Link rendering utility - Optimized version - * Handles text replacement with clickable links - */ - -interface Link { - text: string; - url: string; -} - -/** - * Replace link text with clickable links - * Optimized with better regex handling and null checks - */ -export const renderContentWithLinks = ( - text: string, - links: Link[] | null | undefined, -): string => { - if (!links?.length || !text) return text; - - // Sort links by text length (descending) to handle nested links correctly - const sortedLinks = [...links].sort((a, b) => b.text.length - a.text.length); - - // Replace each link text with clickable link - return sortedLinks.reduce((processedText, { text: linkText, url }) => { - // Escape special regex characters in link text - const escapedLinkText = linkText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - const linkRegex = new RegExp(escapedLinkText, 'g'); - - return processedText.replace( - linkRegex, - `<a href="${url}" target="_blank" rel="noopener noreferrer" class="text-blue-600 hover:underline">${linkText}</a>`, - ); - }, text); -}; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts deleted file mode 100644 index 11f02fe2..00000000 --- a/src/vite-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// <reference types="vite/client" /> diff --git a/tsconfig.app.json b/tsconfig.app.json deleted file mode 100644 index c74e1fea..00000000 --- a/tsconfig.app.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "isolatedModules": true, - "moduleDetection": "force", - "noEmit": true, - "jsx": "react-jsx", - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true, - - /* Path Aliases */ - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"] - } - }, - "include": ["src"] -} diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 1e173931..00000000 --- a/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "files": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.node.json" - } - ], - "compilerOptions": { - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"] - } - } -} diff --git a/tsconfig.node.json b/tsconfig.node.json deleted file mode 100644 index db0becc8..00000000 --- a/tsconfig.node.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - "target": "ES2022", - "lib": ["ES2023"], - "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "isolatedModules": true, - "moduleDetection": "force", - "noEmit": true, - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/vite.config.ts b/vite.config.ts deleted file mode 100644 index 9de1a58b..00000000 --- a/vite.config.ts +++ /dev/null @@ -1,45 +0,0 @@ -import path from 'path'; -import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; -import tailwindcss from '@tailwindcss/vite'; - -// https://vitejs.dev/config/ -export default defineConfig({ - base: './', - plugins: [react(), tailwindcss()], - resolve: { - alias: { - '@': path.resolve(__dirname, './src'), // Allows using "@" as an alias for "src" - }, - }, - build: { - rollupOptions: { - /** - * Ignore "use client" warning since we are not using SSR - */ - onwarn(warning, warn) { - if ( - warning.code === 'MODULE_LEVEL_DIRECTIVE' && - warning.message.includes(`"use client"`) - ) { - return; - } - warn(warning); - }, - output: { - manualChunks(id) { - if (id.includes('node_modules')) { - // Split vendor code into separate chunks - return 'vendor'; - } - if (id.includes('src/constants/MarkdownFiles')) { - // Split Markdown related pages into a separate chunk - return 'mdfiles'; - } - // Add more custom chunking logic as needed - }, - }, - }, - chunkSizeWarningLimit: 1000, // Increase the limit as needed - }, -});