[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_final_newline = true\ncharset = utf-8\ntrim_trailing_whitespace = true\n\n[*.json]\nindent_style = space\nindent_size = 2\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/add-new-function.md",
    "content": "---\nname: Add new JavaScript Function\nabout: Add new file for explaining a new JavaScript function\ntitle: 'New Function: '\nlabels: enhancement, hacktoberfest, good+first+issue\nassignees: ''\n\n---\n\n## What\nAdd new method documentation file for a new JavaScript function in `src/content/docs`.\nThe instructions about defining the file's name are documented in the `CONTRIBUTING.md` file.\n\n\n## Description\nFunction name: example `os.version()`\nFunction description: ...\nFile name: example `01-system/02_os-version.md`\n\n## Checklist\n- [ ] create the file with the proper name\n- [ ] create the documentation of the function\n- [ ] write example in `examples` directory\n- [ ] execute `bun run format-examples-bun` or `npm run format-examples`\n- [ ] commit and open the PR.\n\nMust read:\n\n- https://github.com/roberto-butti/some-drops-of-javascript/blob/main/HACKTOBERFEST.md\n- https://github.com/roberto-butti/some-drops-of-javascript/blob/main/CONTRIBUTING.md\n"
  },
  {
    "path": ".gitignore",
    "content": "# build output\ndist/\n# generated types\n.astro/\n\n# dependencies\nnode_modules/\npackage-lock.json\n\n# logs\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\n\n\n# environment variables\n.env\n.env.production\n\n# macOS-specific files\n.DS_Store\n.vscode/\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n    \"trailingComma\": \"es5\",\n    \"tabWidth\": 2,\n    \"useTabs\": false,\n    \"semi\": false,\n    \"singleQuote\": true\n}"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# How to contribute\n\nThe goal is to build an open-source book about JavaScript functions for new users in the JavaScript ecosystem.\nThis book collects some useful, unknown, underrated JavaScript functions or stuff discovered, used, and learned during JavaScript's daily use.\nUsing frameworks daily (like React, Vue, and Svelte), sometimes the perception of the power of the language and the basic functionalities provided by the JavaScript core could be lost. I see that usually, I used to look at the framework documentation or look for a package in Packagist for the system, array, and string functions instead of using some core functionalities provided by the language.\nThe goal is to cover more and more functions, so the goal is to create new pages, and each page covers 1 specific function.\n\nThe functions are grouped into topics:\n\n- System\n- Array\n- Variables and types\n- String\n- File\n- Extra bonus chapter where I'm collecting some nice cheatsheet\n\nEach function is explained with the description, and examples in markdown files in the `src/content/docs` directory.\n\n## The file name convention\nWe have all the Markdown files in the `src/content/docs` directory where you can find the folders for each topic (`00-intro`, `01-system`, `02-array`, etc.\nEach topic ( Intro, System, Array) has a specific folder with the format\n\n- 2 digits (00 , 01) as topic identifier (progressive number)\n- A \"dash\" separator `-`\n- A slug for the topic (intro, system, array)\n\nFollowing the format above you can have folders like: `00-intro`, `01-system`, `02-array`.\nEach folder contains files. Each file shows a JavaScript function.\nThe file name has the format:\n\n- 2 digits (00 , 01) as function identifier (progressive number);\n- An \"underscore\" separator `_`;\n- A subtopic slug (by default is the same of the topic), for example `system`, `os`, `process` etc;\n- A \"dash\" separator `-`;\n- A slug for the function (cpus, version, userinfo);\n- The extension (md or mdx).\n\nFollowing the format described above, you can have in the folder `01-system` files with names like `01_os-cpus.md`, `02_os-version.md` etc\n\nFor example, for the file `01-system/02_os-version.md`:\n- `01`: (the first group of digits) is the progressive number for the `system` topic;\n- `system`: is the slug of the topic;\n- `02`: is the progress number for functions\n- `os`: the subtopic slug (os is for the operating system)\n- `version`: the function explained\n- `md`: the extension\n\n## Running locally the project\nThe rendering part of all the Markdown files is managed via Astro3 + Starlight theme and Bun.\nIf you want to read and browse the HTML eBook and see your changes in realtime when you are working on markdown files in the root directory of the cloned repository (where you have the `package.json`, `bun.lockb` files):\n\n- install the packages via `bun install`;\n- run the local server via `bun run dev`\n\nIf you want to build the HTML files, you can run the following command:\n~~~\nbun run build\n~~~\n\nIf you want to see the preview of the built files you can run the following command:\n\n~~~\nbun run preview\n~~~\n\n## Submit ideas or feature requests\n\n* Take a look if your request is already there https://github.com/roberto-butti/some-drops-of-javascript/issues\n* If it is not present, you can create a new one https://github.com/roberto-butti/some-drops-of-javascript/issues/new\n\n## Submit your changes\n\nIf you want to submit a pull request, please send a [GitHub Pull Request to Some drops of JavaScript](https://github.com/roberto-butti/some-drops-of-javascript/pull/new/main) with a clear list of what you've done (read more about [pull requests](https://help.github.com/articles/about-pull-requests)).\n\n\nPlease use \"main\" branch for pull request.\n\n## Instructions for writing a markdown file for a JavaScript Function\n\nEach chapter in this book focuses on a single JavaScript function or method. The goal is to provide comprehensive, well-structured, and practical documentation that helps developers understand and use the function effectively. Follow the guidelines below to structure your chapter.\n\n### Chapter Structure\n\n1. Frontmatter (Mandatory)\n\nThe frontmatter section should be placed at the beginning of the markdown file and enclosed between triple dashes (---). It provides essential metadata about the chapter.\n\nExample for mandatory fields:\n```\n---\ntitle: 'Modifying an Array'\ndescription: 'Adding, removing, and replacing elements in an array with JavaScript.'\nsidebar:\n  label: Modifying Array\n---\n```\nWhere:\n- `title`: The feature implemented via the function\n- `description`: A brief overview of what the function does.\n- `sidebar.label`: the label used in the left menu\n\n2. Introduction\n\nStart with a clear and concise explanation of what the function does. Highlight its primary use cases and why it's useful.\n\n3. Syntax and Parameters\n\n- Provide the general syntax of the function, including its parameters and their expected types.\n- Describe each parameter in detail, including whether it is optional or required and what its role is.\n- Include the return type of the funtion\n\n4. Use cases\n\nProvide several practical use cases demonstrating how the function can be used to solve real-world problems.\n\nEach use case should include a clear explanation of the problem being solved, a code example, and a detailed breakdown of how the function is being used.\n\n5. Common Pitfalls\n\n- Discuss common mistakes or misunderstandings related to the function.\n- Provide guidance on how to avoid these issues.\n\n6. Additional Resources\n\nInclude links to relevant documentation, tutorials, or other chapters in the book for further reading.\n"
  },
  {
    "path": "HACKTOBERFEST.md",
    "content": "# Hacktoberfest and \"Some drops of JavaScript\"\n\n![Some drops of JavaScript and Hacktoberfest 2024](public/header-hacktoberfest-2024.png)\n\nHello amazing contributors! 👋\n\nWe are excited to invite you to join our Hacktoberfest celebration by contributing to our open-source book project. We welcome contributors with various skills and interests, so whether you're a JavaScript expert, a grammar enthusiast, a design aficionado, or just someone with a passion for learning and sharing knowledge, there's a place for you in our community.\n\n## Ways to Contribute\n\nHere are some of the ways you can get involved:\n\n- **JavaScript Wizards**: Write pages for JavaScript functions, share your expertise, and help fellow developers understand some nice JavaScript functions.\n\n- **Reviewers and Editors**: Help ensure the quality and accuracy of the content by reviewing and editing pages.\n\n- **Grammar Enthusiasts**: Review and improve the English grammar and readability of our documentation.\n\n- **Idea Contributors**: Suggest JavaScript functions that should be covered in the documentation. Your insights are valuable!\n\n- **Design Gurus**: Propose design changes that can enhance the overall user experience of our book.\n\n## How to Get Started\n\n1. Fork the repository to your GitHub account.\n2. Create a new branch for your contributions.\n3. Make your changes and commit them.\n4. Open a pull request to merge your changes back into the main repository.\n\nFor more detailed instructions, please check our [Contribution Guidelines](CONTRIBUTING.md).\n\n## Join the Conversation\n\nHave questions or want to discuss your contributions? Join us on the [repository issue section](https://github.com/roberto-butti/some-drops-of-javascript/issues), where you can create issues but also create suggestions, feature requests.\n\n## Say Thank You!\n\nWe deeply appreciate your willingness to contribute to the open-source book \"Some drops of JavaScript\". Your efforts make a significant impact on the JavaScript community, and we're grateful for your support.\n\nHappy Hacking! 🚀\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "Attribution-NonCommercial-ShareAlike 4.0 International\n\n=======================================================================\n\nCreative Commons Corporation (\"Creative Commons\") is not a law firm and\ndoes not provide legal services or legal advice. Distribution of\nCreative Commons public licenses does not create a lawyer-client or\nother relationship. Creative Commons makes its licenses and related\ninformation available on an \"as-is\" basis. Creative Commons gives no\nwarranties regarding its licenses, any material licensed under their\nterms and conditions, or any related information. Creative Commons\ndisclaims all liability for damages resulting from their use to the\nfullest extent possible.\n\nUsing Creative Commons Public Licenses\n\nCreative Commons public licenses provide a standard set of terms and\nconditions that creators and other rights holders may use to share\noriginal works of authorship and other material subject to copyright\nand certain other rights specified in the public license below. The\nfollowing considerations are for informational purposes only, are not\nexhaustive, and do not form part of our licenses.\n\n     Considerations for licensors: Our public licenses are\n     intended for use by those authorized to give the public\n     permission to use material in ways otherwise restricted by\n     copyright and certain other rights. Our licenses are\n     irrevocable. Licensors should read and understand the terms\n     and conditions of the license they choose before applying it.\n     Licensors should also secure all rights necessary before\n     applying our licenses so that the public can reuse the\n     material as expected. Licensors should clearly mark any\n     material not subject to the license. This includes other CC-\n     licensed material, or material used under an exception or\n     limitation to copyright. More considerations for licensors:\n    wiki.creativecommons.org/Considerations_for_licensors\n\n     Considerations for the public: By using one of our public\n     licenses, a licensor grants the public permission to use the\n     licensed material under specified terms and conditions. If\n     the licensor's permission is not necessary for any reason--for\n     example, because of any applicable exception or limitation to\n     copyright--then that use is not regulated by the license. Our\n     licenses grant only permissions under copyright and certain\n     other rights that a licensor has authority to grant. Use of\n     the licensed material may still be restricted for other\n     reasons, including because others have copyright or other\n     rights in the material. A licensor may make special requests,\n     such as asking that all changes be marked or described.\n     Although not required by our licenses, you are encouraged to\n     respect those requests where reasonable. More considerations\n     for the public:\n    wiki.creativecommons.org/Considerations_for_licensees\n\n=======================================================================\n\nCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International\nPublic License\n\nBy exercising the Licensed Rights (defined below), You accept and agree\nto be bound by the terms and conditions of this Creative Commons\nAttribution-NonCommercial-ShareAlike 4.0 International Public License\n(\"Public License\"). To the extent this Public License may be\ninterpreted as a contract, You are granted the Licensed Rights in\nconsideration of Your acceptance of these terms and conditions, and the\nLicensor grants You such rights in consideration of benefits the\nLicensor receives from making the Licensed Material available under\nthese terms and conditions.\n\n\nSection 1 -- Definitions.\n\n  a. Adapted Material means material subject to Copyright and Similar\n     Rights that is derived from or based upon the Licensed Material\n     and in which the Licensed Material is translated, altered,\n     arranged, transformed, or otherwise modified in a manner requiring\n     permission under the Copyright and Similar Rights held by the\n     Licensor. For purposes of this Public License, where the Licensed\n     Material is a musical work, performance, or sound recording,\n     Adapted Material is always produced where the Licensed Material is\n     synched in timed relation with a moving image.\n\n  b. Adapter's License means the license You apply to Your Copyright\n     and Similar Rights in Your contributions to Adapted Material in\n     accordance with the terms and conditions of this Public License.\n\n  c. BY-NC-SA Compatible License means a license listed at\n     creativecommons.org/compatiblelicenses, approved by Creative\n     Commons as essentially the equivalent of this Public License.\n\n  d. Copyright and Similar Rights means copyright and/or similar rights\n     closely related to copyright including, without limitation,\n     performance, broadcast, sound recording, and Sui Generis Database\n     Rights, without regard to how the rights are labeled or\n     categorized. For purposes of this Public License, the rights\n     specified in Section 2(b)(1)-(2) are not Copyright and Similar\n     Rights.\n\n  e. Effective Technological Measures means those measures that, in the\n     absence of proper authority, may not be circumvented under laws\n     fulfilling obligations under Article 11 of the WIPO Copyright\n     Treaty adopted on December 20, 1996, and/or similar international\n     agreements.\n\n  f. Exceptions and Limitations means fair use, fair dealing, and/or\n     any other exception or limitation to Copyright and Similar Rights\n     that applies to Your use of the Licensed Material.\n\n  g. License Elements means the license attributes listed in the name\n     of a Creative Commons Public License. The License Elements of this\n     Public License are Attribution, NonCommercial, and ShareAlike.\n\n  h. Licensed Material means the artistic or literary work, database,\n     or other material to which the Licensor applied this Public\n     License.\n\n  i. Licensed Rights means the rights granted to You subject to the\n     terms and conditions of this Public License, which are limited to\n     all Copyright and Similar Rights that apply to Your use of the\n     Licensed Material and that the Licensor has authority to license.\n\n  j. Licensor means the individual(s) or entity(ies) granting rights\n     under this Public License.\n\n  k. NonCommercial means not primarily intended for or directed towards\n     commercial advantage or monetary compensation. For purposes of\n     this Public License, the exchange of the Licensed Material for\n     other material subject to Copyright and Similar Rights by digital\n     file-sharing or similar means is NonCommercial provided there is\n     no payment of monetary compensation in connection with the\n     exchange.\n\n  l. Share means to provide material to the public by any means or\n     process that requires permission under the Licensed Rights, such\n     as reproduction, public display, public performance, distribution,\n     dissemination, communication, or importation, and to make material\n     available to the public including in ways that members of the\n     public may access the material from a place and at a time\n     individually chosen by them.\n\n  m. Sui Generis Database Rights means rights other than copyright\n     resulting from Directive 96/9/EC of the European Parliament and of\n     the Council of 11 March 1996 on the legal protection of databases,\n     as amended and/or succeeded, as well as other essentially\n     equivalent rights anywhere in the world.\n\n  n. You means the individual or entity exercising the Licensed Rights\n     under this Public License. Your has a corresponding meaning.\n\n\nSection 2 -- Scope.\n\n  a. License grant.\n\n       1. Subject to the terms and conditions of this Public License,\n          the Licensor hereby grants You a worldwide, royalty-free,\n          non-sublicensable, non-exclusive, irrevocable license to\n          exercise the Licensed Rights in the Licensed Material to:\n\n            a. reproduce and Share the Licensed Material, in whole or\n               in part, for NonCommercial purposes only; and\n\n            b. produce, reproduce, and Share Adapted Material for\n               NonCommercial purposes only.\n\n       2. Exceptions and Limitations. For the avoidance of doubt, where\n          Exceptions and Limitations apply to Your use, this Public\n          License does not apply, and You do not need to comply with\n          its terms and conditions.\n\n       3. Term. The term of this Public License is specified in Section\n          6(a).\n\n       4. Media and formats; technical modifications allowed. The\n          Licensor authorizes You to exercise the Licensed Rights in\n          all media and formats whether now known or hereafter created,\n          and to make technical modifications necessary to do so. The\n          Licensor waives and/or agrees not to assert any right or\n          authority to forbid You from making technical modifications\n          necessary to exercise the Licensed Rights, including\n          technical modifications necessary to circumvent Effective\n          Technological Measures. For purposes of this Public License,\n          simply making modifications authorized by this Section 2(a)\n          (4) never produces Adapted Material.\n\n       5. Downstream recipients.\n\n            a. Offer from the Licensor -- Licensed Material. Every\n               recipient of the Licensed Material automatically\n               receives an offer from the Licensor to exercise the\n               Licensed Rights under the terms and conditions of this\n               Public License.\n\n            b. Additional offer from the Licensor -- Adapted Material.\n               Every recipient of Adapted Material from You\n               automatically receives an offer from the Licensor to\n               exercise the Licensed Rights in the Adapted Material\n               under the conditions of the Adapter's License You apply.\n\n            c. No downstream restrictions. You may not offer or impose\n               any additional or different terms or conditions on, or\n               apply any Effective Technological Measures to, the\n               Licensed Material if doing so restricts exercise of the\n               Licensed Rights by any recipient of the Licensed\n               Material.\n\n       6. No endorsement. Nothing in this Public License constitutes or\n          may be construed as permission to assert or imply that You\n          are, or that Your use of the Licensed Material is, connected\n          with, or sponsored, endorsed, or granted official status by,\n          the Licensor or others designated to receive attribution as\n          provided in Section 3(a)(1)(A)(i).\n\n  b. Other rights.\n\n       1. Moral rights, such as the right of integrity, are not\n          licensed under this Public License, nor are publicity,\n          privacy, and/or other similar personality rights; however, to\n          the extent possible, the Licensor waives and/or agrees not to\n          assert any such rights held by the Licensor to the limited\n          extent necessary to allow You to exercise the Licensed\n          Rights, but not otherwise.\n\n       2. Patent and trademark rights are not licensed under this\n          Public License.\n\n       3. To the extent possible, the Licensor waives any right to\n          collect royalties from You for the exercise of the Licensed\n          Rights, whether directly or through a collecting society\n          under any voluntary or waivable statutory or compulsory\n          licensing scheme. In all other cases the Licensor expressly\n          reserves any right to collect such royalties, including when\n          the Licensed Material is used other than for NonCommercial\n          purposes.\n\n\nSection 3 -- License Conditions.\n\nYour exercise of the Licensed Rights is expressly made subject to the\nfollowing conditions.\n\n  a. Attribution.\n\n       1. If You Share the Licensed Material (including in modified\n          form), You must:\n\n            a. retain the following if it is supplied by the Licensor\n               with the Licensed Material:\n\n                 i. identification of the creator(s) of the Licensed\n                    Material and any others designated to receive\n                    attribution, in any reasonable manner requested by\n                    the Licensor (including by pseudonym if\n                    designated);\n\n                ii. a copyright notice;\n\n               iii. a notice that refers to this Public License;\n\n                iv. a notice that refers to the disclaimer of\n                    warranties;\n\n                 v. a URI or hyperlink to the Licensed Material to the\n                    extent reasonably practicable;\n\n            b. indicate if You modified the Licensed Material and\n               retain an indication of any previous modifications; and\n\n            c. indicate the Licensed Material is licensed under this\n               Public License, and include the text of, or the URI or\n               hyperlink to, this Public License.\n\n       2. You may satisfy the conditions in Section 3(a)(1) in any\n          reasonable manner based on the medium, means, and context in\n          which You Share the Licensed Material. For example, it may be\n          reasonable to satisfy the conditions by providing a URI or\n          hyperlink to a resource that includes the required\n          information.\n       3. If requested by the Licensor, You must remove any of the\n          information required by Section 3(a)(1)(A) to the extent\n          reasonably practicable.\n\n  b. ShareAlike.\n\n     In addition to the conditions in Section 3(a), if You Share\n     Adapted Material You produce, the following conditions also apply.\n\n       1. The Adapter's License You apply must be a Creative Commons\n          license with the same License Elements, this version or\n          later, or a BY-NC-SA Compatible License.\n\n       2. You must include the text of, or the URI or hyperlink to, the\n          Adapter's License You apply. You may satisfy this condition\n          in any reasonable manner based on the medium, means, and\n          context in which You Share Adapted Material.\n\n       3. You may not offer or impose any additional or different terms\n          or conditions on, or apply any Effective Technological\n          Measures to, Adapted Material that restrict exercise of the\n          rights granted under the Adapter's License You apply.\n\n\nSection 4 -- Sui Generis Database Rights.\n\nWhere the Licensed Rights include Sui Generis Database Rights that\napply to Your use of the Licensed Material:\n\n  a. for the avoidance of doubt, Section 2(a)(1) grants You the right\n     to extract, reuse, reproduce, and Share all or a substantial\n     portion of the contents of the database for NonCommercial purposes\n     only;\n\n  b. if You include all or a substantial portion of the database\n     contents in a database in which You have Sui Generis Database\n     Rights, then the database in which You have Sui Generis Database\n     Rights (but not its individual contents) is Adapted Material,\n     including for purposes of Section 3(b); and\n\n  c. You must comply with the conditions in Section 3(a) if You Share\n     all or a substantial portion of the contents of the database.\n\nFor the avoidance of doubt, this Section 4 supplements and does not\nreplace Your obligations under this Public License where the Licensed\nRights include other Copyright and Similar Rights.\n\n\nSection 5 -- Disclaimer of Warranties and Limitation of Liability.\n\n  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE\n     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS\n     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF\n     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,\n     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,\n     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR\n     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,\n     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT\n     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT\n     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.\n\n  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE\n     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,\n     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,\n     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,\n     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR\n     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN\n     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR\n     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR\n     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.\n\n  c. The disclaimer of warranties and limitation of liability provided\n     above shall be interpreted in a manner that, to the extent\n     possible, most closely approximates an absolute disclaimer and\n     waiver of all liability.\n\n\nSection 6 -- Term and Termination.\n\n  a. This Public License applies for the term of the Copyright and\n     Similar Rights licensed here. However, if You fail to comply with\n     this Public License, then Your rights under this Public License\n     terminate automatically.\n\n  b. Where Your right to use the Licensed Material has terminated under\n     Section 6(a), it reinstates:\n\n       1. automatically as of the date the violation is cured, provided\n          it is cured within 30 days of Your discovery of the\n          violation; or\n\n       2. upon express reinstatement by the Licensor.\n\n     For the avoidance of doubt, this Section 6(b) does not affect any\n     right the Licensor may have to seek remedies for Your violations\n     of this Public License.\n\n  c. For the avoidance of doubt, the Licensor may also offer the\n     Licensed Material under separate terms or conditions or stop\n     distributing the Licensed Material at any time; however, doing so\n     will not terminate this Public License.\n\n  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public\n     License.\n\n\nSection 7 -- Other Terms and Conditions.\n\n  a. The Licensor shall not be bound by any additional or different\n     terms or conditions communicated by You unless expressly agreed.\n\n  b. Any arrangements, understandings, or agreements regarding the\n     Licensed Material not stated herein are separate from and\n     independent of the terms and conditions of this Public License.\n\n\nSection 8 -- Interpretation.\n\n  a. For the avoidance of doubt, this Public License does not, and\n     shall not be interpreted to, reduce, limit, restrict, or impose\n     conditions on any use of the Licensed Material that could lawfully\n     be made without permission under this Public License.\n\n  b. To the extent possible, if any provision of this Public License is\n     deemed unenforceable, it shall be automatically reformed to the\n     minimum extent necessary to make it enforceable. If the provision\n     cannot be reformed, it shall be severed from this Public License\n     without affecting the enforceability of the remaining terms and\n     conditions.\n\n  c. No term or condition of this Public License will be waived and no\n     failure to comply consented to unless expressly agreed to by the\n     Licensor.\n\n  d. Nothing in this Public License constitutes or may be interpreted\n     as a limitation upon, or waiver of, any privileges and immunities\n     that apply to the Licensor or You, including from the legal\n     processes of any jurisdiction or authority.\n\n=======================================================================\n\nCreative Commons is not a party to its public\nlicenses. Notwithstanding, Creative Commons may elect to apply one of\nits public licenses to material it publishes and in those instances\nwill be considered the “Licensor.” The text of the Creative Commons\npublic licenses is dedicated to the public domain under the CC0 Public\nDomain Dedication. Except for the limited purpose of indicating that\nmaterial is shared under a Creative Commons public license or as\notherwise permitted by the Creative Commons policies published at\ncreativecommons.org/policies, Creative Commons does not authorize the\nuse of the trademark \"Creative Commons\" or any other trademark or logo\nof Creative Commons without its prior written consent including,\nwithout limitation, in connection with any unauthorized modifications\nto any of its public licenses or any other arrangements,\nunderstandings, or agreements concerning use of licensed material. For\nthe avoidance of doubt, this paragraph does not form part of the\npublic licenses.\n\nCreative Commons may be contacted at creativecommons.org."
  },
  {
    "path": "README.md",
    "content": "# Welcome to Some drops of JavaScript\n\n\n![Some drops of JavaScript](public/header.png)\n\n## The reason why\nThis book collects some useful, unknown, underrated JavaScript functions or stuff discovered, used, and learned during JavaScript daily use.\n\nUsing JavaScript frameworks/libraries daily (like React, Vue, Angular), sometimes the perception of the power of the language and the basic functionalities provided by the JavaScript core could be lost.\nI see that usually, I used to look at the framework documentation or look for a package in Npm for the system, array, and string functions instead of using core functionalities provided by the language.\n\nWhile I wrote this  HTML-book, I also wrote some scripts to better understand the behavior of the functions. You can find these examples here: https://github.com/roberto-butti/some-drops-of-javascript in the _examples_ directory.\n\n> We are excited to invite you to join our Hacktoberfest celebration by contributing to the open-source book project. More [info here](HACKTOBERFEST.md)\n\n### Requirements\n\nThe code used in this book is tested with **Bun** and **NodeJs version 18 (LTS)**.\n\n**Bun** is a JavaScript runtime, package manager, bundler and test runner built from scratch using the Zig programming language. It was designed by Jarred Sumner as a drop-in replacement for Node.js. Bun uses JavaScriptCore as the JavaScript engine, unlike Node.js and Deno, which both use V8. The official website is: https://bun.sh/ .\n\n**Node.js** is an open-source, cross-platform JavaScript runtime environment, and you can obtain Node.js on the official https://nodejs.org/ website.\n\n\n### Continuous release\n\nI was thinking to print this book, but I think that is not so eco-friendly and a book about development could be improved daily in terms of spellchecking and the content and examples. So, I expect to adopt the same approach in the software with the CI/CD, with a continuous release of the book.\n\nReleases:\n\n- **W.I.P.** the 1.0.0 version is not yet released: writing... ;\n\n> The book is **Work in Progress**, the list of the functions covered by the book at the moment are listed in [list-of-functions.md](list-of-functions.md) file\n\nSo, if you have any feedback, or you want to suggest some corrections, feel free to open an issue here: https://github.com/roberto-butti/some-drops-of-javascript/issues\n\n### Where to find this book\n\nThis book is available TBD.\n\n- Markdown files: [content/](content/);\n- Example files: [examples/](examples/);\n\n### Thanks to...\n\nThanks to all the Open Source community.\n\n### License\n\"Some drops of JavaScript\" (c) by Roberto Butti\n\n\"Some drops of JavaScript\" is licensed under a\nCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.\n\nYou should have received a copy of the license along with this\nwork. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.\n"
  },
  {
    "path": "astro.config.mjs",
    "content": "import { defineConfig } from 'astro/config';\nimport starlight from '@astrojs/starlight';\nimport tailwind from '@astrojs/tailwind'\n\n\n// https://astro.build/config\nexport default defineConfig({\n  site: 'https://drops-of-javascript.hi-folks.dev/',\n  integrations: [\n    starlight({\n      title: 'Some drops of JavaScript',\n      customCss: ['./src/styles/tailwind.css', './src/styles/custom.css'],\n      head: [\n        {\n          tag: 'meta',\n          attrs: {\n            property: 'og:image',\n            content:\n              'https://raw.githubusercontent.com/roberto-butti/some-drops-of-javascript/main/public/header.png',\n          },\n        },\n        {\n          tag: 'meta',\n          attrs: {\n            property: 'twitter:image',\n            content:\n              'https://raw.githubusercontent.com/roberto-butti/some-drops-of-javascript/main/public/header.png',\n          },\n        },\n      ],\n      editLink: {\n        baseUrl:\n          'https://github.com/roberto-butti/some-drops-of-javascript/edit/main',\n      },\n      social: {\n        github: 'https://github.com/roberto-butti/some-drops-of-javascript',\n      },\n      sidebar: [\n        {\n          label: '📔 Intro',\n          autogenerate: { directory: '00-intro' },\n          collapsed: false,\n        },\n        {\n          label: '🧑‍💻 System',\n          autogenerate: { directory: '01-system' },\n          collapsed: true,\n        },\n        {\n          label: '📚 Array',\n          autogenerate: { directory: '02-array' },\n          collapsed: true,\n        },\n        {\n          label: '🧑‍🎨 Vars, Objects, Operators',\n          autogenerate: { directory: '03-var' },\n          collapsed: true,\n        },\n        {\n          label: '💫 Functions',\n          autogenerate: { directory: '04-functions' },\n          collapsed: true,\n        },\n        {\n          label: '🪕 Strings',\n          autogenerate: { directory: '05-string' },\n          collapsed: true,\n        },\n        {\n          label: '🗃️ Files',\n          autogenerate: { directory: '06-files' },\n          collapsed: true,\n        },\n        {\n          label: '[ 🧑‍💻 Sources ]',\n          items: [\n            // Each item here is one entry in the navigation menu.\n            {\n              label: 'Markdown',\n              link: 'https://github.com/roberto-butti/some-drops-of-javascript/tree/main/src/content/docs',\n            },\n            {\n              label: 'Examples',\n              link: 'https://github.com/roberto-butti/some-drops-of-javascript/tree/main/examples',\n            },\n          ],\n          collapsed: true,\n        },\n      ],\n    }),\n    tailwind({\n      // Disable the default base styles:\n      applyBaseStyles: false,\n    }),\n  ],\n})\n"
  },
  {
    "path": "examples/01-01_os-cpus.mjs",
    "content": "import { cpus } from 'os'\n\n// getting the CPUs via os.cpus() and looping\ncpus().forEach((cpu, index) => {\n  // each cpu item has: mode, speed and times\n  console.log(`CPU ${index + 1}:`)\n  console.log(` Model: ${cpu.model}`)\n  console.log(` Speed: ${cpu.speed} MHz`)\n  console.log(` Time (milliseconds) spent in`)\n  console.log(`  User mode      : ${cpu.times.user} ms.`)\n  console.log(`  Nice mode      : ${cpu.times.nice} ms.`)\n  console.log(`  System mode    : ${cpu.times.sys} ms.`)\n  console.log(`  For interrupts : ${cpu.times.irq} ms.`)\n})\n\nconsole.log('*** Calculating the CPU utilization ***')\ncpus().forEach((cpu, index) => {\n  const { user, nice, sys, idle, irq } = cpu.times\n  const total = user + nice + sys + idle + irq\n\n  const usage = ((total - idle) / total) * 100\n  console.log(`CPU ${index + 1} Usage: ${usage.toFixed(2)}%`)\n})\n\nconsole.log('*** Identifying the Number of Logical CPU Cores ***')\nconst numCpus = cpus().length\nconsole.log(`Number of logical CPU cores: ${numCpus}`)\n"
  },
  {
    "path": "examples/01-02_os-version.mjs",
    "content": "import { version, platform, release, machine } from 'os'\nconst v = version()\nconsole.log(`Version: ${v}`)\n// Example\n// Version: Darwin Kernel Version 22.5.0: Thu Jun  8 22:22:20 PDT 2023; root:xnu-8796.121.3~7/RELEASE_ARM64_T6000\nconst p = platform()\nconsole.log(`Platform: ${p}`)\n// Example\n// Platform: darwin\nconst r = release()\nconsole.log(`Release: ${r}`)\n// Example\n// Release: 22.5.0\nconst m = machine()\nconsole.log(`Machine: ${m}`)\n// Example\n// Machine: arm64\n"
  },
  {
    "path": "examples/01-03_os-userinfo.mjs",
    "content": "import { userInfo } from 'os'\nconst u = userInfo()\nconsole.log('Hi, %s here your infos:', u.username)\nconsole.table(u)\n/*\n┌──────────┬──────────────────┐\n│ (index)  │      Values      │\n├──────────┼──────────────────┤\n│   uid    │       501        │\n│   gid    │        20        │\n│ username │    'roberto'     │\n│ homedir  │ '/Users/roberto' │\n│  shell   │    '/bin/zsh'    │\n└──────────┴──────────────────┘\n*/\n"
  },
  {
    "path": "examples/01-04_os-freemem.mjs",
    "content": "import { freemem } from 'os'\nconst m = freemem()\nconsole.log('Hi, the free memory is %d bytes', m)\nconsole.log('Hi, the free memory is %d kilobytes', m / 1024)\nconsole.log('Hi, the free memory is %d megabytes', m / 1024 / 1024)\n"
  },
  {
    "path": "examples/01-05_process-env.mjs",
    "content": "console.log(process.env)\nconsole.log(process.env.PATH)\nconst envVarName = 'PATH'\nif (envVarName in process.env) {\n  console.log(process.env[envVarName])\n} else {\n  console.log('no %s defined', envVarName)\n}\n\nObject.keys(process.env).forEach(function (key, index) {\n  console.log(key, index, process.env[key])\n})\n"
  },
  {
    "path": "examples/01-06_os-totalmem.mjs",
    "content": "import { totalmem } from 'os'\nconst m = totalmem()\nconsole.log('Hi, the total memory is %d bytes', m)\nconsole.log('Hi, the total memory is %d kilobytes', m / 1024)\nconsole.log('Hi, the total memory is %d megabytes', m / 1024 / 1024)\nconsole.log('Hi, the total memory is %d gigabytes', m / 1024 / 1024 / 1024)\n"
  },
  {
    "path": "examples/01-07_os-loadavg.mjs",
    "content": "import { loadavg } from 'os'\nconst la = loadavg()\nconsole.log(la[0], la[1], la[2])\n"
  },
  {
    "path": "examples/01-08_os-networkinterfaces.mjs",
    "content": "import { networkInterfaces } from 'os'\nconst ni = networkInterfaces()\n\nObject.keys(ni).forEach(function (key, index) {\n  // each interfaces has an array\n  ni[key].forEach(function (element, index) {\n    // selecting only family === 4 (ipv4 interfaces)\n    if (element.family === 4) {\n      console.log('IP ADDRESS: ' + element.address) // IP address\n    }\n  })\n  // console.log(key, index, ni[key])\n})\n"
  },
  {
    "path": "examples/01-09_process-exit.mjs",
    "content": "console.log('Executing ...')\nprocess.exit(99)\nconsole.log('Never executed')\n"
  },
  {
    "path": "examples/01-10_os-tmpdir.mjs",
    "content": "import { tmpdir } from 'os'\n\nconsole.log('Temporary directory: %s', tmpdir())\n"
  },
  {
    "path": "examples/01-11_performance-now.mjs",
    "content": "let startTime = performance.now()\nconsole.log('Starting')\nconsole.log(performance.now() - startTime, startTime)\nstartTime = performance.now()\nconsole.log('Again')\nconsole.log(performance.now() - startTime, startTime)\nstartTime = performance.now()\nconsole.log('Again and again')\nconsole.log(performance.now() - startTime, startTime)\n"
  },
  {
    "path": "examples/02-01_array-join.mjs",
    "content": "const elements = ['🥝', '🍓', '🍋']\n\nconsole.log(elements.join())\n// expected output: \"🥝,🍓,🍋\"\nconsole.log(elements.join('-'))\n// expected output: \"🥝-🍓-🍋\"\n"
  },
  {
    "path": "examples/02-02_array-includes.mjs",
    "content": "const elements = ['🥝', '🍓', '🍋']\n\nconsole.log(elements.includes('🍓'))\n// Does the array include the 🍓?\n// expected output: true\nconsole.log(elements.includes('🍓', 2))\n// Does the array (from index 2) include the 🍓?\n// expected output: false\nconsole.log(elements.includes('🍋', 2))\n// Does the array (from index 2) include the 🍋?\n// expected output: true\nconsole.log(elements.includes('🧃'))\n// Does the array include the 🧃?\n// expected output: false\n"
  },
  {
    "path": "examples/02-03_array-in.mjs",
    "content": "const fruits = {\n  strawberry: 'Strawberry',\n  kiwi: 'Kiwi',\n  lemon: 'Lemon',\n}\n\nconsole.table(fruits)\nif ('kiwi' in fruits) {\n  console.log('Kiwi is present')\n}\n\nconsole.log('kiwi' in fruits ? 'Yes! Kiwi' : 'ther is no kiwi here')\n\n// checking if the attribute is not defined can fails in this specific case:\nfruits.something = undefined\nif (fruits.somethingelse === undefined) {\n  console.log('Somethingelse attribute does not exist')\n}\nif (fruits.something === undefined) {\n  console.log('Something attribute exists but the value is undefined')\n}\n\nconst fruitsObject = {}\nfruitsObject.strawberry = 'Strawberry'\nfruitsObject.kiwi = 'Kiwi'\nfruitsObject.lemon = 'Lemon'\nconsole.dir(fruitsObject)\nconsole.log('kiwi' in fruitsObject) // true\nconsole.log('something' in fruitsObject) // false\n\nconst fruitsArray = []\nfruitsArray.push('Strawberry')\nfruitsArray.push('Kiwi')\nfruitsArray.push('Lemon')\nconsole.dir(fruitsArray)\nconsole.log(2 in fruitsArray) // true\nconsole.log(3 in fruitsArray) // false\n"
  },
  {
    "path": "examples/02-04_array-concat.mjs",
    "content": "const array1 = ['a', 'b', 'c']\nconst array2 = ['d', 'e', 'f']\nconsole.dir(array1.concat(array2))\n\nconst array3 = ['g', 'h']\nconsole.dir(array1.concat(array2, array3))\n//\nconsole.dir([].concat(array1, array2, array3))\nconsole.dir(array1 + array2 + array3)\n"
  },
  {
    "path": "examples/02-05_array-merge_destructuring.mjs",
    "content": "const array1 = ['a', 'b', 'c']\nconst array2 = ['d', 'e', 'f']\nconsole.dir([...array1, ...array2])\n// [ 'a', 'b', 'c', 'd', 'e', 'f' ]\n\nconst array3 = ['g', 'h']\nconsole.dir([...array1, ...array2, ...array3])\nconsole.dir([...array3, ...array2, ...array1])\n"
  },
  {
    "path": "examples/02-06_array-set.mjs",
    "content": "const array = ['a', 'b', 'c', 'b', 'd', 'e', 'a']\nconst unique = [...new Set(array)]\nconsole.dir(unique)\n"
  },
  {
    "path": "examples/02-07_array-fill.mjs",
    "content": "const array = ['a', 'b', 'c', 'b', 'd', 'e', 'a']\narray.fill(0)\nconsole.dir(array)\n// [ 0, 0, 0, 0, 0, 0, 0 ]\n\nconst array2 = ['a', 'b', 'c', 'b', 'd', 'e', 'a']\narray2.fill(0, 1)\nconsole.dir(array2)\n// [ 'a', 0, 0, 0, 0, 0, 0 ]\n\nconst array3 = ['a', 'b', 'c', 'b', 'd', 'e', 'a']\narray3.fill(0, 1, 3)\nconsole.dir(array3)\n// [ 'a', 0, 0, 'b', 'd', 'e', 'a' ]\n\nconst array4 = ['a', 'b', 'c', 'b', 'd', 'e', 'a']\narray4.fill(0, -1) // last element\nconsole.dir(array4)\n// [ 'a', 'b', 'c', 'b', 'd', 'e', 0 ]\narray4.fill(0, -2) // last 2 elements\nconsole.dir(array4)\n// [ 'a', 'b', 'c', 'b', 'd', 0, 0 ]\n"
  },
  {
    "path": "examples/02-08_array-filter.mjs",
    "content": "const numbers = [3, 75, 42, 13, 69]\nconst resultNumbers = numbers.filter((number) => number >= 50)\nconsole.dir(resultNumbers)\n// output: Array [ 75, 69 ]\n\nconst elements = [\n  { product: 'Desk', price: 200, active: true },\n  { product: 'Chair', price: 100, active: true },\n  { product: 'Door', price: 300, active: false },\n  { product: 'Bookcase', price: 150, active: true },\n  { product: 'Door', price: 100, active: true },\n]\nconst resultElements = elements.filter((element) => element.price >= 150)\n\nconsole.dir(resultElements)\n/*\noutput:\nArray [\n  { product: 'Desk', price: 200, active: true },\n  { product: 'Door', price: 300, active: false },\n  { product: 'Bookcase', price: 150, active: true }\n]\n*/\n\nconst resultActiveElements = elements.filter(\n  (element) => element.active && element.price >= 150\n)\nconsole.dir(resultActiveElements)\n/*\noutput:\nArray [\n  { product: 'Desk', price: 200, active: true },\n  { product: 'Bookcase', price: 150, active: true }\n]\n*/\n"
  },
  {
    "path": "examples/02-09_array-every.mjs",
    "content": "const array = [32, 30, 39, 29, 100, 43]\n\nconsole.log(array.every((currentValue) => currentValue > 25))\n"
  },
  {
    "path": "examples/02-10_array-some.mjs",
    "content": "const array = [32, 30, 39, 29, 100, 43]\n\nconsole.log(array.some((currentValue) => currentValue > 90))\n"
  },
  {
    "path": "examples/02-11_array-map.mjs",
    "content": "const numbers = [1, 2, 3, 4, 5]\n\n// Using map() method to create a new array by doubling each number\nconst doubledNumbers = numbers.map((number) => number * 2)\n\nconsole.log('Original Array:', numbers)\nconsole.log('Doubled Array:', doubledNumbers)\n"
  },
  {
    "path": "examples/02-12_array-reduce.mjs",
    "content": "const numbers = [1, 2, 3, 4, 5]\n\nconst sumWithInitialValue = numbers.reduce((accumulator, currentValue) => {\n  return accumulator + currentValue\n}, 0) //Here 0 is an initial value to the accumulator\n\n/* Here if we do not mention initialValue '0', then initial value of accumulator will be first array value \nand the currentValue will be second value of Array. */\nconst sumWithoutInitialValue = numbers.reduce((acc, curr) => {\n  return acc + curr\n})\n\nconsole.log('SumWithInitialValue:', sumWithInitialValue)\nconsole.log('SumWithoutInitialValue:', sumWithoutInitialValue)\n\n//Counting the number of occurrences of elements in an array using reduce():\nconst fruits = ['apple', 'banana', 'orange', 'apple', 'banana', 'apple']\n\nconst fruitCounter = fruits.reduce((accumulator, currentFruit) => {\n  accumulator[currentFruit] = (accumulator[currentFruit] || 0) + 1\n  return accumulator\n}, {})\n\nconsole.log('Occurrences:', fruitCounter)\n// Output: Occurrences: { apple: 3, banana: 2, orange: 1 }\n\n//Finding the Maximum and Minimum Values using reduce():\nconst numbersArray = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]\n\nconst max = numbersArray.reduce((accumulator, currentValue) => {\n  return Math.max(accumulator, currentValue)\n})\n\nconst min = numbersArray.reduce((accumulator, currentValue) => {\n  return Math.min(accumulator, currentValue)\n})\n\nconsole.log('Maximum value:', max) // Output: Maximum value: 9\nconsole.log('Minimum value:', min) // Output: Minimum value: 1\n\n//Transforming an Array into a Different Data Structure using reduce():\nconst data = [\n  { id: 1, name: 'Alice' },\n  { id: 2, name: 'Bob' },\n  { id: 3, name: 'Charlie' },\n]\n\nconst transformedData = data.reduce((accumulator, currentValue) => {\n  accumulator[currentValue.id] = currentValue.name\n  return accumulator\n}, {})\n\nconsole.log('Transformed Data:', transformedData)\n// Output: Transformed Data: { 1: 'Alice', 2: 'Bob', 3: 'Charlie' }\n"
  },
  {
    "path": "examples/02-13_array-splice.mjs",
    "content": "// Using splice() method to modify an array by removing, adding, and replacing elements:\nconst fruits = ['Apple', 'Banana', 'Cherry', 'Date']\n\n// Removing elements\nconst removedFruits = fruits.splice(1, 2) // Removes 2 elements starting from index 1\nconsole.log('Modified array:', fruits) // Output: ['Apple', 'Date']\nconsole.log('Removed elements:', removedFruits) // Output: ['Banana', 'Cherry']\n\n// Adding elements\nfruits.splice(1, 0, 'Blueberry', 'Coconut') // Adds two elements at index 1\nconsole.log('Array after adding:', fruits) // Output: ['Apple', 'Blueberry', 'Coconut', 'Date']\n\n// Replacing elements\nfruits.splice(2, 1, 'Dragonfruit') // Replaces 1 element at index 2\nconsole.log('Array after replacing:', fruits) // Output: ['Apple', 'Blueberry', 'Dragonfruit', 'Date']\n\n// Using splice() method to shuffle an array:\nconst numbers = [1, 2, 3, 4, 5]\n\nfor (let i = numbers.length - 1; i > 0; i--) {\n  // Generate a random index 'j' between 0 and 'i' (inclusive)\n  const j = Math.floor(Math.random() * (i + 1))\n\n  // Remove the element at index 'j' from the array\n  const [removed] = numbers.splice(j, 1)\n\n  // Insert the removed element back into the array at index 'i'\n  numbers.splice(i, 0, removed)\n}\nconsole.log('Shuffled array:', numbers)\n\n// Using splice() method to swap elements:\nconst arr = ['a', 'b', 'c', 'd']\n\nfunction swap(arr, index1, index2) {\n  const [elem1] = arr.splice(index1, 1)\n  const [elem2] = arr.splice(index2 - 1, 1) // '-1' adjusts for the earlier removal of 'elem1'\n  arr.splice(index1, 0, elem2)\n  arr.splice(index2, 0, elem1)\n}\nswap(arr, 1, 3)\nconsole.log('Swapped array:', arr) // Output: ['a', 'd', 'c', 'b']\n"
  },
  {
    "path": "examples/02-15_array-flat.mjs",
    "content": "const arr = [[1, 2, 3], [4, 5, 6], 7, 8]\nconsole.log(arr.flat()) // Output: [1, 2, 3, 4, 5, 6, 7, 8]\n\nconst arr2 = [1, 2, [3, 4, [5, 6]]]\nconsole.log(arr2.flat()) // Output: [1, 2, 3, 4, [5, 6]]\n\nconsole.log(arr2.flat(2)) // Output: [1, 2, 3, 4, 5, 6]\n\nconst arr5 = [1, 2, , 4, 5]\nconsole.log(arr5.flat()) // Output: [1, 2, 4, 5]\n"
  },
  {
    "path": "examples/02-16_array-findindex.mjs",
    "content": "// using findIndex() method to get the first index of the element that passes the test\nconst ages = [3, 10, 18, 20]\n\n// storing the index value in index variable\nlet index = ages.findIndex(checkAge)\n\n// printing the index value (3)\nconsole.log(index)\n\n// testing function, passed as a callback to findIndex() method\nfunction checkAge(age) {\n  return age > 18\n}\n\n// findIndex() returns -1 when no element match is found\nconst newAges = [3, 10, 13, 15]\n\n// storing the index value in index variable\nindex = newAges.findIndex(checkAge)\n\n// printing the index value (-1)\nconsole.log(index)\n"
  },
  {
    "path": "examples/02-17_array-at.mjs",
    "content": "const fruit = ['banana', 'mango', 'orange', 'apple']\n\nconsole.log(fruit.at(0)) // Output: \"banana\"\n\nconst item = fruit.at(2)\n\nconsole.log(item) // Output: \"orange\"\n\n// Using a negative index\n\nconsole.log(fruit.at(-1)) // Output: \"apple\"\n\nconst item2 = fruit.at(-3)\n\nconsole.log(item2) // Output: \"mango\"\n"
  },
  {
    "path": "examples/02-18_array-flatmap.mjs",
    "content": "const arr = [\n  [1, 2],\n  [3, 4],\n  [5, 6],\n]\nconsole.log(arr.flatMap((x) => x)) // Output: [1, 2, 3, 4, 5, 6]\n\nconst arr2 = [\n  [1, 2],\n  [3, 4],\n  [5, 6],\n]\nconsole.log(arr2.flatMap((x) => x.map((n) => n * 2))) // Output: [2, 4, 6, 8, 10, 12]\n\nconst arr3 = [[1, 2], , [3, 4], [5, 6]]\nconsole.log(arr3.flatMap((x) => x)) // Output: [1, 2, 3, 4, 5, 6]\n\nconst arr4 = [\n  ['hello', 'world'],\n  ['foo', 'bar'],\n]\nconsole.log(arr4.flatMap((x) => x.join(' '))) // Output: [\"hello world\", \"foo bar\"]\n"
  },
  {
    "path": "examples/02-19_array-keys.mjs",
    "content": "const fruit = ['watermelon', 'pineapple', 'pear', 'mango']\nconst fruitKeys = fruit.keys()\n\nfor (let key of fruitKeys) {\n  console.log(key)\n}\n\n// Output:\n// 0\n// 1\n// 2\n// 3\n\n// with sparse arrays\n\nconst animal = ['dog', , 'cat']\n\nfor (let key of animal.keys()) {\n  console.log(`Animal at index ${key} is ${animal[key]}`)\n}\n\n// Output:\n// Animal at index 0 is dog\n// Animal at index 1 is undefined\n// Animal at index 2 is cat\n"
  },
  {
    "path": "examples/02-20_array-entries.mjs",
    "content": "// Examples for Array.entries()\n\n// Basic usage\nconst fruits = ['Apple', 'Banana', 'Orange']\nconsole.log('Original array:', fruits)\n\nconsole.log('\\nIterating over entries:')\nconst iterator = fruits.entries()\nfor (const entry of iterator) {\n    console.log(entry)\n}\n// Output:\n// [0, \"Apple\"]\n// [1, \"Banana\"]\n// [2, \"Orange\"]\n\n// Destructuring in loop\nconst colors = ['red', 'green', 'blue']\nconsole.log('\\nOriginal array:', colors)\nconsole.log('Destructuring entries in loop:')\nconst iterator2 = colors.entries()\nfor (const [index, value] of iterator2) {\n    console.log(`${index}: ${value}`)\n}\n// Output:\n// \"0: red\"\n// \"1: green\"\n// \"2: blue\"\n\n// Converting iterator to array\nconst numbers = [1, 2, 3, 4, 5]\nconsole.log('\\nOriginal array:', numbers)\nconst iterator3 = numbers.entries()\nconst entriesArray = [...iterator3]\nconsole.log('Entries as array:', entriesArray)\n// Output: [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]]\n\n// Using with iterator methods\nconst letters = ['a', 'b', 'c']\nconsole.log('\\nOriginal array:', letters)\nconst iterator4 = letters.entries()\nconsole.log('First entry:', iterator4.next().value)\nconsole.log('Second entry:', iterator4.next().value)\nconsole.log('Third entry:', iterator4.next().value)\nconsole.log('Is iteration complete?', iterator4.next().done)\n// Output:\n// [0, \"a\"]\n// [1, \"b\"]\n// [2, \"c\"]\n// true\n\n// Creating a Map from an array\nfunction arrayToMap(array) {\n    const map = new Map()\n    for (const [index, value] of array.entries()) {\n        map.set(index, value)\n    }\n    return map\n}\n\nconst fruitsMap = arrayToMap(fruits)\nconsole.log('\\nCreating a Map from array:')\nconsole.log('Map.get(1):', fruitsMap.get(1)) // Output: \"Banana\"\nconsole.log('Map has 0:', fruitsMap.has(0)) // Output: true\nconsole.log('Map has 3:', fruitsMap.has(3)) // Output: false\n\n// Filtering with index awareness\nfunction filterWithIndex(array, callback) {\n    const result = []\n    for (const [index, value] of array.entries()) {\n        if (callback(value, index)) {\n            result.push(value)\n        }\n    }\n    return result\n}\n\nconst nums = [10, 20, 30, 40, 50]\nconsole.log('\\nOriginal array:', nums)\nconst filteredNumbers = filterWithIndex(nums, (value, index) => index % 2 === 0)\nconsole.log('Elements at even indices:', filteredNumbers) // Output: [10, 30, 50]\n\n// Creating an object with array indices as keys\nfunction arrayToObject(array) {\n    return Object.fromEntries(array.entries())\n}\n\nconst fruitsObject = arrayToObject(fruits)\nconsole.log('\\nCreating an object from array:')\nconsole.log(fruitsObject)\n// Output: { 0: \"Apple\", 1: \"Banana\", 2: \"Orange\" }\n\n// Comparison with other array iterator methods\nconst arr = ['a', 'b', 'c']\nconsole.log('\\nOriginal array:', arr)\n\nconsole.log('\\nDifferent iterator methods:')\n// entries() - returns [index, value] pairs\nconsole.log('entries():')\nconst entryIterator = arr.entries()\nfor (const entry of entryIterator) {\n    console.log(entry)\n}\n// Output: [0, \"a\"], [1, \"b\"], [2, \"c\"]\n\n// keys() - returns indices\nconsole.log('\\nkeys():')\nconst keyIterator = arr.keys()\nfor (const key of keyIterator) {\n    console.log(key)\n}\n// Output: 0, 1, 2\n\n// values() - returns values\nconsole.log('\\nvalues():')\nconst valueIterator = arr.values()\nfor (const value of valueIterator) {\n    console.log(value)\n}\n// Output: \"a\", \"b\", \"c\" "
  },
  {
    "path": "examples/02-21_array-findlastindex.mjs",
    "content": "// using findLastIndex() method to get the last index of the element that passes the test\nconst numbers = [5, 12, 8, 130, 44]\n\n// storing the last index value in lastIndex variable\nlet lastIndex = numbers.findLastIndex(checkLargeNumber)\n\n// printing last index value\nconsole.log(lastIndex)\n\n// testing function, passed as a callback to findLastIndex() method\nfunction checkLargeNumber(num) {\n  return num > 10\n}\n\n// findLastIndex() returns -1 when no element match is found\nconst new_numbers = [1, 2, 3, 4, 5]\n\n// storing the last index value in lastIndex variable\nlastIndex = new_numbers.findLastIndex(checkLargeNumber)\n\n// printing the lastIndex variable value (-1)\nconsole.log(lastIndex)\n"
  },
  {
    "path": "examples/02-22_array-findlastind.mjs",
    "content": "const numbers = [5, 12, 8, 130, 44]\n\nconst lastLargeNumber = numbers.findLast((element) => element > 10)\nconsole.log('Last number larger than 10:', lastLargeNumber)\n// Expected output: 44\n\nconst fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']\nconst lastLongFruit = fruits.findLast((fruit) => fruit.length > 5)\nconsole.log('Last fruit with more than 5 characters:', lastLongFruit)\n// Expected output: elderberry\n\nconst people = [\n  { name: 'Tom', age: 25 },\n  { name: 'Bill', age: 30 },\n  { name: 'Kate', age: 28 },\n  { name: 'Pete', age: 32 },\n]\nconst lastAdult = people.findLast((person) => person.age >= 30)\nconsole.log('Last person aged 30 or older:', lastAdult)\n// Expected output: { name: 'Pete', age: 32 }\n\n// When no element satisfies the condition\nconst noMatch = numbers.findLast((num) => num > 1000)\nconsole.log('No number larger than 1000:', noMatch)\n// Expected output: undefined\n"
  },
  {
    "path": "examples/02-23_array-copywithin.mjs",
    "content": "const numbers = [1, 2, 3, 4, 5]\nconsole.log('Original Array:', numbers) //expected output: [1, 2, 3, 4, 5]\n\n// Using copyWithin() method to create a new array where method copies to index 1 all elements from index 3 to the end\nconsole.log('New Array:', numbers.copyWithin(1, 3)) //expected output: [1, 4, 5, 4, 5]\n\n// In this case, the method copies to index 1 all elements from index 0 to index 3\nconsole.log('New Array:', numbers.copyWithin(1, 0, 3)) //expected output: [1, 1, 2, 3, 5]\n\n// It's possible use negative values\nconsole.log('New Array:', numbers.copyWithin(-2, -3, -1)) //expected output: [1, 2, 3, 3, 4]\n\n// copyWithin() will propagate empty slots\nconst halfBlankArray = [1, , 3]\nconsole.log('New Array:', halfBlankArray.copyWithin(2, 1, 2)) //expected output: [1,,]\n\n// The method reads the length property of 'obj' and then manipulates the integer indices involved.\nconst obj = {\n  length: 5,\n  3: 1,\n}\nconsole.log(Array.prototype.copyWithin.call(obj, 0, 3)) // expected output: { '0': 1, '3': 1, length: 5 }\n"
  },
  {
    "path": "examples/02-24_array-entries.mjs",
    "content": "const fruits = ['Banana', 'Apple', 'Mango']\nconst fruitsEntries = fruits.entries()\n\nfor (const [index, fruit] of fruits.entries()) {\n  console.log(index, fruit)\n}\n\nfor (const fruit of fruitsEntries) {\n  console.log(fruit)\n}\n// 0 'Banana'\n// 1 'Apple'\n// 2 'Mango'\n\nfor (const fruit of [, \"Banana\"].entries()) {\n  console.log(fruit)\n}\n// [0, undefined]\n// [1, 'Banana']\n\nconsole.log(fruitsEntries.next().value + \" \" + fruitsEntries.next().value);\n// \"0,Banana 1,Apple\"\n\nconst user = {\n    name: 'John',\n    age: 30\n}\nconsole.log(Object.entries(user)); // [['name', 'John'], ['age', 30]]\n\nconst mapping = new Map();\nmapping.set(\"0\", \"Peach\");\nmapping.set(1, \"Mango\");\nmapping.set({}, \"Banana\");\n\nconst mapIter = mapping.entries();\n\nconsole.log(mapIter.next().value); // [\"0\", \"Peach\"]\nconsole.log(mapIter.next().value); // [1, \"Mango\"]\nconsole.log(mapIter.next().value); // [Object, \"Banana\"]"
  },
  {
    "path": "examples/02-25_array-values.mjs",
    "content": "// Examples for Array.values()\n\n// Basic usage\nconst fruits = ['Apple', 'Banana', 'Orange']\nconsole.log('Original array:', fruits)\n\nconsole.log('\\nIterating over values:')\nconst iterator = fruits.values()\nfor (const value of iterator) {\n    console.log(value)\n}\n// Output:\n// Apple\n// Banana\n// Orange\n\n// Converting iterator to array\nconst numbers = [1, 2, 3, 4, 5]\nconsole.log('\\nOriginal array:', numbers)\nconst iterator2 = numbers.values()\nconst valuesArray = [...iterator2]\nconsole.log('Values as array:', valuesArray)\n// Output: [1, 2, 3, 4, 5]\n\n// Using with iterator methods\nconst colors = ['red', 'green', 'blue']\nconsole.log('\\nOriginal array:', colors)\nconst iterator3 = colors.values()\nconsole.log('First value:', iterator3.next().value)\nconsole.log('Second value:', iterator3.next().value)\nconsole.log('Third value:', iterator3.next().value)\nconsole.log('Is iteration complete?', iterator3.next().done)\n// Output:\n// red\n// green\n// blue\n// true\n\n// Iterating over sparse arrays\nconst sparseArray = [1, , 3, , 5]\nconsole.log('\\nSparse array:', sparseArray)\nconsole.log('Iterating over sparse array values:')\nconst iterator4 = sparseArray.values()\nfor (const value of iterator4) {\n    console.log(value)\n}\n// Output:\n// 1\n// undefined\n// 3\n// undefined\n// 5\n\n// Iterating over array values\nfunction processArrayValues(array) {\n    console.log('\\nProcessing array values:')\n    const iterator = array.values()\n    for (const value of iterator) {\n        console.log(`Processing: ${value}`)\n    }\n}\n\nprocessArrayValues(['a', 'b', 'c'])\n// Output:\n// Processing: a\n// Processing: b\n// Processing: c\n\n// Creating multiple independent iterators\nconst data = [10, 20, 30]\nconsole.log('\\nOriginal array:', data)\nconst iterator5 = data.values()\nconst iterator6 = data.values()\n\nconsole.log('First iterator - first value:', iterator5.next().value)\nconsole.log('First iterator - second value:', iterator5.next().value)\nconsole.log('Second iterator - first value:', iterator6.next().value)\n// Output:\n// 10\n// 20\n// 10 (independent iterator)\n\n// Working with other iteration methods\nconst items = ['item1', 'item2', 'item3']\nconsole.log('\\nOriginal array:', items)\nconst iterator7 = items.values()\n\n// Convert to array and apply array methods\nconst upperCaseItems = [...iterator7].map(item => item.toUpperCase())\nconsole.log('Uppercase items:', upperCaseItems)\n// Output: [\"ITEM1\", \"ITEM2\", \"ITEM3\"]\n\n// Comparison with other array iterator methods\nconst arr = ['a', 'b', 'c']\nconsole.log('\\nOriginal array:', arr)\n\nconsole.log('\\nDifferent iterator methods:')\n// values() - returns values\nconsole.log('values():')\nconst valueIterator = arr.values()\nfor (const val of valueIterator) {\n    console.log(val)\n}\n// Output: \"a\", \"b\", \"c\"\n\n// keys() - returns indices\nconsole.log('\\nkeys():')\nconst keyIterator = arr.keys()\nfor (const key of keyIterator) {\n    console.log(key)\n}\n// Output: 0, 1, 2\n\n// entries() - returns [index, value] pairs\nconsole.log('\\nentries():')\nconst entryIterator = arr.entries()\nfor (const entry of entryIterator) {\n    console.log(entry)\n}\n// Output: [0, \"a\"], [1, \"b\"], [2, \"c\"] "
  },
  {
    "path": "examples/02-26_array-sort.mjs",
    "content": "// Examples for Array.sort()\n\n// Basic usage - sorting strings\nconst fruits = ['Banana', 'Orange', 'Apple', 'Mango']\nconsole.log('Original array:', fruits)\nfruits.sort()\nconsole.log('Sorted array:', fruits)\n// Output: [\"Apple\", \"Banana\", \"Mango\", \"Orange\"]\n\n// Sorting numbers - default behavior\nconst numbers = [40, 100, 1, 5, 25, 10]\nconsole.log('\\nOriginal numbers:', numbers)\nnumbers.sort()\nconsole.log('Sorted numbers (default):', numbers)\n// Output: [1, 10, 100, 25, 40, 5] - not what you might expect!\n\n// Using a compare function for numbers - ascending order\nconst numbers2 = [40, 100, 1, 5, 25, 10]\nconsole.log('\\nOriginal numbers:', numbers2)\nnumbers2.sort((a, b) => a - b)\nconsole.log('Sorted numbers (ascending):', numbers2)\n// Output: [1, 5, 10, 25, 40, 100]\n\n// Sorting in descending order\nconst numbers3 = [40, 100, 1, 5, 25, 10]\nconsole.log('\\nOriginal numbers:', numbers3)\nnumbers3.sort((a, b) => b - a)\nconsole.log('Sorted numbers (descending):', numbers3)\n// Output: [100, 40, 25, 10, 5, 1]\n\n// Sorting objects by property\nconst people = [\n    { name: 'John', age: 30 },\n    { name: 'Alice', age: 25 },\n    { name: 'Bob', age: 35 }\n]\nconsole.log('\\nOriginal people array:')\nconsole.log(people)\n\n// Sort by age\npeople.sort((a, b) => a.age - b.age)\nconsole.log('\\nPeople sorted by age:')\nconsole.log(people)\n// Output: [{ name: 'Alice', age: 25 }, { name: 'John', age: 30 }, { name: 'Bob', age: 35 }]\n\n// Sort by name\npeople.sort((a, b) => a.name.localeCompare(b.name))\nconsole.log('\\nPeople sorted by name:')\nconsole.log(people)\n// Output: [{ name: 'Alice', age: 25 }, { name: 'Bob', age: 35 }, { name: 'John', age: 30 }]\n\n// Case-insensitive sorting\nconst cities = ['Vienna', 'berlin', 'Amsterdam', 'paris']\nconsole.log('\\nOriginal cities array:', cities)\ncities.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))\nconsole.log('Cities sorted case-insensitive:', cities)\n// Output: [\"Amsterdam\", \"berlin\", \"paris\", \"Vienna\"]\n\n// Custom sorting logic\nconst items = [\n    { name: 'Edward', value: 21 },\n    { name: 'Sharpe', value: 37 },\n    { name: 'And', value: 45 },\n    { name: 'The', value: -12 },\n    { name: 'Magnetic', value: 13 },\n    { name: 'Zeros', value: 37 }\n]\nconsole.log('\\nOriginal items array:')\nconsole.log(items)\n\n// Sort by value, then by name if values are equal\nitems.sort((a, b) => {\n    if (a.value !== b.value) {\n        return a.value - b.value\n    }\n    return a.name.localeCompare(b.name)\n})\nconsole.log('\\nItems sorted by value, then by name:')\nconsole.log(items)\n\n// Sorting with internationalization\nconst names = ['Österreich', 'Andorra', 'Vietnam', 'Zaire', 'Åland']\nconsole.log('\\nOriginal names array:', names)\nconst collator = new Intl.Collator('en')\nnames.sort((a, b) => collator.compare(a, b))\nconsole.log('Names sorted with Intl.Collator:', names)\n// Output: [\"Åland\", \"Andorra\", \"Österreich\", \"Vietnam\", \"Zaire\"]\n\n// Demonstrating stability of sort\nconst data = [\n    { id: 1, value: 'a' },\n    { id: 2, value: 'b' },\n    { id: 3, value: 'a' },\n    { id: 4, value: 'c' }\n]\nconsole.log('\\nOriginal data array:')\nconsole.log(data)\n\n// Sort by value\ndata.sort((a, b) => a.value.localeCompare(b.value))\nconsole.log('\\nData sorted by value (stable sort):')\nconsole.log(data)\n// Output: The elements with value 'a' maintain their relative order (id 1 before id 3) "
  },
  {
    "path": "examples/02-27_array-reverse.mjs",
    "content": "// Examples for Array.reverse()\n\n// Basic usage\nconst fruits = ['Apple', 'Banana', 'Orange', 'Mango']\nconsole.log('Original array:', fruits)\nfruits.reverse()\nconsole.log('Reversed array:', fruits)\n// Output: [\"Mango\", \"Orange\", \"Banana\", \"Apple\"]\n\n// Reversing a numeric array\nconst numbers = [1, 2, 3, 4, 5]\nconsole.log('\\nOriginal numbers:', numbers)\nnumbers.reverse()\nconsole.log('Reversed numbers:', numbers)\n// Output: [5, 4, 3, 2, 1]\n\n// Chaining with other array methods\nconst originalNumbers = [1, 2, 3, 4, 5]\nconsole.log('\\nOriginal array:', originalNumbers)\nconst reversed = [...originalNumbers].reverse()\nconsole.log('Original array (unchanged):', originalNumbers)\nconsole.log('New reversed array:', reversed)\n// Output: \n// Original: [1, 2, 3, 4, 5]\n// Reversed: [5, 4, 3, 2, 1]\n\n// Reversing a string using array methods\nconst str = 'Hello World'\nconsole.log('\\nOriginal string:', str)\nconst reversedStr = str.split('').reverse().join('')\nconsole.log('Reversed string:', reversedStr)\n// Output: \"dlroW olleH\"\n\n// Reversing a copy of an array\nfunction reverseArrayCopy(array) {\n    return [...array].reverse()\n}\n\nconst original = [1, 2, 3, 4, 5]\nconsole.log('\\nOriginal array:', original)\nconst reversedCopy = reverseArrayCopy(original)\nconsole.log('Original array (unchanged):', original)\nconsole.log('Reversed copy:', reversedCopy)\n// Output:\n// Original: [1, 2, 3, 4, 5]\n// Reversed: [5, 4, 3, 2, 1]\n\n// Implementing a palindrome check\nfunction isPalindrome(str) {\n    // Remove non-alphanumeric characters and convert to lowercase\n    const cleanStr = str.toLowerCase().replace(/[^a-z0-9]/g, '')\n    // Compare with its reverse\n    return cleanStr === cleanStr.split('').reverse().join('')\n}\n\nconsole.log('\\nPalindrome checks:')\nconsole.log('Is \"A man, a plan, a canal: Panama\" a palindrome?',\n    isPalindrome('A man, a plan, a canal: Panama')) // Output: true\nconsole.log('Is \"race a car\" a palindrome?',\n    isPalindrome('race a car')) // Output: false\n\n// Creating a reverse iterator\nfunction* reverseIterator(array) {\n    for (let i = array.length - 1; i >= 0; i--) {\n        yield array[i]\n    }\n}\n\nconst letters = ['a', 'b', 'c', 'd']\nconsole.log('\\nOriginal array:', letters)\nconsole.log('Using reverse iterator:')\nfor (const item of reverseIterator(letters)) {\n    console.log(item)\n}\n// Output:\n// \"d\"\n// \"c\"\n// \"b\"\n// \"a\"\n\n// Reversing nested arrays\nconst nestedArray = [[1, 2], [3, 4], [5, 6]]\nconsole.log('\\nOriginal nested array:', nestedArray)\nnestedArray.reverse()\nconsole.log('Top-level reversed:', nestedArray)\n// Output: [[5, 6], [3, 4], [1, 2]]\n\n// Deep reversing nested arrays\nconst nestedArray2 = [[1, 2], [3, 4], [5, 6]]\nconsole.log('\\nOriginal nested array:', nestedArray2)\nconst deepReversed = nestedArray2.map(subArray => subArray.reverse()).reverse()\nconsole.log('Deep reversed:', deepReversed)\n// Output: [[6, 5], [4, 3], [2, 1]] "
  },
  {
    "path": "examples/02-28_array-push-pop.mjs",
    "content": "// Examples for Array.push() and Array.pop()\n\n// Basic usage of push()\nconst fruits = ['Apple', 'Banana']\nconsole.log('Original array:', fruits)\nconst newLength = fruits.push('Orange')\nconsole.log('After push():', fruits)\nconsole.log('New length:', newLength)\n// Output:\n// [\"Apple\", \"Banana\", \"Orange\"]\n// 3\n\n// Adding multiple elements with push()\nconst numbers = [1, 2]\nconsole.log('\\nOriginal array:', numbers)\nconst multiPushLength = numbers.push(3, 4, 5)\nconsole.log('After push() with multiple elements:', numbers)\nconsole.log('New length:', multiPushLength)\n// Output:\n// [1, 2, 3, 4, 5]\n// 5\n\n// Basic usage of pop()\nconst vegetables = ['Carrot', 'Broccoli', 'Spinach']\nconsole.log('\\nOriginal array:', vegetables)\nconst removedItem = vegetables.pop()\nconsole.log('After pop():', vegetables)\nconsole.log('Removed item:', removedItem)\n// Output:\n// [\"Carrot\", \"Broccoli\"]\n// \"Spinach\"\n\n// Popping from an empty array\nconst emptyArray = []\nconsole.log('\\nEmpty array:', emptyArray)\nconst removedFromEmpty = emptyArray.pop()\nconsole.log('After pop() on empty array:', emptyArray)\nconsole.log('Removed item (undefined):', removedFromEmpty)\n// Output:\n// []\n// undefined\n\n// Implementing a Stack data structure\nconsole.log('\\n--- Stack Implementation ---')\nclass Stack {\n    constructor() {\n        this.items = []\n    }\n\n    push(element) {\n        return this.items.push(element)\n    }\n\n    pop() {\n        if (this.items.length === 0) {\n            return 'Underflow'\n        }\n        return this.items.pop()\n    }\n\n    peek() {\n        return this.items[this.items.length - 1]\n    }\n\n    isEmpty() {\n        return this.items.length === 0\n    }\n\n    size() {\n        return this.items.length\n    }\n\n    clear() {\n        this.items = []\n    }\n}\n\nconst stack = new Stack()\nconsole.log('Is stack empty?', stack.isEmpty()) // true\n\nstack.push(10)\nstack.push(20)\nstack.push(30)\nconsole.log('Stack after pushes:', stack.items)\nconsole.log('Stack size:', stack.size()) // 3\nconsole.log('Top element:', stack.peek()) // 30\n\nconsole.log('Popped element:', stack.pop()) // 30\nconsole.log('Stack after pop:', stack.items)\nconsole.log('Stack size after pop:', stack.size()) // 2\n\nstack.clear()\nconsole.log('Stack after clear:', stack.items)\nconsole.log('Is stack empty after clear?', stack.isEmpty()) // true\n\n// Building and managing a task queue\nconsole.log('\\n--- Task Queue Example ---')\nconst taskQueue = []\n\n// Add tasks to the queue\ntaskQueue.push('Task 1')\ntaskQueue.push('Task 2')\ntaskQueue.push('Task 3')\n\nconsole.log('Current queue:', taskQueue) // [\"Task 1\", \"Task 2\", \"Task 3\"]\n\n// Process tasks in a LIFO (Last In, First Out) order\nconsole.log('Processing tasks:')\nwhile (taskQueue.length > 0) {\n    const currentTask = taskQueue.pop()\n    console.log('Processing:', currentTask)\n}\nconsole.log('Queue after processing:', taskQueue) // []\n\n// Manipulating a history stack\nconsole.log('\\n--- Browser History Example ---')\nconst browserHistory = []\n\n// Navigate to pages\nfunction navigateTo(page) {\n    browserHistory.push(page)\n    console.log(`Navigated to ${page}`)\n}\n\n// Go back one page\nfunction goBack() {\n    if (browserHistory.length > 1) {\n        browserHistory.pop() // Remove current page\n        const previousPage = browserHistory[browserHistory.length - 1]\n        console.log(`Navigated back to ${previousPage}`)\n        return previousPage\n    } else {\n        console.log('No previous page to navigate to')\n        return null\n    }\n}\n\nnavigateTo('Home')\nnavigateTo('Products')\nnavigateTo('Product Details')\n\nconsole.log('Current history stack:', browserHistory)\nconsole.log('Current page:', browserHistory[browserHistory.length - 1])\n\ngoBack() // Back to Products\nconsole.log('History stack after going back:', browserHistory)\n\ngoBack() // Back to Home\nconsole.log('History stack after going back again:', browserHistory) "
  },
  {
    "path": "examples/02-29_array-shift-unshift.mjs",
    "content": "// Examples for Array.shift() and Array.unshift()\n\n// Basic usage of shift()\nconst fruits = ['Apple', 'Banana', 'Orange']\nconsole.log('Original array:', fruits)\nconst removedItem = fruits.shift()\nconsole.log('After shift():', fruits)\nconsole.log('Removed item:', removedItem)\n// Output:\n// [\"Banana\", \"Orange\"]\n// \"Apple\"\n\n// Shifting from an empty array\nconst emptyArray = []\nconsole.log('\\nEmpty array:', emptyArray)\nconst removedFromEmpty = emptyArray.shift()\nconsole.log('After shift() on empty array:', emptyArray)\nconsole.log('Removed item (undefined):', removedFromEmpty)\n// Output:\n// []\n// undefined\n\n// Basic usage of unshift()\nconst vegetables = ['Broccoli', 'Spinach']\nconsole.log('\\nOriginal array:', vegetables)\nconst newLength = vegetables.unshift('Carrot')\nconsole.log('After unshift():', vegetables)\nconsole.log('New length:', newLength)\n// Output:\n// [\"Carrot\", \"Broccoli\", \"Spinach\"]\n// 3\n\n// Adding multiple elements with unshift()\nconst numbers = [3, 4, 5]\nconsole.log('\\nOriginal array:', numbers)\nconst multiUnshiftLength = numbers.unshift(1, 2)\nconsole.log('After unshift() with multiple elements:', numbers)\nconsole.log('New length:', multiUnshiftLength)\n// Output:\n// [1, 2, 3, 4, 5]\n// 5\n\n// Implementing a Queue data structure\nconsole.log('\\n--- Queue Implementation ---')\nclass Queue {\n    constructor() {\n        this.items = []\n    }\n\n    enqueue(element) {\n        return this.items.push(element)\n    }\n\n    dequeue() {\n        if (this.items.length === 0) {\n            return 'Underflow'\n        }\n        return this.items.shift()\n    }\n\n    front() {\n        if (this.items.length === 0) {\n            return 'No elements in Queue'\n        }\n        return this.items[0]\n    }\n\n    isEmpty() {\n        return this.items.length === 0\n    }\n\n    size() {\n        return this.items.length\n    }\n\n    clear() {\n        this.items = []\n    }\n}\n\nconst queue = new Queue()\nconsole.log('Is queue empty?', queue.isEmpty()) // true\n\nqueue.enqueue(10)\nqueue.enqueue(20)\nqueue.enqueue(30)\nconsole.log('Queue after enqueues:', queue.items)\nconsole.log('Queue size:', queue.size()) // 3\nconsole.log('Front element:', queue.front()) // 10\n\nconsole.log('Dequeued element:', queue.dequeue()) // 10\nconsole.log('Queue after dequeue:', queue.items)\nconsole.log('Queue size after dequeue:', queue.size()) // 2\nconsole.log('New front element:', queue.front()) // 20\n\nqueue.clear()\nconsole.log('Queue after clear:', queue.items)\nconsole.log('Is queue empty after clear?', queue.isEmpty()) // true\n\n// Processing tasks in order\nconsole.log('\\n--- Task Processing Example ---')\nconst taskQueue = []\n\n// Add tasks to the queue\ntaskQueue.push('Task 1')\ntaskQueue.push('Task 2')\ntaskQueue.push('Task 3')\n\nconsole.log('Current queue:', taskQueue) // [\"Task 1\", \"Task 2\", \"Task 3\"]\n\n// Process tasks in a FIFO (First In, First Out) order\nconsole.log('Processing tasks:')\nwhile (taskQueue.length > 0) {\n    const currentTask = taskQueue.shift()\n    console.log('Processing:', currentTask)\n}\nconsole.log('Queue after processing:', taskQueue) // []\n\n// Maintaining a sliding window\nconsole.log('\\n--- Sliding Window Example ---')\nfunction slidingWindow(arr, windowSize) {\n    const result = []\n    const window = []\n\n    for (let i = 0; i < arr.length; i++) {\n        window.push(arr[i]) // Add new element\n\n        // If window is full, process it\n        if (window.length === windowSize) {\n            result.push([...window]) // Store current window\n            window.shift() // Remove oldest element\n        }\n    }\n\n    return result\n}\n\nconst data = [1, 2, 3, 4, 5, 6, 7]\nconsole.log('Original data:', data)\nconsole.log('Sliding windows of size 3:', slidingWindow(data, 3))\n// Output: [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7]]\n\n// Performance comparison between shift and pop\nconsole.log('\\n--- Performance Note ---')\nconsole.log('For large arrays, shift() and unshift() are slower than pop() and push()')\nconsole.log('This is because all elements need to be reindexed when adding/removing from the beginning')\nconsole.log('Consider using specialized data structures for frequent operations on large arrays') "
  },
  {
    "path": "examples/03-01_op-typeof.mjs",
    "content": "console.log(typeof 12) // \"number\"\nconsole.log(typeof 'open source') //\"string\"\nconsole.log(typeof true) // \"boolean\"\n"
  },
  {
    "path": "examples/03-02_path-sep.mjs",
    "content": "const path = require('path')\n\nconst folderName = 'documents'\nconst fileName = 'file.txt'\n\nconst filePath = `user${path.sep}${folderName}${path.sep}${fileName}`\n\nconsole.log(`File Path: ${filePath}`)\n//Linux: File Path: user/documents/file.txt\n//Windows: File Path: user\\documents\\file.txt\n\n//Another example of creating filePath using path.sep along with join function\nconsole.log(['user', folderName, fileName].join(path.sep))\n"
  },
  {
    "path": "examples/03-03_os-eol.mjs",
    "content": "const os = require('os')\n\nconst text = 'This is the first line' + os.EOL + 'This is the second line'\nconsole.log(text)\n"
  },
  {
    "path": "examples/03-12_object-groupby.mjs",
    "content": "// Sample inventory data\nconst inventory = [\n    { name: 'asparagus', type: 'vegetables', quantity: 5 },\n    { name: 'bananas', type: 'fruit', quantity: 0 },\n    { name: 'goat', type: 'meat', quantity: 23 },\n    { name: 'cherries', type: 'fruit', quantity: 5 },\n    { name: 'fish', type: 'meat', quantity: 22 },\n  ];\n\n  // Example 1: Grouping by item type\n  const groupedByType = Object.groupBy(inventory, ({ type }) => type);\n\n  console.log(\"Grouped by type:\");\n  console.log(JSON.stringify(groupedByType, null, 2));\n  /* Expected output:\n  {\n    \"vegetables\": [\n      { \"name\": \"asparagus\", \"type\": \"vegetables\", \"quantity\": 5 }\n    ],\n    \"fruit\": [\n      { \"name\": \"bananas\", \"type\": \"fruit\", \"quantity\": 0 },\n      { \"name\": \"cherries\", \"type\": \"fruit\", \"quantity\": 5 }\n    ],\n    \"meat\": [\n      { \"name\": \"goat\", \"type\": \"meat\", \"quantity\": 23 },\n      { \"name\": \"fish\", \"type\": \"meat\", \"quantity\": 22 }\n    ]\n  }\n  */\n\n  // Example 2: Grouping by stock status\n  const groupedByStock = Object.groupBy(inventory,\n    ({ quantity }) => quantity > 5 ? 'in stock' : 'restock'\n  );\n\n  console.log(\"\\nGrouped by stock status:\");\n  console.log(JSON.stringify(groupedByStock, null, 2));\n  /* Expected output:\n  {\n    \"restock\": [\n      { \"name\": \"asparagus\", \"type\": \"vegetables\", \"quantity\": 5 },\n      { \"name\": \"bananas\", \"type\": \"fruit\", \"quantity\": 0 },\n      { \"name\": \"cherries\", \"type\": \"fruit\", \"quantity\": 5 }\n    ],\n    \"in stock\": [\n      { \"name\": \"goat\", \"type\": \"meat\", \"quantity\": 23 },\n      { \"name\": \"fish\", \"type\": \"meat\", \"quantity\": 22 }\n    ]\n  }\n  */\n\n  // Demonstration of using the grouped results\n  console.log(\"\\nItems to restock:\");\n  groupedByStock.restock?.forEach(item =>\n    console.log(`- ${item.name} (Quantity: ${item.quantity})`)\n  );\n  /* Expected output:\n  Items to restock:\n  - asparagus (Quantity: 5)\n  - bananas (Quantity: 0)\n  - cherries (Quantity: 5)\n  */\n\n\n// Grouping fruits by type\nconst fruits = [\n  { name: 'Apple', type: 'Citrus', quantity: 15 },\n  { name: 'Banana', type: 'Tropical', quantity: 10 },\n  { name: 'Orange', type: 'Citrus', quantity: 8 },\n  { name: 'Mango', type: 'Tropical', quantity: 5 },\n  { name: 'Lemon', type: 'Citrus', quantity: 12 }\n];\n\nconst groupedFruitByType = Object.groupBy(fruits, fruit => fruit.type);\nconsole.log(groupedFruitByType)\n/*\n{\n  Citrus: [\n    { name: 'Apple', type: 'Citrus', quantity: 15 },\n    { name: 'Orange', type: 'Citrus', quantity: 8 },\n    { name: 'Lemon', type: 'Citrus', quantity: 12 }\n  ],\n  Tropical: [\n    { name: 'Banana', type: 'Tropical', quantity: 10 },\n    { name: 'Mango', type: 'Tropical', quantity: 5 }\n  ]\n}\n*/\n\n\n\n// Group fruits by quantity range\nconst groupedByQuantityRange = Object.groupBy(fruits, fruit => {\n  if (fruit.quantity < 10) return 'Low';\n  if (fruit.quantity < 15) return 'Medium';\n  return 'High';\n});\n\nconsole.log(groupedByQuantityRange);\n/*\n{\n  Low: [\n    { name: 'Orange', type: 'Citrus', quantity: 8 },\n    { name: 'Mango', type: 'Tropical', quantity: 5 }\n  ],\n  Medium: [\n    { name: 'Banana', type: 'Tropical', quantity: 10 },\n    { name: 'Lemon', type: 'Citrus', quantity: 12 }\n  ],\n  High: [\n    { name: 'Apple', type: 'Citrus', quantity: 15 }\n  ]\n}\n*/\n\n\n\n\n// Grouping fruits by the length of the name\nconst groupedByNameLength = Object.groupBy(fruits, fruit => fruit.name.length);\nconsole.log(groupedByNameLength);\n/*\n{\n  5: [\n    { name: 'Apple', type: 'Citrus', quantity: 15 },\n    { name: 'Mango', type: 'Tropical', quantity: 5 },\n    { name: 'Lemon', type: 'Citrus', quantity: 12 }\n  ],\n  6: [\n    { name: 'Banana', type: 'Tropical', quantity: 10 },\n    { name: 'Orange', type: 'Citrus', quantity: 8 }\n  ]\n}\n*/\n"
  },
  {
    "path": "examples/05-01_str-concat.mjs",
    "content": "// Examples for String.concat()\n\n// Concatenating two strings\nconst str1 = 'Hello, '\nconst str2 = 'world'\nconst result1 = str1.concat(str2)\nconsole.log(result1) // Output: \"Hello, world\"\n\n// Concatenating multiple strings\nconst str3 = 'This'\nconst str4 = ' is'\nconst str5 = ' an'\nconst str6 = ' example.'\nconst result2 = str3.concat(str4, str5, str6)\nconsole.log(result2) // Output: \"This is an example.\"\n\n// Combining strings with different delimiters\nconst str7 = 'Concatenate'\nconst str8 = 'these'\nconst str9 = 'strings'\nconst delimiter = ' - '\nconst result3 = str7.concat(delimiter, str8, delimiter, str9)\nconsole.log(result3) // Output: \"Concatenate - these - strings\"\n"
  },
  {
    "path": "examples/05-02_str-padding.mjs",
    "content": "//Examples for padStart()\n\nconst text = 'Hello'\nconst paddedText = text.padStart(10)\nconsole.log(paddedText) // \"     Hello\"\n\nconst text1 = 'Worlds'\nconst paddedText1 = text1.padStart(10, '-*')\nconsole.log(paddedText) // \"-*-*Worlds\"\n\nconst text2 = 'World'\nconst paddedText2 = text2.padStart(10, '0')\nconsole.log(paddedText) // \"00000World\"\n\nconst text3 = 'JavaScript'\nconst paddedText3 = text3.padStart(5)\nconsole.log(paddedText) // \"JavaScript\"\n\nconst text4 = 'OpenAI'\nconst paddedText4 = text4.padStart(10, 'Knowledge ')\nconsole.log(paddedText) // \"Knowledge OpenAI\"\n\n// Examples for padEnd()\n\nconst text5 = 'Hello'\nconst paddedText5 = text5.padEnd(10)\nconsole.log(paddedText) // \"Hello     \"\n\nconst text6 = 'World'\nconst paddedText6 = text6.padEnd(10, '*')\nconsole.log(paddedText) // \"World*****\"\n\nconst text7 = 'JavaScript'\nconst paddedText7 = text7.padEnd(5)\nconsole.log(paddedText) // \"JavaScript\"\n\nconst num4 = 42\nconst paddedNum4 = num4.toString().padEnd(6, '0')\nconsole.log(paddedNum) // \"420000\"\n"
  },
  {
    "path": "examples/05-03_str-includes.mjs",
    "content": "const str = 'Hello, world!'\n\n// Examples of includes() with one parameter\n\nconst isWorldPresent = str.includes('world')\nconsole.log(isWorldPresent) // Output: true\n\nconst isUniversePresent = str.includes('universe')\nconsole.log(isUniversePresent) // Output: false\n\n// Examples of includes() with two parameter\n\nconst isWorldPresentFromIndex = str.includes('world', 7)\nconsole.log(isWorldPresentFromIndex) // Output: false\n"
  },
  {
    "path": "examples/05-04_str-slice.mjs",
    "content": "const str = 'Hello, world!'\n\n// Using only the start parameter\nconst slicedString1 = str.slice(7)\nconsole.log(slicedString1) // Output: \"world!\"\n\n// Using both start and end parameters\nconst slicedString2 = str.slice(1, 4)\nconsole.log(slicedString2) // Output: \"ell\"\n\n// Using negative indices with only start parameter\nconst slicedString3 = str.slice(-6)\nconsole.log(slicedString3) // Output: \"world!\"\n\n// Using negative indices with both start and end parameter\nconst slicedString4 = str.slice(-6, -3)\nconsole.log(slicedString4) // Output: \"wor\"\n"
  },
  {
    "path": "examples/05-05_str-indexOf.mjs",
    "content": "const str = 'Hello, world!'\n\n// Finding the index of a substring\nconst index1 = str.indexOf('world')\nconsole.log(index1) // Output: 7\n\n// Finding the index of a substring with a specified start index\nconst index2 = str.indexOf('o', 5)\nconsole.log(index2) // Output: 8\n\n// Finding the index of a substring that is not present\nconst index3 = str.indexOf('universe')\nconsole.log(index3) // Output: -1\n"
  },
  {
    "path": "examples/05-06_str-repeat.mjs",
    "content": "const str = 'Hello, '\n\n// Repeating a string multiple times\nconst repeatedString1 = str.repeat(3)\nconsole.log(repeatedString1)\n// Output: \"Hello, Hello, Hello, \"\n\n// Repeating a string zero times\nconst repeatedString2 = str.repeat(0)\nconsole.log(repeatedString2)\n// Output: \"\"\n\n// Repeating a string with a non-integer count\nconst repeatedString = str.repeat(2.5)\nconsole.log(repeatedString)\n// Output: \"Hello, Hello, \"\n"
  },
  {
    "path": "examples/05-07_str-split.mjs",
    "content": "// Splitting a string based on a space separator\nconst str1 = 'Hello, world!'\nconst splitArray1 = str1.split(' ')\nconsole.log(splitArray1)\n// Output: [\"Hello,\", \"world!\"]\n\n// Splitting a string based on a comma separator with a specified limit\nconst str2 = 'apple,orange,banana,grape'\nconst splitArray2 = str2.split(',', 2)\nconsole.log(splitArray2)\n// Output: [\"apple\", \"orange\"]\n\n// Splitting a string into individual characters\nconst str3 = 'Hello'\nconst splitArray3 = str3.split('')\nconsole.log(splitArray3)\n// Output: [\"H\", \"e\", \"l\", \"l\", \"o\"]\n"
  },
  {
    "path": "examples/05-08_str-toUppercase.mjs",
    "content": "const str = 'Hello, world!'\n\n// Converting a string to uppercase\nconst upperCasedString = str.toUpperCase()\nconsole.log(upperCasedString) // Output: \"HELLO, WORLD!\"\n"
  },
  {
    "path": "examples/05-09_str-toLowercase.mjs",
    "content": "const str = 'Hello, World!'\n\n// Converting a string to lowercase\nconst lowercasedString = str.toLowerCase()\nconsole.log(lowercasedString) // Output: \"hello, world!\"\n"
  },
  {
    "path": "examples/05-10_str-startsWith.mjs",
    "content": "const str = 'Hello, world!'\n\n// Checking if a string starts with a specific substring\nconst startsWithHello = str.startsWith('Hello')\nconsole.log(startsWithHello) // Output: true\n\n// Checking if a string starts with a substring at a specific position\nconst startsWithWorld = str.startsWith('world', 7)\nconsole.log(startsWithWorld) // Output: true\n\nconst startsWithHelloWithPosition = str.startsWith('hello', 7)\nconsole.log(startsWithHelloWithPosition) // Output: false\n\n// Checking if a string starts with a substring at a position beyond the string length\nconst startsWithBeyondLength = str.startsWith('world', 15)\nconsole.log(startsWithBeyondLength) // Output: false\n\n// Checking if a string starts with a substring using a negative position\nconst startsWithUniverseNegative = str.startsWith('universe', -20)\nconsole.log(startsWithUniverseNegative) // Output: false\n\nconst startsWithHelloNegative = str.startsWith('Hello', -20)\nconsole.log(startsWithHelloNegative) // Output: true\n"
  },
  {
    "path": "examples/05-11_str-replaceAll.mjs",
    "content": "const str = 'Hello, world! Hello again, world!'\n\n// Replacing all occurrences of a substring\nconst replacedHello = str.replaceAll('Hello', 'Hi')\nconsole.log(replacedHello) // Output: \"Hi, world! Hi again, world!\"\n\n// Replacing all occurrences of a substring that's not found\nconst replacedUniverse = str.replaceAll('universe', 'galaxy')\nconsole.log(replacedUniverse) // Output: \"Hello, world! Hello again, world!\"\n\n// Replacing using a regular expression\nconst replacedWorldWithRegex = str.replaceAll(/world/g, 'earth')\nconsole.log(replacedWorldWithRegex) // Output: \"Hello, earth! Hello again, earth!\"\n\n// Replacing case-sensitive strings (no match due to case sensitivity)\nconst replacedCaseSensitive = str.replaceAll('hello', 'Hi')\nconsole.log(replacedCaseSensitive) // Output: \"Hello, world! Hello again, world!\"\n\n// Replacing special characters\nconst strWithSymbols = 'This is a $test$ string with $symbols$'\nconst replacedSymbols = strWithSymbols.replaceAll('$', '#')\nconsole.log(replacedSymbols) // Output: \"This is a #test# string with #symbols#\"\n\n// Replacing a string with an empty string (removal)\nconst removedWorld = str.replaceAll('world', '')\nconsole.log(removedWorld) // Output: \"Hello, ! Hello again, !\"\n\n// Trying to replace a substring in an empty string\nconst emptyString = ''\nconst replacedInEmpty = emptyString.replaceAll('world', 'earth')\nconsole.log(replacedInEmpty) // Output: \"\"\n"
  },
  {
    "path": "examples/05-12_str-trimstart-trimend.mjs",
    "content": "// Trimming Whitespace from the Start and End of a String\n\n// Removing Whitespace from the Start: trimStart()\n\n// Example 1: Using trimStart() to remove leading whitespace\nconst str1 = \"   Hello, World!   \";\nlet trimmedStr1 = str1.trimStart();\nconsole.log(trimmedStr1); \n// Output: \"Hello, World!   \"\n\n\n// Removing Whitespace from the End: trimEnd()\n\n// Example 1: Using trimEnd() to remove trailing whitespace\nconst str3 = \"   Hello, World!   \";\nlet trimmedStr3 = str3.trimEnd();\nconsole.log(trimmedStr3); \n// Output: \"   Hello, World!\"\n\n"
  },
  {
    "path": "examples/05-13_str-trim.mjs",
    "content": "// Examples for String.trim()\n\n// Basic usage - removing spaces from both ends\nconst greeting = '   Hello world!   '\nconsole.log(`Original: \"${greeting}\"`)\nconsole.log(`Trimmed: \"${greeting.trim()}\"`)\n// Output: Trimmed: \"Hello world!\"\n\n// Removing various whitespace characters\nconst text = '\\t\\n  JavaScript is awesome!  \\n\\r'\nconsole.log(`Original: \"${text.replace(/\\n/g, '\\\\n').replace(/\\t/g, '\\\\t').replace(/\\r/g, '\\\\r')}\"`)\nconsole.log(`Trimmed: \"${text.trim()}\"`)\n// Output: Trimmed: \"JavaScript is awesome!\"\n\n// Chaining with other string methods\nconst userInput = '   heLLo@eXampLe.com   '\nconst normalizedEmail = userInput.trim().toLowerCase()\nconsole.log(`Original: \"${userInput}\"`)\nconsole.log(`Normalized: \"${normalizedEmail}\"`)\n// Output: Normalized: \"hello@example.com\"\n\n// Form validation example\nfunction validateUsername(username) {\n    const trimmedUsername = username.trim()\n    return trimmedUsername.length >= 3\n}\n\nconsole.log(`Validating '   user   ': ${validateUsername('   user   ')}`) // true\nconsole.log(`Validating '  ab  ': ${validateUsername('  ab  ')}`) // false\n\n// Data cleaning example\nconst csvData = ['  name ', ' age ', ' city  ']\nconst cleanData = csvData.map(item => item.trim())\nconsole.log('Original CSV data:', csvData)\nconsole.log('Cleaned data:', cleanData)\n// Output: Cleaned data: [\"name\", \"age\", \"city\"]\n"
  },
  {
    "path": "examples/05-14_str-endsWith.mjs",
    "content": "// Examples for String.endsWith()\n\n// Basic usage\nconst sentence = 'This is a complete sentence.'\nconsole.log(`\"${sentence}\" ends with \"sentence.\": ${sentence.endsWith('sentence.')}`)\n// Output: true\nconsole.log(`\"${sentence}\" ends with \"question.\": ${sentence.endsWith('question.')}`)\n// Output: false\n\n// Using the length parameter\nconst filename = 'document.pdf'\nconsole.log(`\"${filename}\" ends with \"pdf\": ${filename.endsWith('pdf')}`)\n// Output: true\n\n// Check if the first 8 characters end with 'doc'\nconsole.log(`First 8 chars of \"${filename}\" end with \"doc\": ${filename.endsWith('doc', 8)}`)\n// Output: true\n\n// Case sensitivity\nconst text = 'JavaScript is awesome!'\nconsole.log(`\"${text}\" ends with \"awesome!\": ${text.endsWith('awesome!')}`)\n// Output: true\nconsole.log(`\"${text}\" ends with \"AWESOME!\": ${text.endsWith('AWESOME!')}`)\n// Output: false\n\n// File extension validation\nfunction isImageFile(filename) {\n    const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp']\n    return imageExtensions.some(ext => filename.toLowerCase().endsWith(ext))\n}\n\nconsole.log(`\"vacation.jpg\" is an image file: ${isImageFile('vacation.jpg')}`)\n// Output: true\nconsole.log(`\"document.pdf\" is an image file: ${isImageFile('document.pdf')}`)\n// Output: false\n\n// URL validation\nfunction isSecureGoogleUrl(url) {\n    return url.toLowerCase().endsWith('.google.com') && url.startsWith('https://')\n}\n\nconsole.log(`\"https://www.google.com\" is a secure Google URL: ${isSecureGoogleUrl('https://www.google.com')}`)\n// Output: true\nconsole.log(`\"http://www.google.com\" is a secure Google URL: ${isSecureGoogleUrl('http://www.google.com')}`)\n// Output: false\n\n// String formatting validation\nfunction endsWithPunctuation(text) {\n    const punctuation = ['.', '!', '?']\n    return punctuation.some(p => text.endsWith(p))\n}\n\nconsole.log(`\"Hello world!\" ends with punctuation: ${endsWithPunctuation('Hello world!')}`)\n// Output: true\nconsole.log(`\"Hello world\" ends with punctuation: ${endsWithPunctuation('Hello world')}`)\n// Output: false\n"
  },
  {
    "path": "examples/05-15_str-substring.mjs",
    "content": "// Examples for String.substring()\n\n// Basic usage\nconst text = 'JavaScript'\nconsole.log('Original text:', text)\nconsole.log('text.substring(0, 4):', text.substring(0, 4)) // Output: \"Java\"\nconsole.log('text.substring(4):', text.substring(4)) // Output: \"Script\"\n\n// Handling out-of-range indices\nconst shortText = 'Hello'\nconsole.log('\\nOriginal text:', shortText)\nconsole.log('shortText.substring(-3, 2):', shortText.substring(-3, 2)) // Output: \"He\" (negative treated as 0)\nconsole.log('shortText.substring(2, 10):', shortText.substring(2, 10)) // Output: \"llo\" (out of range)\n\n// Swapping parameters\nconsole.log('\\nDemonstrating parameter swapping:')\nconsole.log('text.substring(4, 0):', text.substring(4, 0)) // Output: \"Java\" (swaps indices)\nconsole.log('text.substring(0, 4):', text.substring(0, 4)) // Output: \"Java\" (for comparison)\n\n// Comparison with slice()\nconsole.log('\\nComparing substring() with slice():')\nconsole.log('text.substring(-3):', text.substring(-3)) // Output: \"JavaScript\" (treats -3 as 0)\nconsole.log('text.slice(-3):', text.slice(-3)) // Output: \"ipt\" (counts from the end)\n\n// Extracting a portion of text\nfunction truncateText(text, maxLength) {\n    if (text.length <= maxLength) {\n        return text\n    }\n    return text.substring(0, maxLength) + '...'\n}\n\nconst longText = 'This is a very long text that needs to be truncated'\nconsole.log('\\nTruncating text:')\nconsole.log('Original:', longText)\nconsole.log('Truncated to 20 chars:', truncateText(longText, 20)) // Output: \"This is a very long...\"\n\n// Parsing URL components\nfunction getDomainFromUrl(url) {\n    // Remove protocol\n    let domain = url\n    if (url.indexOf('://') > -1) {\n        domain = url.substring(url.indexOf('://') + 3)\n    }\n\n    // Remove path\n    if (domain.indexOf('/') > -1) {\n        domain = domain.substring(0, domain.indexOf('/'))\n    }\n\n    return domain\n}\n\nconsole.log('\\nExtracting domain from URL:')\nconsole.log('URL: https://example.com/path')\nconsole.log('Domain:', getDomainFromUrl('https://example.com/path')) // Output: \"example.com\"\n\n// Removing specific characters\nfunction removeFirstAndLastChar(text) {\n    return text.substring(1, text.length - 1)\n}\n\nconsole.log('\\nRemoving first and last characters:')\nconsole.log('Original: \"quoted\"')\nconsole.log('Result:', removeFirstAndLastChar('\"quoted\"')) // Output: \"quoted\" "
  },
  {
    "path": "examples/05-16_str-replace.mjs",
    "content": "// Examples for String.replace()\n\n// Basic usage with string pattern\nconst text = 'Hello, world!'\nconsole.log('Original text:', text)\nconst newText = text.replace('world', 'JavaScript')\nconsole.log('After replace:', newText) // Output: \"Hello, JavaScript!\"\n\n// Using regular expression\nconst text2 = 'The quick brown fox jumps over the lazy dog.'\nconsole.log('\\nOriginal text:', text2)\nconst newText2 = text2.replace(/fox|dog/g, 'animal')\nconsole.log('After replace with regex:', newText2)\n// Output: \"The quick brown animal jumps over the lazy animal.\"\n\n// Case-insensitive replacement\nconst text3 = 'JavaScript is awesome. javascript is fun.'\nconsole.log('\\nOriginal text:', text3)\nconst newText3 = text3.replace(/javascript/i, 'TypeScript')\nconsole.log('After case-insensitive replace:', newText3)\n// Output: \"TypeScript is awesome. javascript is fun.\"\n\n// Using function as replacement\nconst text4 = 'apple orange banana'\nconsole.log('\\nOriginal text:', text4)\nconst newText4 = text4.replace(/apple|orange|banana/g, match => match.toUpperCase())\nconsole.log('After replace with function:', newText4)\n// Output: \"APPLE ORANGE BANANA\"\n\n// Text formatting - Phone number\nfunction formatPhoneNumber(phoneNumber) {\n    // Format: XXX-XXX-XXXX\n    return phoneNumber.replace(/(\\d{3})(\\d{3})(\\d{4})/, '$1-$2-$3')\n}\n\nconsole.log('\\nFormatting phone number:')\nconsole.log('1234567890 ->', formatPhoneNumber('1234567890'))\n// Output: \"123-456-7890\"\n\n// Sanitizing user input\nfunction sanitizeHTML(text) {\n    const map = {\n        '&': '&amp;',\n        '<': '&lt;',\n        '>': '&gt;',\n        '\"': '&quot;',\n        \"'\": '&#039;'\n    }\n    return text.replace(/[&<>\"']/g, m => map[m])\n}\n\nconsole.log('\\nSanitizing HTML:')\nconsole.log('<script>alert(\"XSS\")</script> ->', sanitizeHTML('<script>alert(\"XSS\")</script>'))\n// Output: \"&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;\"\n\n// URL slug creation\nfunction createSlug(title) {\n    return title\n        .toLowerCase()\n        .replace(/\\s+/g, '-')     // Replace spaces with -\n        .replace(/[^\\w-]+/g, '')  // Remove all non-word chars\n        .replace(/--+/g, '-')     // Replace multiple - with single -\n        .replace(/^-+/, '')       // Trim - from start of text\n        .replace(/-+$/, '')       // Trim - from end of text\n}\n\nconsole.log('\\nCreating URL slug:')\nconsole.log('Hello World! This is a Title ->', createSlug('Hello World! This is a Title'))\n// Output: \"hello-world-this-is-a-title\" "
  },
  {
    "path": "examples/05-17_str-lastIndexOf.mjs",
    "content": "// Examples for String.lastIndexOf()\n\n// Basic usage\nconst text = 'JavaScript is amazing. JavaScript is fun.'\nconsole.log('Original text:', text)\nconst lastIndex = text.lastIndexOf('JavaScript')\nconsole.log('Last index of \"JavaScript\":', lastIndex) // Output: 25\n\n// Using fromIndex parameter\nconsole.log('\\nSearching with fromIndex:')\nconst lastIndex2 = text.lastIndexOf('JavaScript', 20)\nconsole.log('Last index of \"JavaScript\" before position 20:', lastIndex2) // Output: 0\n\n// Searching for a character\nconst text2 = 'Hello, world!'\nconsole.log('\\nOriginal text:', text2)\nconst lastIndex3 = text2.lastIndexOf('o')\nconsole.log('Last index of \"o\":', lastIndex3) // Output: 8\n\n// Not found case\nconst lastIndex4 = text2.lastIndexOf('z')\nconsole.log('Last index of \"z\" (not found):', lastIndex4) // Output: -1\n\n// File extension extraction\nfunction getFileExtension(filename) {\n    const dotIndex = filename.lastIndexOf('.')\n    return dotIndex === -1 ? '' : filename.substring(dotIndex + 1)\n}\n\nconsole.log('\\nExtracting file extensions:')\nconsole.log('document.pdf ->', getFileExtension('document.pdf')) // Output: \"pdf\"\nconsole.log('image.large.jpg ->', getFileExtension('image.large.jpg')) // Output: \"jpg\"\nconsole.log('noextension ->', getFileExtension('noextension')) // Output: \"\"\n\n// Finding the last word in a sentence\nfunction getLastWord(sentence) {\n    const lastSpaceIndex = sentence.lastIndexOf(' ')\n    return lastSpaceIndex === -1 ? sentence : sentence.substring(lastSpaceIndex + 1)\n}\n\nconsole.log('\\nFinding the last word:')\nconsole.log('Hello, world! ->', getLastWord('Hello, world!')) // Output: \"world!\"\nconsole.log('JavaScript ->', getLastWord('JavaScript')) // Output: \"JavaScript\"\n\n// Checking if a string ends with a specific substring\nfunction endsWith(str, suffix) {\n    const position = str.lastIndexOf(suffix)\n    return position !== -1 && position === str.length - suffix.length\n}\n\nconsole.log('\\nChecking if string ends with substring:')\nconsole.log('Does \"Hello, world!\" end with \"world!\"?', endsWith('Hello, world!', 'world!')) // Output: true\nconsole.log('Does \"Hello, world!\" end with \"Hello\"?', endsWith('Hello, world!', 'Hello')) // Output: false\n\n// Compare with built-in endsWith method\nconsole.log('\\nComparing with built-in endsWith method:')\nconsole.log('Using built-in: \"Hello, world!\".endsWith(\"world!\") =', 'Hello, world!'.endsWith('world!'))\nconsole.log('Using built-in: \"Hello, world!\".endsWith(\"Hello\") =', 'Hello, world!'.endsWith('Hello')) "
  },
  {
    "path": "examples/05-18_str-match.mjs",
    "content": "// Examples for String.match()\n\n// Basic usage with global flag\nconst text = 'The rain in Spain stays mainly in the plain'\nconsole.log('Original text:', text)\nconst matches = text.match(/ain/g)\nconsole.log('Matches for /ain/g:', matches) // Output: [\"ain\", \"ain\", \"ain\"]\n\n// Without global flag\nconsole.log('\\nWithout global flag:')\nconst match = text.match(/ain/)\nconsole.log('Match for /ain/:', match)\n// Output includes the match, index, input string, and groups\n\n// Using capturing groups\nconst text2 = 'JavaScript was created in 1995'\nconsole.log('\\nOriginal text:', text2)\nconst matchWithGroups = text2.match(/(\\w+) was created in (\\d+)/)\nconsole.log('Match with capturing groups:')\nconsole.log('Full match:', matchWithGroups[0])\nconsole.log('Group 1 (language):', matchWithGroups[1])\nconsole.log('Group 2 (year):', matchWithGroups[2])\n\n// No match case\nconst text3 = 'Hello, world!'\nconsole.log('\\nOriginal text:', text3)\nconst noMatch = text3.match(/xyz/)\nconsole.log('Match for /xyz/:', noMatch) // Output: null\n\n// Extracting information from text\nfunction extractEmails(text) {\n    const emailRegex = /[\\w.-]+@[\\w.-]+\\.\\w+/g\n    return text.match(emailRegex) || []\n}\n\nconst content = 'Contact us at support@example.com or sales@example.com for assistance.'\nconsole.log('\\nExtracting emails:')\nconsole.log('Original text:', content)\nconsole.log('Extracted emails:', extractEmails(content))\n// Output: [\"support@example.com\", \"sales@example.com\"]\n\n// Parsing data from formatted text\nfunction parseCSVLine(line) {\n    return line.match(/(\".*?\"|[^,]+)(?=,|$)/g)\n        .map(item => item.replace(/^\"|\"$/g, ''))\n}\n\nconst csvLine = 'John,\"Doe,Jr\",42,\"New York, NY\"'\nconsole.log('\\nParsing CSV line:')\nconsole.log('Original CSV:', csvLine)\nconsole.log('Parsed values:', parseCSVLine(csvLine))\n// Output: [\"John\", \"Doe,Jr\", \"42\", \"New York, NY\"]\n\n// Validating input format\nfunction isValidUsername(username) {\n    // Alphanumeric, 3-16 characters\n    const match = username.match(/^[a-z0-9]{3,16}$/i)\n    return match !== null\n}\n\nconsole.log('\\nValidating usernames:')\nconsole.log('Is \"user123\" valid?', isValidUsername('user123')) // Output: true\nconsole.log('Is \"us\" valid?', isValidUsername('us')) // Output: false (too short)\nconsole.log('Is \"user@123\" valid?', isValidUsername('user@123')) // Output: false (invalid character)\n\n// Counting words\nfunction countWords(text) {\n    const words = text.toLowerCase().match(/\\b\\w+\\b/g) || []\n    return words.length\n}\n\nconst paragraph = 'The quick brown fox jumps over the lazy dog.'\nconsole.log('\\nCounting words:')\nconsole.log('Text:', paragraph)\nconsole.log('Word count:', countWords(paragraph)) // Output: 9 "
  },
  {
    "path": "examples/06-01_process-cwd.mjs",
    "content": "// Simple example of using process.cwd()\n\n// 1. Get and display the current working directory\nconsole.log('Current working directory:')\nconsole.log(process.cwd())\n\n// 2. Use process.cwd() to create a file path\nconst path = require('path')\nconst filePath = path.join(process.cwd(), 'example.txt')\n\nconsole.log('\\nFile path using current working directory:')\nconsole.log(filePath)\n\n// 3. Display the components of the file path\nconsole.log('\\nComponents of the file path:')\nconsole.log('Directory:', path.dirname(filePath))\nconsole.log('File name:', path.basename(filePath))\n\n// Note: This example doesn't create or modify any files\n"
  },
  {
    "path": "list-of-functions.md",
    "content": "- [x] 01-00 **System**\n- [x] 01-01 Info from CPU: `os.cpus()`\n- [x] 01-02 Info from Operating System: `os.version()` and `os.platform()`\n- [x] 01-03 Info from current user: `os.userInfo()`\n- [x] 01-04 Access to environment variables: `process.env`\n- [x] 01-05 Get the amount of free memory in bytes (as integer): `os.freemem()`\n- [x] 01-06 Get the amount of total memory available in bytes (as integer): `os.totalmem()`\n- [x] 01-07 The load average of CPU: `os.loadavg()`\n- [x] 01-08 Network interfaces information: `os.networkInterfaces()`\n- [x] 01-09 Stop the execution with a proper status code: `process.exit()`\n- [x] 01-10 Get temporary directory: `os.tmpdir()`\n- [x] 01-11 Get monotonic time: `performance.now()`\n\n- [x] 02-00 **Array**\n- [x] 02-01 Create a string from an array: `join()`\n- [x] 02-02 Check if the array includes a certain value: `includes()`\n- [x] 02-03 Check if a key exists in the array: `in`\n- [x] 02-04 Concat arrays: `concat()`\n- [x] 02-05 Concat arrays via destructuring\n- [x] 02-06 Remove duplicate values in an array via `Set(`)`\n- [x] 02-07 Generate and fill a new array `fill()`\n- [x] 02-08 Filtering elements: `filter()`\n- [x] 02-09 Testing all elements: `every()`\n- [x] 02-10 Testing at least one element: `some()`\n- [x] 02-11 Mapping new array: `map()`\n- [x] 02-12 Reduce array: `reduce()`\n- [x] 02-13 Modify array: `splice()`\n- [x] 02-14 Extracting elements: `slice()`\n- [x] 02-15 Flat nested array: `flat()`\n- [x] 02-16 Find the index of an element that matches a condition `findIndex()`\n- [x] 02-17 Allows accessing elements using positive or negative indices `at()`\n- [x] 02-18 First maps each element using a mapping function, then flattens the result into a new array `flatMap()`\n- [x] 02-19 Returns a new Array Iterator object that contains the keys (indices) for each index in the array `keys()`\n- [x] 02-20 Returns a new Array Iterator object that contains key/value pairs for each index in the array `entries()`\n- [x] 02-21 returns the last index of the element in the array that satisfies the provided testing function `findLastIndex()`\n- [x] 02-22 returns the last element in the array that satisfies the provided testing function `findLast()`\n- [x] 02-23 Shallow copies part of an array to another location in the same array `copyWithin()`\n- [x] 02-25 returns a new Array Iterator object that contains the values for each index in the array `values()`\n- [x] 02-26 Sorts the elements of an array in place `sort()`\n- [x] 02-27 Reverses the order of elements in an array in place `reverse()`\n- [x] 02-28 Adding and removing elements from the end of an array `push()` and `pop()`\n- [x] 02-29 Adding and removing elements from the beginning of an array `shift()` and `unshift()`\n\n- [x] 03-00 **Variables, constants, Object**\n- [x] 03-01 Get variable type: `typeof`\n- [x] 03-02 Portable directory separator: `path.sep`\n- [x] 03-03 Portable end of line: `os.EOL`\n- [x] 03-04 Gets the properties of the given object: `getOwnPropertyNames()`\n- [x] 03-05 Getting all the Object properties/attributes: `keys()`\n- [x] 03-06 Object values: `values()`\n- [x] 03-07 Object entries: `entries()`\n- [x] 03-08 Object freeze: `freeze()`\n- [x] 03-09 Object seal: `seal()`\n- [x] 03-10 Object is frozen: `isFrozen()`\n- [x] 03-11 Object is sealed: `isSealed()`\n- [ ] 03-12 Groups elements of an array based on a function, either returning an object `groupBy()` https://github.com/roberto-butti/some-drops-of-javascript/issues/64\n- [ ] 03-13 Transforms a list of key-value pairs into an object: `fromEntries()`\n\n- [x] 04-00 **Functions**\n\n- [x] 05-00 **Strings**\n- [x] 05-01 Concatenating strings: `concat()`\n- [x] 05-02 Padding Strings: `padStart()` `padEnd()`\n- [x] 05-03 String includes: `includes()`\n- [x] 05-04 Slicing strings: `slice()`\n- [x] 05-05 Finding index: `indexOf()`\n- [x] 05-06 Repeating a string: `repeat()`\n- [x] 05-07 Splitting a String into an Array: `split()`\n- [x] 05-08 Upper case: `toUpperCase()`\n- [x] 05-09 Lower case: `toLowerCase()`\n- [x] 05-10 Start with: `startWith()`\n- [ ] 05-11 Replaces all occurrences of a substring in a string: `replaceAll()`\n- [ ] 05-12 Removes whitespace from the beginning or end of a String `trimStart()` and `trimEnd()`\n- [x] 05-13 Removes whitespace from both ends of a String: `trim()`\n- [x] 05-14 Checking if a string ends with a specific substring: `endsWith()`\n- [x] 05-15 Extracting parts of a string: `substring()`\n- [x] 05-16 Replacing substrings in a string: `replace()`\n- [x] 05-17 Finding the last occurrence of a substring: `lastIndexOf()`\n- [x] 05-18 Matching strings against regular expressions: `match()`\n\n- [x] 06-00 **Files**\n- [ ] 06-01 Current directory: `process.cwd()` https://github.com/roberto-butti/some-drops-of-javascript/issues/53\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"some-drops-of-javascript\",\n  \"type\": \"module\",\n  \"version\": \"0.0.1\",\n  \"scripts\": {\n    \"dev\": \"astro dev\",\n    \"start\": \"astro dev\",\n    \"build\": \"astro build\",\n    \"preview\": \"astro preview\",\n    \"astro\": \"astro\",\n    \"format-examples\": \"npx prettier ./examples/ --write\",\n    \"format-examples-bun\": \"bunx prettier ./examples/ --write\"\n  },\n  \"dependencies\": {\n    \"@astrojs/starlight\": \"0.31.0\",\n    \"@astrojs/starlight-tailwind\": \"3.0.0\",\n    \"@astrojs/tailwind\": \"^5.1.5\",\n    \"astro\": \"5.1.6\",\n    \"sharp\": \"^0.33.5\"\n  },\n  \"devDependencies\": {\n    \"bun-types\": \"^1.2.16\",\n    \"daisyui\": \"^4.12.24\"\n  },\n  \"trustedDependencies\": [\n    \"esbuild\",\n    \"sharp\"\n  ]\n}\n"
  },
  {
    "path": "src/components/about-block.astro",
    "content": "---\ninterface Props {\n  title: string\n}\n\nconst { title } = Astro.props\n---\n\n<article class=\"sl-flex\" aria-labelledby=\"about-astro-heading\">\n  <small id=\"about-astro-heading\">\n    {title}\n    <span class=\"sr-only\">Some Drops of JavaScript</span>\n  </small>\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 630 630\">\n<rect width=\"630\" height=\"630\" fill=\"#f7df1e\"/>\n<path d=\"m423.2 492.19c12.69 20.72 29.2 35.95 58.4 35.95 24.53 0 40.2-12.26 40.2-29.2 0-20.3-16.1-27.49-43.1-39.3l-14.8-6.35c-42.72-18.2-71.1-41-71.1-89.2 0-44.4 33.83-78.2 86.7-78.2 37.64 0 64.7 13.1 84.2 47.4l-46.1 29.6c-10.15-18.2-21.1-25.37-38.1-25.37-17.34 0-28.33 11-28.33 25.37 0 17.76 11 24.95 36.4 35.95l14.8 6.34c50.3 21.57 78.7 43.56 78.7 93 0 53.3-41.87 82.5-98.1 82.5-54.98 0-90.5-26.2-107.88-60.54zm-209.13 5.13c9.3 16.5 17.76 30.45 38.1 30.45 19.45 0 31.72-7.61 31.72-37.2v-201.3h59.2v202.1c0 61.3-35.94 89.2-88.4 89.2-47.4 0-74.85-24.53-88.81-54.075z\"/>\n</svg>  <slot />\n</article>\n\n<style>\n  article {\n    max-width: 40rem;\n    margin-inline: auto;\n    padding-block: 5rem;\n    flex-direction: column;\n    align-items: center;\n    text-align: center;\n    gap: 0.5rem;\n  }\n  article > :global(*) {\n    max-width: 50ch;\n    margin-top: 0 !important;\n  }\n  small {\n    color: var(--sl-color-gray-3);\n  }\n  svg {\n    width: 15rem;\n  }\n</style>\n"
  },
  {
    "path": "src/components/arrow.astro",
    "content": "<svg\n  class=\"w-5 h-5 ml-2 -mr-1\"\n  fill=\"currentColor\"\n  viewBox=\"0 0 20 20\"\n  xmlns=\"http://www.w3.org/2000/svg\"\n  ><path\n    fill-rule=\"evenodd\"\n    d=\"M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z\"\n    clip-rule=\"evenodd\"></path></svg\n>\n"
  },
  {
    "path": "src/components/hero.astro",
    "content": "---\ninterface Props {\n  title: string\n}\n\nconst { title } = Astro.props\nimport Arrow from './arrow.astro'\nimport { Image } from 'astro:assets'\n\nimport coverImage from '../assets/some-drops-of-javascript-cover-square.png'\n---\n\n<section class=\"bg-base-100\">\n  <div\n    class=\"grid max-w-screen-xl px-4 py-8 mx-auto lg:gap-8 xl:gap-0 lg:py-16 lg:grid-cols-12\"\n  >\n    <div class=\"mr-auto place-self-center lg:col-span-7\">\n      <h1\n        class=\"base-content max-w-2xl mb-4 text-4xl font-extrabold tracking-tight leading-none md:text-5xl xl:text-6xl\"\n      >\n        Some drops of JavaScript is an open source e-book.\n      </h1>\n      <p\n        class=\"max-w-2xl mb-6 font-light base-content lg:mb-8 md:text-lg lg:text-xl\"\n      >\n        This book compiles a collection of useful, lesser-known, and underrated\n        JavaScript functions and techniques. These discoveries have been made,\n        utilized, and refined through daily JavaScript programming practice.\n      </p>\n      <a\n        href=\"/00-intro/01_contributing/\"\n        class=\"inline-flex items-center justify-center px-5 py-3 mr-3 text-base font-medium text-center text-white rounded-lg bg-primary-700 hover:base-300 focus:ring-4 focus:ring-primary-300 dark:focus:ring-primary-900\"\n      >\n        Contribute\n        <Arrow />\n      </a>\n      <a\n        href=\"/00-intro/00_intro\"\n        class=\"inline-flex items-center justify-center px-5 py-3 text-base font-medium text-center text-gray-900 border border-gray-300 rounded-lg hover:base-300 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-800\"\n      >\n        Read the Book\n        <Arrow />\n      </a>\n    </div>\n    <div class=\"hidden lg:mt-0 lg:col-span-5 lg:flex\">\n      <Image\n        src={coverImage}\n        alt=\"Some Drops of JavaScript is an open source e-book.\"\n      />\n    </div>\n  </div>\n</section>\n"
  },
  {
    "path": "src/content/docs/00-intro/00_intro.md",
    "content": "---\ntitle: Some drops of JavaScript\ndescription: This HTML eBook collects some useful, unknown, underrated JavaScript functions or stuff discovered, used, and learned during JavaScript daily use.\nsidebar:\n  label: About the eBook\n---\n\n\n\n## The reason why\nThis book collects practical, unknown, or underrated JavaScript functions or things discovered, used, and learned during daily JavaScript use.\n\nWhen using JavaScript frameworks/libraries daily (like React, Vue, Angular, and Svelte), sometimes one needs to catch up on the language's power and the basic functionalities the JavaScript core provides.\nI notice that I usually look at the framework documentation or find a package in NPM for the system, array, and string functions instead of using the core functionalities provided by the language.\n\nWhile I wrote this HTML book, I also wrote some scripts to better understand the functions' behavior. You can find these examples in the examples directory at https://github.com/roberto-butti/some-drops-of-javascript.\n\n### Requirements\n\nThe code used in this book is tested with **Bun (latest)** and **Node.js (LTS)**.\n\n**Bun** is a JavaScript runtime, package manager, bundler, and test runner built from scratch using the Zig programming language. Jarred Sumner designed it as a drop-in replacement for Node.js. Bun uses JavaScriptCore as the JavaScript engine, unlike Node.js and Deno, which both use V8. The official website is: https://bun.sh/ .\n\n**Node.js** is an open-source, cross-platform JavaScript runtime environment. You can obtain it on the official https://nodejs.org/ website.\n\n\n### Continuous release\n\nI was thinking of printing this book, but I think it is not eco-friendly, and a book about development could be improved daily regarding spellchecking, content, and examples. I expect to adopt the same approach in the software with the CI/CD, with a continuous release of the book.\n\nReleases:\n\n- **W.I.P.** the 1.0.0 version has not yet been released: writing... ;\n\n> The book is a Work in Progress, and the list of currently covered functions is in the [list-of-functions.md](list-of-functions.md) file\n\nSo, if you have any feedback or you want to suggest some corrections, feel free to open an issue here: https://github.com/roberto-butti/some-drops-of-javascript/issues\n\n### Where to find this book\n\nThis book is available for download for free here: https://github.com/roberto-butti/some-drops-of-javascript/\n\n### Thanks to...\n\nThanks to all the Open Source community.\n\n### License\n\"Some drops of JavaScript\" (c) by Roberto Butti.\n\n\"Some drops of JavaScript\" is licensed under a\nCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.\n\nYou should have received a copy of the license along with this\nwork. If not, see <http://creativecommons.org/licenses/by-nc-sa/4.0/>.\n"
  },
  {
    "path": "src/content/docs/00-intro/01_contributing.md",
    "content": "---\ntitle: The Open Source eBook\ndescription: We are excited to invite you to join our repository and contribute to the open-source book project. We welcome contributors with various skills and interests, so whether you're a JavaScript expert, a grammar enthusiast, a design aficionado, or just someone with a passion for learning and sharing knowledge, there's a place for you in our open-source book project.\n\nsidebar:\n  label: How to contribute\n  badge:\n    text: New\n    variant: tip\nbanner:\n  content: |\n    The open-source eBook,\n    <a href=\"https://github.com/roberto-butti/some-drops-of-javascript\">feel free to contribute adding or reviewing content</a>\n\n---\n\nHello, amazing contributors! 👋\n\nWe are excited to invite you to join our [repository](https://github.com/roberto-butti/some-drops-of-javascript) and contribute to the open-source book project. We welcome contributors with various skills and interests, so whether you're a JavaScript expert, a grammar enthusiast, a design aficionado, or just someone with a passion for learning and sharing knowledge, there's a place for you in our open-source book project.\n\n\n## Ways to Contribute\n\nHere are some of the ways you can get involved:\n\n- **JavaScript Wizards**: Write pages for JavaScript functions, share your expertise, and help fellow developers understand some nice JavaScript functions.\n\n- **Reviewers and Editors**: Help ensure the quality and accuracy of the content by reviewing and editing pages.\n\n- **Grammar Enthusiasts**: Review and improve our documentation's English grammar and readability.\n\n- **Idea Contributors**: Suggest JavaScript functions that should be covered in the documentation. Your insights are valuable!\n\n- **Design Gurus**: Propose design changes that can enhance the overall user experience of our book.\n\n## How to Get Started\n\n1. Fork the repository to your GitHub account.\n2. Create a new branch for your contributions.\n3. Make your changes and commit them.\n4. Open a pull request to merge your changes back into the main repository.\n\nFor more detailed instructions, please check our [Contribution Guidelines](https://github.com/roberto-butti/some-drops-of-javascript/blob/main/CONTRIBUTING.md).\n\n## Join the Conversation\n\nHave questions or want to discuss your contributions? Join us in the [repository](https://github.com/roberto-butti/some-drops-of-javascript/issues) issue section](https://github.com/roberto-butti/some-drops-of-javascript/issues), where you can create issues but also create suggestions, and feature requests.\n\n## Thank You!\n\nWe deeply appreciate your willingness to contribute to the open-source book \"Some Drops of JavaScript\". Your efforts significantly impact the JavaScript community, and we're grateful for your support.\n\n:::tip[Thank you to all the contributors]\nI want to say a special thank you to all the [contributors](https://github.com/roberto-butti/some-drops-of-javascript/graphs/contributors).\n:::\n\nThank you! 🚀\n"
  },
  {
    "path": "src/content/docs/00-intro/01_hacktoberfest-2024.md",
    "content": "---\ntitle: Hacktoberfest and \"Some drops of JavaScript\"\ndescription: How to contribute for Hacktoberfest.\nsidebar:\n  label: Hacktoberfest 2024\n  badge:\n    text: Contribute\n    variant: tip\nbanner:\n  content: |\n    The open-source eBook,\n    <a href=\"https://github.com/roberto-butti/some-drops-of-javascript\">feel free to contribute adding or reviewing content for Hacktoberfest</a>\ndraft: true\n---\n\n\n\n![Some drops of JavaScript and Hacktoberfest 2024](../../../assets/header-hacktoberfest-2024.png)\n\nHello amazing contributors! 👋\n\nWe are excited to invite you to join our Hacktoberfest celebration by contributing to our open-source book project. We welcome contributors with various skills and interests, so whether you're a JavaScript expert, a grammar enthusiast, a design aficionado, or just someone with a passion for learning and sharing knowledge, there's a place for you in our community.\n\n## Ways to Contribute\n\nHere are some of the ways you can get involved:\n\n- **JavaScript Wizards**: Write pages for JavaScript functions, share your expertise, and help fellow developers understand some nice JavaScript functions.\n\n- **Reviewers and Editors**: Help ensure the quality and accuracy of the content by reviewing and editing pages.\n\n- **Grammar Enthusiasts**: Review and improve our documentation's English grammar and readability.\n\n- **Idea Contributors**: Suggest JavaScript functions that should be covered in the documentation. Your insights are valuable!\n\n- **Design Gurus**: Propose design changes that can enhance the overall user experience of our book.\n\n## How to Get Started\n\n1. Fork the repository to your GitHub account.\n2. Create a new branch for your contributions.\n3. Make your changes and commit them.\n4. Open a pull request to merge your changes back into the main repository.\n\nFor more detailed instructions, please check our [Contribution Guidelines](https://github.com/roberto-butti/some-drops-of-javascript/blob/main/CONTRIBUTING.md).\n\n## Join the Conversation\n\nHave questions or want to discuss your contributions? Join us in the repository issue section, where you can create issues, suggestions, and feature requests.\n\n## Say Thank You!\n\nWe deeply appreciate your willingness to contribute to the open-source book \"Some Drops of JavaScript\". Your efforts significantly impact the JavaScript community, and we're grateful for your support.\n\nHappy Hacking! 🚀\n"
  },
  {
    "path": "src/content/docs/00-intro/02_runtime.md",
    "content": "---\ntitle: What is JavaScript?\ndescription: JavaScript, the language, the engine, and the runtime.\nsidebar:\n  label: What is JavaScript?\n---\n\n## Javascript Langauge\n\nJavaScript is a high-level, versatile, and widely used programming language. Originally created for web development to make web pages interactive, JavaScript has since expanded its scope and can now be used in various environments, including server-side development, mobile app development, and even desktop application building.\n\nJavaScript is a dynamically typed language, meaning that variable types are determined at runtime.\n\nJavaScript is an interpreted language that allows developers to execute code without requiring a compilation step.\n\nJavaScript relies on the ECMAScript standard as its foundation, ensuring a standardized set of rules and features that promote consistency and compatibility across various JavaScript implementations.\n\n## JavaScript Engine\n\nA JavaScript engine interprets and executes the code.\nJavaScript engines play a crucial role by converting JavaScript code into machine code, facilitating efficient execution and performance optimization.\n\nJavaScript engines use Just-In-Time (JIT) compilation to execute the code.\n\nJust-In-Time (JIT) compilation is a key technique employed by JavaScript engines to boost performance. Instead of interpreting the entire JavaScript code at once, JIT compilation dynamically translates specific portions of the code into machine code during runtime. This on-the-fly translation allows the engine to optimize the execution of frequently used code, resulting in faster and more efficient JavaScript programs.\n\nThere is more than one engine; the most common are:\n\n- **V8** is an open-source JavaScript and WebAssembly engine developed by Google. It is written in C++ and used in the Google Chrome web browser and the Node.js runtime. V8 is designed to execute JavaScript code at high speeds and has become a crucial component for improving the performance of web applications.\n- **SpiderMonkey** is the JavaScript engine developed by Mozilla, the organization behind the Firefox web browser. It is an open-source engine written in C++ that interprets and executes JavaScript code within the Firefox browser.\n- **JavaScriptCore** is the open-source JavaScript engine part of the WebKit project. WebKit is a browser engine primarily developed by Apple and used in Safari and other browsers on Apple platforms. JavaScriptCore, known as Nitro, is responsible for interpreting and executing JavaScript code within the WebKit browser engine. JavaScriptCore is used also by the Bun runtime.\n\n## JavaScript Runtime\n\nA JavaScript runtime uses the JavaScript engine to execute the JavaScript code. Additionally, a JavaScript runtime provides some APIs or functionalities to interact with the hosting environment. For example, a JavaScript runtime can provide API for interaction with the Browser (for the Brower Javascript runtimes) or can provide API for interacting with the filesystem (for non-browser JavaSCript runtimes like Node.js and Bun.js).\n\nFor example, the most common JavaScript runtimes are:\n\n- **Bun** runtime is a fast JavaScript runtime is designed as a drop-in replacement for Node.js. It's written in Zig and powered by JavaScriptCore under the hood, dramatically reducing startup times and memory usage.\n- **Node.js** is an open-source, cross-platform JavaScript runtime built on the V8 JavaScript engine. It allows developers to run JavaScript code on the server side, enabling the development of server-side and network applications. Node.js is event-driven and non-blocking, efficiently handling many concurrent connections.\n- **Browser** is a runtime environment within a web browser where JavaScript client-side code is executed. It provides APIs for interacting with the browser the Fetch API for making network requests, the Web Storage API for local data storage, and the Geolocation API for location-based services.\n"
  },
  {
    "path": "src/content/docs/01-system/00_system_intro.md",
    "content": "---\ntitle: System functions\ndescription: The chapter covers functions about \"system\" functionalities (for example how to retrieve the operating system version, environment variables, memory usage, CPU usage, user information etc.).\nsidebar:\n  label: System functions\n---\n\n# System\nIn this chapter, we will explore how to interact with system-level functionalities using JavaScript. While JavaScript is often associated with front-end development, it can also be a powerful tool for retrieving and managing system information, especially in server-side environments. JavaScript provides several built-in modules that allow us to access vital details about the underlying system, offering a deeper understanding of the environment where the code is running.\n\nThis chapter will introduce key functions and techniques to help you access critical system information, such as:\n\n- **Operating System Information:** Learn how to retrieve details like the operating system version, platform type, architecture, and uptime. This is useful for cross-platform applications where behavior may vary depending on the environment.\n- **Environment Variables:** Discover how to access and manipulate environment variables, which are often used for configuration purposes in development, staging, and production environments.\n- **Memory and CPU Usage:** We'll look into monitoring system resource consumption, including memory and CPU usage, to help optimize performance and detect potential bottlenecks or issues.\n- **User and Process Information:** Find out how to gather data about the current user, home directory, system processes, and more. This is particularly valuable in user-centric or process-driven applications.\n\nBy the end of this chapter, you'll have the tools to write JavaScript code that effectively interacts with the system, enhancing your ability to monitor, debug, and optimize your applications. Whether you are building a desktop tool, a server-side script, or need to gain insights into your deployment environment, this chapter will give you a solid foundation for handling system-related tasks using JavaScript.\n"
  },
  {
    "path": "src/content/docs/01-system/01_os-cpus.md",
    "content": "---\ntitle: \"CPUs information\"\ndescription: \"Retrieving the list of the available CPUs\"\nsidebar:\n  label: CPUs information\n---\n## Info from CPU: `os.cpus()`\n\nThe `os` module allows you to retrieve relevant information about the environment used for running your _Node.js_ script or application.\n\n```javascript\nimport { cpus } from 'os'\nconst c = cpus()\n```\n\nThe `os` module provides you with some methods. One is the `cpus()` that returns the list of CPUs available in your environment. For each element of the list (each element is one CPU), you have the `model` attribute that has the CPU model name (for example, \"Apple M1 Pro\") and the `speed` attribute, an integer for showing the speed of the CPU.\nThen you have also `times` attribute for the times (in milliseconds) that the CPU has spent in these modes: `user`, `nice` (valid only for Posix systems, in Windows this value is always 0), `sys`, `idle`, `irq`.\n\nIt returns:\n\nAn array of objects, where each object represents a **logical** CPU core and contains the following properties:\n- `model` (string): The model of the CPU.\n- `speed` (number): The speed of the CPU in MHz.\n- `times` (object): An object containing the number of milliseconds the CPU has spent in different modes:\n  - `user` (number): Time spent in user mode.\n  - `nice` (number): Time spent in nice mode.\n  - `sys` (number): Time spent in system mode.\n  - `idle` (number): Time spent in idle mode.\n  - `irq` (number): Time spent servicing interrupts.\n\nSo, you can walk through the list of CPUs:\n\n```js\nimport { cpus } from 'os'\ncpus().forEach(cpu => {\n  console.info(cpu.model + ' speed: ' + cpu.speed)\n  console.table(cpu.times)\n})\n```\n\n\n### Calculating the CPU utilization\n\nYou can use the `os.cpus()` function to calculate the utilization of each CPU core, which is helpful for performance monitoring and workload analysis.\n\n```javascript\nimport { cpus } from 'os'\nconsole.log(\"*** Calculating the CPU utilization ***\")\ncpus().forEach((cpu, index) => {\n  const { user, nice, sys, idle, irq } = cpu.times;\n  const total = user + nice + sys + idle + irq;\n\n  const usage = ((total - idle) / total) * 100;\n  console.log(`CPU ${index + 1} Usage: ${usage.toFixed(2)}%`);\n});\n```\n\n### Identifying the Number of Logical CPU Cores\n\nIn scenarios where you need to determine the number of **logical CPU cores** available for parallel processing, you can use `os.cpus()` as follows:\n\n\n```javascript\nimport { cpus } from 'os'\nconst numCpus = cpus().length;\n\nconsole.log(`Number of logical CPU cores: ${numCpus}`);\n```\n\nThe `os.cpus()` function returns an array where each element represents a logical CPU core. The length of this array gives the number of logical CPU cores available.\nThis is particularly useful when creating worker threads or child processes to maximize CPU utilization.\n\n### Common Pitfalls\n\n- Misunderstanding Logical vs. Physical Cores: The `os.cpus()` function returns the number of logical cores, not physical cores. In systems with hyper-threading, the number of logical cores will be higher than that of physical cores.\n- Platform-Specific Behavior: The data returned by `os.cpus()` may vary slightly depending on the operating system. If your application needs to run on multiple OS types, ensure compatibility and testing across different platforms.\n\n### Resources\n\n- Node.js Documentation: [os.cpus](https://nodejs.org/api/os.html#oscpus)\n- Chapter: Get the amount of total memory available in bytes [os.totalmem()](/01-system/06_os-totalmem/)\n- Chapter: Get the amount of free memory in bytes [os.freemem()](/01-system/05_os-freemem/)\n"
  },
  {
    "path": "src/content/docs/01-system/02_os-version.md",
    "content": "---\ntitle: \"OS information\"\nsidebar:\n  label: OS information\n---\nIf you need to retrieve information about the Operating System, like the version, the release, the platform, the release, you can use some functions implemented by the `os` module.\n\n## The Operating System version: `os.version()`\nThe `os` module has the `version()` method to return the version of the Operating System in use.\n\n~~~javascript\nimport { version } from 'os'\nconst version = version()\nconsole.log(v)\n~~~\n\nThe `version()` method returns a string with the full name of the Operating System version, like this:\n\n~~~\nDarwin Kernel Version 21.6.0: Wed Aug 10 14:28:23 PDT 2022; root:xnu-8020.141.5~2/RELEASE_ARM64_T6000\n~~~\n\n## The Operating System platform: `os.platform()`\n\nThe `os` module has the `platform()` function to return the name of the platform of the Operating System in use.\n\n~~~javascript\nimport { platform } from 'os'\nconst platform = platform()\nconsole.log(platform)\n~~~\n\nThe `platform()` method returns a string with the name of the platform Operating System version, like for example: `aix`, `android`, `darwin`, `freebsd`,`linux`, `openbsd`, `sunos`, or `win32`.\nIf you are running Node on a Mac OS machine, you will obtain `darwin`.\n"
  },
  {
    "path": "src/content/docs/01-system/03_os-userinfo.md",
    "content": "---\ntitle: \"Getting user information\"\nsidebar:\n  label: User information\n---\nWhen you launch a Node script, you will launch it with a specific operating system user. The user used for launcing the script determines the permission of the script.\nIf you need to retrieve the information related to the current user you can use `userInfo()` function.\n\n## Info for the current user: `os.userInfo()`\nThe `os` module has the `userInfo`()` method to return information on the current system user.\n\n```javascript\nimport { userInfo } from 'os'\nconst u = userInfo()\n```\n\nThe `userInfo()` method returns an object with attributes:\n\n- `uid`: the user identifier (integer)\n- `gid`: the group identifier (integer)\n- `username`: the username (string)\n- `homedir`: the user's home directory (string)\n- `shell`: the user's shell (string)\n"
  },
  {
    "path": "src/content/docs/01-system/04_process-env.md",
    "content": "---\ntitle: \"Access to environment variables: process.env\"\nsidebar:\n  label: Environment Vars\n---\n\n## Access to environment variables: process.env\n\nThe `process` global module has the `env` attribute to return information on the environment variable.\nThe `process.env` attribute contains an object and it represents the list of environment variables. Each attribute is an environment variable.\nThe `process` module is a global module, which means that you don't have to import the process module manually, but it is automatically available in your code.\n\nFor retrieving the environment variables object:\n```javascript\nconsole.log(process.env)\n```\n\nIf you want to access a specific environment variable via the name (for example to the `PATH` environment variable):\n```javascript\nconsole.log(process.env.PATH)\n```\n\nIf you have to access dynamically to an environment variable, you can use the square brackets:\n```javascript\nconst envVarName = 'PATH'\nif (envVarName in process.env) {\n  console.log(process.env[envVarName])\n} else {\n  console.log('no %s defined', envVarName)\n}\n```\n\nIf you want to walk through all the environment variables you can iterate on the object attributes via `Object.keys()` method:\n\n```javascript\nObject.keys(process.env).forEach(function (key, index) {\n  console.log(key, index, process.env[key])\n})\n```\n"
  },
  {
    "path": "src/content/docs/01-system/05_os-freemem.md",
    "content": "---\ntitle: \"Get the amount of free memory in bytes (as integer): `os.freemem()`\"\nsidebar:\n  label: Free memory\n---\n\n## Get the amount of free memory in bytes (as integer): `os.freemem()`\nThe `os` module has the `freemem()` method to return information on the free memory available in the system.\nThe `freemem()` function returns an integer and it represents the bytes. If you need megabytes or kilobytes you have to convert it.\n\n```javascript\nimport { freemem } from 'os'\nconst mem = freemem()\nconsole.log('The amount of free memory is %d bytes', mem)\n```\n"
  },
  {
    "path": "src/content/docs/01-system/06_os-totalmem.md",
    "content": "---\ntitle: \"Get the amount of total memory available in bytes\"\nsidebar:\n  label: Available memory\n---\n\n## Get the amount of total memory available in bytes (as integer): `os.totalmem()`\n\nThe `os` module has the `totalmem()` method to return information on the total memory available in the system.\nThe `totalmem()` function returns an integer and it represents the bytes. If you need megabytes or kilobytes you have to convert it.\n\n```javascript\nimport { totalmem } from 'os'\nconst mem = totalmem()\nconsole.log(\n  'Hi, the total memory is %d gigabytes',\n  mem / 1024 / 1024 / 1024\n)\n```\n"
  },
  {
    "path": "src/content/docs/01-system/07_os-loadavg.md",
    "content": "---\ntitle: \"Getting the load average of CPU\"\nsidebar:\n  label: CPU load\n---\n\n## The load average of CPU: `os.loadavg()`\n\nThe `os` module has the `loadavg()` method to return the \"load\" measurement information about the CPU usage of the system.\nThe \"load\" measurement is calculated by the number of processes that are being executed by the CPU or in a 'waiting' state.\n\nThe `loadavg()` function returns an array with 3 float numbers. These three numbers represents the average system load calculated over a given period of 1, 5 and 15 minutes\n\n\n```javascript\nimport { loadavg } from 'os'\nconst la = loadavg()\nconsole.log(\n  la[0], // last minute\n  la[1], // last 5 minutes\n  la[2]  // last 15 minutes\n)\n// it returns: 1.59619140625 2.42822265625 2.60400390625\n```\n\n>{quote} On Windows machine this functionality is not available, the method returns an array with 0 values, like `[0, 0, 0]`\n"
  },
  {
    "path": "src/content/docs/01-system/08_os-networkinterfaces.md",
    "content": "---\ntitle: \"Getting the network interfaces information\"\nsidebar:\n  label: Network interfaces\n---\n\n## Network interfaces information: `os.networkInterfaces()`\n\nThe `os` module has the `networkInterfaces()` method to return the object that shows the information about the network interfaces available on the system.\nThe object has multiple interfaces.\nEach interface has an identifier used as an object key attribute like `lo0`, `en0`, `utun0`, `utun1` ... etc.\nEach interface has an array of addresses.\nEach address is an object like this one:\n\n```json\n{\n    address: '127.0.0.1',\n    netmask: '255.0.0.0',\n    family: 4,\n    mac: '00:00:00:00:00:00',\n    internal: true,\n    cidr: '127.0.0.1/8'\n}\n```\n\nWhere `address`, `netmask`, `mac`, `cidr` are the address (ip address, mac addres) and netmask.\nThe `family` attribute identifies the type of the ip protocol.\nThe `internal` attribute is a boolean value, `true` if the address is remotely accessible.\n\n```javascript\nimport { networkInterfaces } from 'os'\nconst ni = networkInterfaces()\n\nObject.keys(ni).forEach(function (key, index) {\n  // each interfaces has an array\n  ni[key].forEach(function (element, index) {\n    // selecting only family === 4 (ipv4 interfaces)\n    if (element.family === 4) {\n      console.log('IP ADDRESS: ' + element.address) // IPv4 address\n    }\n  })\n})\n```\n"
  },
  {
    "path": "src/content/docs/01-system/09_process-exit.md",
    "content": "---\ntitle: \"Stopping the script execution\"\nsidebar:\n  label: Stop execution\n---\n\n## Stop the script execution: `process.exit()`\n\nThe `process` global module has the `exit()` method to stop the current execution and return to the shell, or in general to the environment where the script was launched.\nAll the processes can return a status code to the shell. By convention, if the execution ends correctly a status code value equal to 0 is returned. In case of an error, the process can return a not 0 status code value.\nSo if you want to stop the execution of the script and return a status code equal to 99 you can use `process.exit(99)` like the example:\n\n```javascript\nconsole.log('Executing ...')\nprocess.exit(99)\nconsole.log('Never executed')\n```\n\nExecuting this snippet, a `99` status code error will be returned to the shell.\nFor example, once the script execution is terminated, you can test the shell environment variable `$?` that contains the status code of the last process executed. If you execute in a shell (`bash` or `zsh` or some other shell) the node script and then try to show the last status code via `echo $?`:\n\n```bash\nnode examples/01-09_process-exit.mjs\necho $?\n```\n\nYou will see the `99` value will be shown in the terminal (because the JS script returns with `process.exit(99)`)."
  },
  {
    "path": "src/content/docs/01-system/10_os-tmpdir.md",
    "content": "---\ntitle: \"Getting the temporary directory absolute path\"\nsidebar:\n  label: Temp directory\n---\n\n## Getting the temporary directory: `os.tmpdir()`\n\nIf you need to store temporary a file in your script, you can save the temporary file in the default operating system temporary directory.\nYou can retrieve the current operating system temporary directory via `tmpdir()` function:\n\n```javascript\nimport { tmpdir } from 'os'\nconsole.log('Temporary directory: %s', tmpdir())\n```\n"
  },
  {
    "path": "src/content/docs/01-system/11_performance-now.md",
    "content": "---\ntitle: \"Tracking the execution time getting the monotonic time\"\nsidebar:\n  label: Tracking time\n---\n\n## Getting monotonic time: `performance.now()`\n\nIf you have to track execution time or the time spent in a script or a long-running application, you have to keep in mind that while you are executing your script and your logic the date time of the operating system could change because the user adjusts the hour, or the date time is adjusted automatically by the NTP system.\nSo if you want to track the millisecond spent executing a logic you need a monotonic time.\nIn JavaScript (Node.js) you have a kind of stopwatch that is started at the beginning of the execution of the script.\nThis timer is used for measuring performance because is a relative metric and it isn't affected by system clock changes.\n\n```javascript\n// saving the timer in startTime\nlet startTime = performance.now()\nconsole.log('Starting')\n// calculating the time by difference performance.now() - startTime\nconsole.log(performance.now() - startTime, startTime)\n```"
  },
  {
    "path": "src/content/docs/02-array/00_array.md",
    "content": "---\ntitle: \"Array\"\ndescription: The chapter will cover functions about \"array\" functionalities\nsidebar:\n  label: Introduction\n---\n\n# Handling the Array data structures\nThis chapter will explore one of JavaScript's most fundamental and versatile data structures: **arrays**.\n\nArrays are essential in any JavaScript developer’s toolkit, enabling efficient data storage and manipulation. Understanding how to work with arrays is key to writing clean, performant, and maintainable code.\n\nThis chapter will guide you through a wide range of **array manipulation techniques** and functions, helping you to harness the full power of arrays in your projects. You will learn how to perform operations such as:\n\n- **Filtering Arrays:** We'll explore how to extract subsets of data from arrays using the `filter()` method. This method allows you to remove unwanted or irrelevant elements based on specific criteria, which is useful for tasks like filtering search results or handling large datasets.\n- **Mapping Arrays:** The `map()` method transforms arrays by applying a function to each element and returning a new array with the modified values. You’ll see how this can format data, calculate new values, or manipulate objects within arrays.\n- **Reducing Arrays:** Learn how to condense an entire array into a single value using the powerful `reduce()` method. Whether you need to sum a list of numbers, accumulate object properties, or process data streams, `reduce()` provides a flexible way to handle complex transformations.\n- **Sorting and Reversing Arrays:** We'll cover how to sort arrays alphabetically, numerically, or based on custom logic, and how to reverse their order when needed. Sorting data efficiently is crucial for many real-world applications, such as organizing user lists, rankings, or search results.\n- **Finding and Checking Values:** You'll learn to search for specific elements in an array using methods like `find()`, `findIndex()`, `includes()`, and `some()`, which enable you to locate data points or verify if certain conditions are met within your array.\n- **Merging, Splitting, and Slicing Arrays:** You’ll understand how to combine arrays, extract portions of arrays, and break them into smaller parts using methods like `concat()`, `slice()`, and `splice()`. This is helpful when working with large datasets or implementing features like pagination.\n\nThrough real-world examples and use cases, this chapter will demonstrate how these array methods can be applied to solve common programming challenges, such as data manipulation, search optimization, and efficient iteration. By the end of the chapter, you’ll not only master array manipulation techniques but also understand how to use them to write more concise, expressive, and scalable JavaScript code."
  },
  {
    "path": "src/content/docs/02-array/01_array-join.md",
    "content": "---\ntitle: \"Create a string from an array: `join()`\"\nsidebar:\n  label: From array to string\n---\n\n## Create a string from an array: `join()`\n\nIf you want to generate a string, joining all the array elements, you can use the `join()` method. By default, the character is used as separator. If you want to use a specific separator you can call the join('-') method with the separator needed as the first argument.\n\n```javascript\nconst elements = ['kiwi', 'strawberry', 'lemon']\n\nconsole.log(elements.join())\n// expected output: \"kiwi,strawberry,lemon\"\nconsole.log(elements.join('-'))\n// expected output: \"kiwi-strawberry-lemon\"\n```"
  },
  {
    "path": "src/content/docs/02-array/02_array-includes.md",
    "content": "---\ntitle: \"Check if the array includes a certain value: `includes()`\"\nsidebar:\n  label: Checking an item\n---\n\n## Check if the array includes a certain value: `includes()`\n\nIf you want to check if the array includes a specific value, you can use `includes()` method. The first mandatory input argument of `includes()` method is the value of the element you want to check.\n\n```javascript\nconst elements = ['kiwi', 'strawberry', 'lemon']\n\nconsole.log(elements.includes('strawberry'))\n// Does the array include the 'strawberry'?\n// expected output: true\n```\n\nIf you want to check if the value is included starting from a specific index you can use the second input parameter for setting the index (remember to start from 0 for counting the position).\n\n```javascript\nconst elements = ['kiwi', 'strawberry', 'lemon']\n\nconsole.log(elements.includes('strawberry', 2))\n// Does the array starting from index 2, include the 'strawberry'?\n// expected output: false\n```\n"
  },
  {
    "path": "src/content/docs/02-array/03_array-in.md",
    "content": "---\ntitle: \"Check if a property exists in the object or array: `in`\"\nsidebar:\n  label: Checking a property\n---\n\n## Check if a property exists in the object or array: `in`\n\nIf you have an object and you want to check if a property is present you can use the `in` operator.\n\n```javascript\nconst fruits = {\n  strawberry: 'Strawberry',\n  kiwi: 'Kiwi',\n  lemon: 'Lemon'\n}\n// for checking the presence of an property you can use in operator\nif ('kiwi' in fruits) {\n  console.log('Kiwi is present')\n}\n// you can use in the short form\nconsole.log('kiwi' in fruits ? 'Yes! Kiwi' : 'ther is no kiwi here')\n```\n\nI think the `in` operator is one of the best ways to check the presence of a property because, for example, if you want to check if the value is `undefined`, you can't distinguish the cases if the property doesn't exist or the property exists and has an undefined value:\n\n```javascript\nconst fruits = {\n  strawberry: 'Strawberry',\n  kiwi: 'Kiwi',\n  lemon: 'Lemon'\n}\n\nfruits.something = undefined\nif (fruits.somethingelse === undefined) {\n    console.log('Somethingelse property does not exist')\n}\nif (fruits.something === undefined) {\n  console.log('Something property exists but the value is undefined')\n}\n```\n\nThe `in` operator works also with the arrays. With the arrays, you can check the presence of the numeric index:\n\n```javascript\nconst fruitsArray = []\nfruitsArray.push('Strawberry')\nfruitsArray.push('Kiwi')\nfruitsArray.push('Lemon')\nconsole.dir(fruitsArray)\nconsole.log(2 in fruitsArray) // true\nconsole.log(3 in fruitsArray) // false\n```"
  },
  {
    "path": "src/content/docs/02-array/04_array-concat.md",
    "content": "---\ntitle: \"Concatenate two (or more) arrays: `concat()`\"\nsidebar:\n  label: Concatenating arrays\n---\n\n## Concatenate two (or more) arrays: `concat()`\n\nYou can concatenate (append) two or more arrays with the `concat()` method.\n\n```javascript\nconst array1 = ['a', 'b', 'c']\nconst array2 = ['d', 'e', 'f']\nconsole.dir(array1.concat(array2)) // ['a', 'b', 'c', 'd', 'e', 'f']\n```\n\nyou can concatenate more arrays:\n\n```javascript\nconst array1 = ['a', 'b', 'c']\nconst array2 = ['d', 'e', 'f']\nconst array3 = ['g', 'h']\nconsole.dir(array1.concat(array2, array3))\nconsole.dir([].concat(array1, array2, array3))\n```"
  },
  {
    "path": "src/content/docs/02-array/05_array-merge_destructuring.md",
    "content": "---\ntitle: \"Concat arrays via destructuring\"\nsidebar:\n  label: Concatenating arrays via destructuring\n---\n\n## Concat arrays via destructuring\nFor concatenating or merging two or more arrays, you can use the destructuring technique.\n\nWith this technique essentially you are going to unpack the arrays into a list of distinct variables, and use this list to recreate a new array with square brackets.\n\n```js\nconst array1 = ['a', 'b', 'c']\nconst array2 = ['d', 'e', 'f']\nconsole.dir([...array1, ...array2])\n// [ 'a', 'b', 'c', 'd', 'e', 'f' ]\n```\n\nYou can use this technique with more than 2 arrays:\n```js\nconst array1 = ['a', 'b', 'c']\nconst array2 = ['d', 'e', 'f']\nconst array3 = ['g', 'h']\nconsole.dir([...array1, ...array2, ...array3])\n// [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ]\n```\nThe order you are using the `[...array1, ...array2, ...array3]` is important because determines the order of the items for the new array\n```js\nconst array1 = ['a', 'b', 'c']\nconst array2 = ['d', 'e', 'f']\nconst array3 = ['g', 'h']\nconsole.dir([...array3, ...array2, ...array1])\n// [ 'g', 'h', 'd', 'e', 'f', 'a', 'b', 'c' ]\n```\n"
  },
  {
    "path": "src/content/docs/02-array/06_array-set.md",
    "content": "---\ntitle: \"Remove duplicate values in an array via `Set()`\"\nsidebar:\n  label: Removing duplicates\n---\n\n## Remove duplicate values in an array via `Set()`\n\nIf you want to remove duplicates from an array there is no specific array method for removing duplicate elements but you can achieve this using destructuring, the `Set()` function and recreating the array.\nIt means that the original array will not change.\n```js\nconst array = ['a', 'b', 'c', 'b', 'd', 'e', 'a']\nconst unique = [...new Set(array)]\n// [ 'a', 'b', 'c', 'd', 'e' ]\n```\n"
  },
  {
    "path": "src/content/docs/02-array/07_array-fill.md",
    "content": "---\ntitle: \"Generate and fill a new array `fill()`\"\nsidebar:\n  label: Filling an array\n---\n\n## Generate and fill a new array `fill()`\n\nThe `fill()` method sets a specific value to the elements of the array.\n\nIf you have an array with some values:\n\n```js\nconst array = ['a', 'b', 'c', 'b', 'd', 'e', 'a']\n```\nand you want to replace/fill the elements with the value `0`, you can call `fill()` method on the array, using `0` as a parameter:\n\n```js\narray.fill(0)\n// [ 0, 0, 0, 0, 0, 0, 0 ]\n```\n\nAs you can see the `fill()` method changes the content of the original array. The size of the array will be the same as the original one.\n\nThe `fill()` method has two more optional parameters about the starting index to apply the changes and the ending index.\nFor example, if you want to replace values starting with the second element (remember 0 index array):\n\n```js\nconst array2 = ['a', 'b', 'c', 'b', 'd', 'e', 'a']\narray2.fill(\n    0, // the value to fill\n    1 // the index where to start\n)\nconsole.dir(array2)\n// [ 'a', 0, 0, 0, 0, 0, 0 ]\n```\n\nyou can also set the last index to apply the replacement. For example, if you want to replace elements from index 1 (the second element) until index 3 (the third element included):\n```js\nconst array3 = ['a', 'b', 'c', 'b', 'd', 'e', 'a']\narray3.fill(\n    0, // the value to fill\n    1 // the index where to start\n    3 // the index where to end\n)\nconsole.dir(array3)\n// [ 'a', 0, 0, 'b', 'd', 'e', 'a' ]\n```\n\nIf you want to fill/replace the last element you can use the negative index:\n\n```js\nconst array4 = ['a', 'b', 'c', 'b', 'd', 'e', 'a']\narray4.fill(0, -1) // last element\nconsole.dir(array4)\n// [ 'a', 'b', 'c', 'b', 'd', 'e', 0 ]\narray4.fill(0, -2) // last 2 elements\nconsole.dir(array4)\n// [ 'a', 'b', 'c', 'b', 'd', 0, 0 ]\n```\n"
  },
  {
    "path": "src/content/docs/02-array/08_array-filter.md",
    "content": "---\ntitle: \"Filtering elements: `filter()`\"\nsidebar:\n  label: Filtering elements\n---\n\n## Filtering elements: `filter()`\n\nWith the arrays, you have the `filter()` method to filter the elements of the array with a specific condition. For example with an array of numbers, you want to retrieve only the element greater than 50.\nThe `filter()` doesn't change the original array. It returns a new array with the elements that satisfy the condition.\n\n```js\nconst numbers = [3, 75, 42, 13, 69]\nconst resultNumbers = numbers.filter(\n    number => number >= 50\n)\nconsole.dir(resultNumbers)\n// output: Array [ 75, 69 ]\n```\n\nIf the element is an object you can filter for the attribute of the object. For example, if you have objects like this one:\n```\n{ product: 'Desk', price: 200, active: true }\n```\nand you have an array of elements, and you want to filter and retrieve the object with a price greater (or equal) than 150:\n\n```js\nconst elements = [\n  { product: 'Desk', price: 200, active: true },\n  { product: 'Chair', price: 100, active: true },\n  { product: 'Door', price: 300, active: false },\n  { product: 'Bookcase', price: 150, active: true },\n  { product: 'Door', price: 100, active: true }\n]\n\nconst resultElements = elements.filter(\n    element => element.price >= 150\n)\nconsole.dir(resultElements)\n```\n\nthe result is:\n\n```\nArray [\n  { product: 'Desk', price: 200, active: true },\n  { product: 'Door', price: 300, active: false },\n  { product: 'Bookcase', price: 150, active: true }\n]\n```\n\nyou can create a more complex conditions like:\n\n```js\nconst resultActiveElements = elements.filter(\n    element =>\n    (element.active && element.price >= 150)\n)\n```\n\nwhere the result is:\n\n```\nArray [\n  { product: 'Desk', price: 200, active: true },\n  { product: 'Bookcase', price: 150, active: true }\n]\n```"
  },
  {
    "path": "src/content/docs/02-array/09_array-every.md",
    "content": "---\ntitle: \"Testing all elements: `every()`\"\nsidebar:\n  label: Checking all the elements\n---\n\n## Testing all elements: `every()`\n\nIf you have an array and you want to check if all the elements satisfy a certain condition, you can use `every()` method on Array.\nFor example, if you want to check that all the array elements are greater than 25, you can use this example:\n\n```js\n// the array\nconst array = [32, 30, 39, 29, 100, 43]\n\nconsole.log(\n  array.every(\n    (currentValue) => currentValue > 25\n  )\n)\n\n\n```"
  },
  {
    "path": "src/content/docs/02-array/10_array-some.md",
    "content": "---\ntitle: \"Testing at least one element: `some()`\"\nsidebar:\n  label: Checking at least one element\n---\n\n## Testing at least one element: `some()`\n\nIf you have an array and you want to check if at least one of the elements satisfies a certain condition, you can use `some()` method on Array.\nFor example, if you want to check that at least one element of the array is greater than 90, you can use this example:\n\n```js\nconst array = [32, 30, 39, 29, 100, 43]\n\nconsole.log(\n  array.some(\n    (currentValue) => currentValue > 90\n  )\n)\n```"
  },
  {
    "path": "src/content/docs/02-array/11_array-map.md",
    "content": "---\ntitle: 'Mapping an Array: `map()`'\nsidebar:\n  label: Mapping Array\n---\n\n## Mapping an Array: `map()`\n\nThe `map()` method in JavaScript allows you to create a new array by applying a function to each element of an existing array. It iterates through the elements of the original array, performs a specified operation on each element, and returns a new array with the results.\n\n### Example\n\nSuppose you have an array of numbers and you want to create a new array where each number is doubled. You can use the `map()` method as shown in this example:\n\n```js\nconst numbers = [1, 2, 3, 4, 5]\n\n// Using map() method to create a new array by doubling each number\nconst doubledNumbers = numbers.map((number) => number * 2)\n\nconsole.log('Original Array:', numbers)\nconsole.log('Doubled Array:', doubledNumbers)\n```\n"
  },
  {
    "path": "src/content/docs/02-array/12_array-reduce.md",
    "content": "---\ntitle: 'Reducing an Array'\nsidebar:\n  label: Reducing Array\n---\n\n## Reducing an Array: `reduce()`\n\nThe `reduce()` method is a powerful array method in JavaScript used to reduce an array into a single value. It iterates over each element of the array and applies a callback function to accumulate a result.\n\nThe `reduce()` function takes two main arguments: the callback function and an (_optional_) initial value.\n\nThe callback function is called for each element in the array and is responsible for accumulating the result. The result is then carried over to the next iteration. The final result is returned after iterating through all the array elements.\n\n```js\n//Syntax\nreduce(callbackFn)\nreduce(callbackFn, initialValue)\n\ncallbackFn(accumulator, currentValue, currentIndex, array)\n```\n\n- `callbackFn`: A function that is called for each element in the array. It takes four arguments:\n  - `accumulator`: The accumulated result from previous iterations or the initial value.\n  - `currentValue`: The current element being processed in the array.\n  - `currentIndex`: (Optional) The index of the current element being processed.\n  - `array`: (Optional) The array reduce() was called upon.\n\n- `initialValue`: (Optional) The initial value for the accumulator. If not provided, the first element of the array is used as the initial value.\n\n### Examples\n\n_Example 1_, let's use the `reduce()` to find the sum of all elements in an array:\n\n```js\nconst numbers = [1, 2, 3, 4, 5]\n\nconst sumWithInitialValue = numbers.reduce((accumulator, currentValue) => {\n  return accumulator + currentValue\n}, 0) //Here 0 is an initial value to the accumulator\n\n/* Here if we do not mention initialValue '0', then initial value of accumulator will be first array value\nand the currentValue will be second value of Array. */\nconst sumWithoutInitialValue = numbers.reduce((acc, curr) => {\n  return acc + curr\n})\n\nconsole.log('SumWithInitialValue:', sumWithInitialValue)\nconsole.log('SumWithoutInitialValue:', sumWithoutInitialValue)\n```\n\n_Example 2_, counting the number of occurrences of elements in an array using `reduce()`:\n\n```js\nconst fruits = ['🍎', '🍓', '🍋', '🍎', '🍋', '🍎']\n\nconst fruitCounter = fruits.reduce((accumulator, currentFruit) => {\n  accumulator[currentFruit] = (accumulator[currentFruit] || 0) + 1\n  return accumulator\n}, {})\n\nconsole.log('Occurrences:', fruitCounter)\n// Output: Occurrences: {\n  \"🍎\": 3,\n  \"🍓\": 1,\n  \"🍋\": 2\n}\n```\n"
  },
  {
    "path": "src/content/docs/02-array/13_array-splice.md",
    "content": "---\ntitle: 'Modifying an Array'\ndescription: 'Adding, removing, and replacing elements in an array with JavaScript.'\nsidebar:\n  label: Modifying Array\n---\n\n## Adding, removing, and replacing elements in an array: `splice()`\n\nThe `splice()` method is a versatile array method in JavaScript that allows you to modify an array by adding, removing, or replacing elements. It directly changes the original array and returns an array of the removed elements.\n\nThe `splice()` method takes three main arguments: the start index, the number of elements to remove (_optional_), and the elements to add (_optional_).\n\nBy specifying a start index, you can define where the changes should occur in the array. The method can then remove a specified number of elements, add new elements, or both, depending on the parameters provided. This makes `splice()` a powerful tool for modifying arrays in place.\n\n```js\n//Syntax\nsplice(start)\nsplice(start, deleteCount)\nsplice(start, deleteCount, item1, item2, ...)\n```\n\n- `start`: The index at which to start modifying the array.\n\n- `deleteCount`: (Optional) Number of elements to remove from the array.\n\n- `item1, item2`: (Optional) Elements to add starting from the _start_ index.\n\n### Adding Elements\n\nThe `splice()` method can add new elements to an array. New elements can be inserted at the specified start index by setting the `deleteCount` parameter (the second parameter) to 0.\n\nLet's use the `splice()` method to modify an array by adding elements:\n\n```js\nconst fruits = ['Apple', 'Banana', 'Cherry', 'Date']\n\n// Adding elements\nfruits.splice(1, 0, 'Blueberry', 'Coconut') // Adds two elements at index 1\nconsole.log('Array after adding:', fruits) // Output: ['Apple', 'Blueberry', 'Coconut', 'Banana', 'Cherry', 'Date']\n```\n\n### Removing Elements\n\nThe `splice()` method can also remove elements from an array. By specifying the `start` index and `deleteCount`, a specific number of elements can be removed starting at a given position.\n\nLet's use the `splice()` method to modify an array by removing elements:\n\n```js\nconst fruits = ['Apple', 'Banana', 'Cherry', 'Date']\n\n// Removing elements\nconst removedFruits = fruits.splice(1, 2) // Removes 2 elements starting from index 1\nconsole.log('Modified array:', fruits) // Output: ['Apple', 'Date']\nconsole.log('Removed elements:', removedFruits) // Output: ['Banana', 'Cherry']\n```\n\n### Replacing Elements\n\nThe `splice()` method can replace existing elements by removing some and adding others at the same index.\n\nLet's use the `splice()` method to modify an array by replacing elements:\n\n```js\nconst fruits = ['Apple', 'Blueberry', 'Coconut', 'Date']\n\n// Replacing elements\nfruits.splice(2, 1, 'Dragonfruit') // Replaces 1 element at index 2\nconsole.log('Array after replacing:', fruits) // Output: ['Apple', 'Blueberry', 'Dragonfruit', 'Date']\n```\n### Swap elements in an array\n\nAnother useful application of the `splice()` function is to swap elements within an array.\nThis can be particularly handy when rearranging elements without using additional variables or temporary arrays. Here's how you can do it:\n\n1. Identify the indices of the two elements you want to swap.\n2. Use `splice()` to remove the element at one index and store it temporarily.\n3. Use `splice()` again to insert the removed element at the position of the other element and vice versa.\n\nHere is an example of using the `splice()` function to swap elements in an array:\n\n```js\n  const arr = ['a', 'b', 'c', 'd']\n\n  function swap(arr, index1, index2) {\n    const [elem1] = arr.splice(index1, 1)\n    const [elem2] = arr.splice(index2 - 1, 1) // '-1' adjusts for the earlier removal of 'elem1'\n    arr.splice(index1, 0, elem2)\n    arr.splice(index2, 0, elem1)\n  }\n  swap(arr, 1, 3)\n  console.log('Swapped array:', arr) // Output: ['a', 'd', 'c', 'b']\n```\n"
  },
  {
    "path": "src/content/docs/02-array/14_array-slice.md",
    "content": "---\ntitle: 'Extracting Part of an Array'\nsidebar:\n  label: Extracting Array\n---\n\n## Extracting part of an Array: `slice()`\n\nThe `slice()` method in JavaScript extracts a section of an array and returns it as a new array without modifying the original array. This method is helpful when working with a portion of an array without affecting the original one.\n\nThe `slice()` function takes two arguments: the start index (inclusive) and the end index (exclusive). The range defined by these indices is used to select elements from the array.\n\n```js\n//Syntax\nslice(start)\nslice(start, end)\n\n`start`: The index at which to start extracting elements (inclusive). If not provided, `slice()` starts from index `0`.\n`end`: (Optional) The index at which to stop extracting elements (exclusive). If not provided, `slice()` extracts up to the end of the array.\n```\n\n### Examples\n\n_Example 1_, using `slice()` to extract a subarray:\n\n```js\nconst animals = ['dog', 'cat', 'elephant', 'giraffe', 'lion']\n\nconst subArray = animals.slice(1, 4)\nconsole.log(subArray) // Output: ['cat', 'elephant', 'giraffe']\n```\n\nIn this example:\n\n- The start index is `1` (which is \"cat\"), and the end index is `4` (which is \"lion\", but since the end index is exclusive, it's not included).\n- The extracted subarray includes the elements from index `1` to `3`.\n\n_Example 2_, using `slice()` with only the start index:\n\n```js\nconst fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']\n\nconst subArrayFromIndex = fruits.slice(2)\nconsole.log(subArrayFromIndex) // Output: ['cherry', 'date', 'elderberry']\n```\n\n- In this case, by providing only the start index (2), `slice()` extracts all elements from index 2 to the end of the array.\n\n_Example 3_, using `slice()` with negative indices:\n\n```js\nconst colors = ['red', 'blue', 'green', 'yellow', 'purple']\n\nconst lastTwo = colors.slice(-2)\nconsole.log(lastTwo) // Output: ['yellow', 'purple']\n```\n\n- Negative indices can be used with `slice()`. A negative start index counts from the end of the array, so `-2` refers to the second-to-last element, and the extraction continues to the end.\n\n### Notes\n\n- Non-destructive: The `slice()` method does not modify the original array.\n- Empty array: If the start index is greater than or equal to the array length, or if the start index is greater than the end index, `slice()` returns an empty array.\n- Omitting arguments: If both start and end are omitted, `slice()` returns a shallow copy of the entire array.\n- The `slice()` method returns a shallow copy of a portion of an array into a new array object.\n- The `slice()` method can take no arguments: the start index is 0 and the end index is the length of the array.\n"
  },
  {
    "path": "src/content/docs/02-array/15_array-flat.md",
    "content": "---\ntitle: 'Flattening an Array'\ndescription: 'Flattening an Array with the flat() method'\nsidebar:\n  label: Flattening an Array\n---\n\n## Flattening an Array: `flat()`\n\nThe `flat()` method in Javascript is used to flatten an array, meaning it merges nested sub-arrays into a single array up to a specified depth. This method is helpful when working with multidimentional arrays and merging arrays with nested elements.\n\nThe `flat()` method takes `depth` as an optional argument. By default, the depth is set to 1.\n\nThe option argument `depth` is the depth level specifying how deep a nested array structure should be flattened. Defaults to 1.\n\n\n### Examples\n\n_Example 1_, using `flat()` to flatten an array:\n\n```javascript\nconst arr = [[1, 2, 3], [4, 5, 6], 7, 8];\nconsole.log(arr.flat()); // Output: [1, 2, 3, 4, 5, 6, 7, 8]\n```\n\nIn this example, the flat by default takes the depth as 1 and flattens the array to one level deep.\n\n_Example 2_, using `flat()` with a depth argument:\n\n```javascript\nconst arr2 = [1, 2, [3, 4, [5, 6]]];\nconsole.log(arr2.flat()); // Output: [1, 2, 3, 4, [5, 6]]\nconsole.log(arr2.flat(2)); // Output: [1, 2, 3, 4, 5, 6]\n```\n\nIn this example, using the flat method without the depth argument flattens the array to only one level deep. Calling `flat()` without specifying a depth will flatten only the first level of nested arrays. This means it unpacks [3, 4] from the array, but leaves [5, 6] untouched, as it's inside another nested array. \n\nHence the result [1, 2, 3, 4, [5, 6]] – where [5, 6] is still nested.\n\nBut with the depth argument set to 2, `flat(2)` will flatten the array up to two levels deep. This means it will flatten both the first level ([3, 4]) and the second level ([5, 6]) of nesting, resulting in a completely flattened array in this case.\n\nHence the result [1, 2, 3, 4, 5, 6] – where all elements are at the top level.\n\n_Example 3_, using `flat()` in an array which has empty slots (Sparse Array):\n\n```javascript\nconst arr5 = [1, 2, , 4, 5];\nconsole.log(arr5.flat()); // Output: [1, 2, 4, 5]\n```\n\nUsing `flat()` method on a sparse array not only flattens nested arrays but also removes empty slots from sparse arrays. This behavior is particularly useful when you want to ensure that your array contains only defined values.\n\n### Notes\n\n- Setting the depth argument to `Infinity`, allows you to completely flatten an array. It ensures that no matter how deeply nested the elements are, they will all be accessible at the top level of the resulting array.\n"
  },
  {
    "path": "src/content/docs/02-array/16_array-findindex.md",
    "content": "---\ntitle: 'Finding the Index'\ndescription: 'Finding the index of the first element that passes a test'\nsidebar:\n  label: Finding the Index\n---\n\n## Finding the index of the first element that passes a test: `findIndex()`\n\nThe `findIndex()` method in JavaScript searches through an array and returns the index of the first element that satisfies a provided testing function. If no such element is found, it returns -1. This method is useful for locating an element based on a specific condition without altering the original array.\n\nThe `findIndex()` function accepts a single argument: a callback function that tests each element in the array. This callback function can be customized to define the condition that the elements must meet to be considered.\n\n\n```js\n//Syntax\nfindIndex(callbackFn(currentVal, index, arr))\nfindIndex(callbackFn(currentVal, index, arr), thisArg)\n```\n\n- `callbackFn()`: A function to execute for each element in the array. It should return a truthy value to indicate a matching element has been found, and a falsy value otherwise. The function is called with the following arguments: currentVal, index and arr\n- `currentVal`: (Required) The current element being processed in the array.\n- `index`: (Optional) The index of the current element being processed in the array.\n- `arr`: (Optional) The array findIndex() was called upon.\n- `thisArg`: (Optional) The value to use as `this` when executing the callback function. By default it is undefined.\n\n\n### Examples\n\n_Example 1_, using `findIndex()` to get the index of the first element that passes the test:\n\n```js\nconst ages = [3, 10, 18, 20];\n\nlet index = ages.findIndex(checkAge);\n\nfunction checkAge(age) {\n  return age > 18;\n}\n```\n\nIn this example:\n\n- A function checkAge() is passed as a callback to `findIndex()` function\n- `findIndex()` function will execute checkAge() callback function for each element of ages array\n- The condition age > 18 holds true for element value 20 at index 3 in ages array, therefore `findIndex()` will return 3\n\n_Example 2_, `findIndex()` returns -1 when no element matches the callback function condition:\n\n```js\nconst ages = [3, 10, 13, 15];\n\nlet index = ages.findIndex(checkAge);\n\nfunction checkAge(age) {\n  return age > 18;\n}\n```\n\n- In this case, no element of ages satisfies the age > 18 condition so the `findIndex()` function will return -1.\n\n\n### Notes\n\n- Executes a function on each array element\n- Returns the index (position) of the first element that passes the test\n- Returns -1 if no match is found\n- Does not executes the function for empty array elements\n- Does not change the original array"
  },
  {
    "path": "src/content/docs/02-array/17_array-at.md",
    "content": "---\ntitle: 'Access an element at a specific index with `at()`'\nsidebar:\n  label: Accessing a specific element\n---\n\n## Access an element at a specific index with `at()`\n\nThe `at()` method in Javascript allows you to access an element of an array at a specific index.\n\nThe `at()` method takes one argument, which is the index of the element that you want to retrieve. You can use positive or negative integers. Positive integers access elements from the start of the array, while negative integers count from the end.\n\n### Examples\n\n_Example 1_, using `at()` to access an element counting from the start of the array:\n\n```js\nconst fruit = [\"banana\", \"mango\", \"orange\", \"apple\"]\n\nconsole.log(fruit.at(0)) // Output: \"banana\"\n\n\nconst item = fruit.at(2)\n\nconsole.log(item) // Output: \"orange\"\n```\nIn this example we used positive integers to access elements, counting from the start of the array. When we used `0` as the index, the first element was returned. \n\n_Example 2_, using `at()` to access an element counting back from the end of the array:\n\n```js\nconst fruit = [\"banana\", \"mango\", \"orange\", \"apple\"]\n\nconsole.log(fruit.at(-1)) // Output: \"apple\" \n\n\nconst item = fruit.at(-3)\n\nconsole.log(item) // Output: \"mango\"\n```\n\nIn this example we used negative integers to access elements, counting back from the end of the array. When we used `-1` as the index, the last element was returned. \n\n### Notes\n\n- When accessing an element with a negative index (for example `-2`), the `at()` function is accessing `index + array.length`.\n- If the index is out of range, it will return `undefined`.\n"
  },
  {
    "path": "src/content/docs/02-array/18_array-flatmap.md",
    "content": "---\ntitle: 'Flattening and Mapping a Nested Array'\ndescription: 'Flattening and Mapping a Nested Array with the flatMap() method'\nsidebar:\n  label: Flattening and Mapping a Nested Array\n---\n\n## Flattening and Mapping a Nested Array: `flatMap()`\n\nThe `flatMap()` method in JavaScript combines the functionality of `map()` and `flat()` into one. It maps each element using a mapping function and then flattens the result into a new array. By default, it flattens the array one level deep, making it useful for dealing with nested arrays while performing a transformation.\n\nThe `flatMap()` method does not take a depth argument; it flattens the array by exactly one level.\n\nThe two arguments:\n\n- `callback`: a function to execute on each element.\n- `thisArg`: value to use as `this` when executing the callback.\n\n\n### Examples\n_Example 1_, using `flatMap()` to map and flatten a nested array:\n\n```javascript\nconst arr = [[1, 2], [3, 4], [5, 6]];\nconsole.log(arr.flatMap(x => x)); // Output: [1, 2, 3, 4, 5, 6]\n```\n\nIn this example, the `flatMap()` method is used to flatten each sub-array in arr by one level. The callback simply returns the elements as they are, and flatMap() flattens the resulting nested arrays.\n\n_Example 2_, using `flatMap()` to handle nested arrays and sparse arrays:\n\n```javascript\nconst arr3 = [[1, 2], , [3, 4], [5, 6]];\nconsole.log(arr3.flatMap(x => x)); // Output: [1, 2, 3, 4, 5, 6]\n```\n\nIn this example, `flatMap()` flattens the nested arrays while automatically removing empty slots from sparse arrays.\n\n_Example 3_, using `flatMap()` to concatenate and flatten strings in a nested array:\n\n```javascript\nconst arr4 = [[\"hello\", \"world\"], [\"foo\", \"bar\"]];\nconsole.log(arr4.flatMap(x => x.join(' ')));  // Output: [\"hello world\", \"foo bar\"]\n```\n\nHere, each nested array is joined into a single string using `join()`, and `flatMap()` flattens the resulting array of strings into a single-level array.\n\n### Notes\n- The `flatMap()` method is a combination of `map()` followed by `flat(1)`.\n- It's important to note that `flatMap()` only flattens by one level. If you need to flatten more deeply nested arrays, you should use `map()` followed by `flat()` with the required depth.\n"
  },
  {
    "path": "src/content/docs/02-array/19_array-keys.md",
    "content": "---\ntitle: 'Iterating over Array Indexes'\nsidebar:\n  label: Iterating over Array Indexes\n---\n\n## Iterating over Array Indexes with `keys()`\n\nIn JavaScript, the `keys()` method allows you to create an iterator object that contains the indexes (or keys) of the elements in an array.\n\nThe `keys()` method does not change the original array.\n\n### Examples\n\n_Example 1_, using `keys()` to iterate over an array:\n\n```js\nconst fruit = ['watermelon', 'pineapple', 'pear', 'mango']\nconst fruitKeys = fruit.keys()\n\nfor (let key of fruitKeys) {\n  console.log(key)\n}\n\n// Output:\n// 0\n// 1\n// 2\n// 3\n```\n\n_Example 2_, using `keys()` with a sparse array:\n\nIf an array has \"holes\" (i.e. missing elements), the `keys()` method still iterates over all possible indexes.\n\n```js\nconst animal = ['dog', , 'cat']\n\nfor (let key of animal.keys()) {\n  console.log(`Animal at index ${key} is ${animal[key]}`)\n}\n\n// Output:\n// Animal at index 0 is dog\n// Animal at index 1 is undefined\n// Animal at index 2 is cat\n```"
  },
  {
    "path": "src/content/docs/02-array/20_array-entries.md",
    "content": "---\ntitle: \"Getting key-value pairs from an array\"\nsidebar:\n  label: Array entries\n---\n\n## Array entries: `Array.entries()`\n\nThe **entries()** method in JavaScript returns a new Array Iterator object that contains key-value pairs for each index in the array. Each key-value pair is an array where the first element is the index and the second element is the value.\n\nSyntax:\n```javascript\narray.entries()\n```\n\n### Parameters:\n\nThe `entries()` method doesn't take any parameters.\n\n### Return Value:\n\nThe `entries()` method returns a new Array Iterator object that contains key-value pairs for each index in the array.\n\n### Examples:\n\n#### Basic Usage:\n\n```javascript\nconst fruits = ['Apple', 'Banana', 'Orange'];\nconst iterator = fruits.entries();\n\nfor (const entry of iterator) {\n  console.log(entry);\n}\n// Output:\n// [0, \"Apple\"]\n// [1, \"Banana\"]\n// [2, \"Orange\"]\n```\n\nIn this example, the `entries()` method returns an iterator that provides key-value pairs (index-value pairs) of the array elements, which are then accessed using a for...of loop.\n\n#### Destructuring in Loop:\n\n```javascript\nconst colors = ['red', 'green', 'blue'];\nconst iterator = colors.entries();\n\nfor (const [index, value] of iterator) {\n  console.log(`${index}: ${value}`);\n}\n// Output:\n// \"0: red\"\n// \"1: green\"\n// \"2: blue\"\n```\n\nUsing array destructuring, we can directly access the index and value from each entry.\n\n#### Converting Iterator to Array:\n\n```javascript\nconst numbers = [1, 2, 3, 4, 5];\nconst iterator = numbers.entries();\nconst entriesArray = [...iterator];\n\nconsole.log(entriesArray);\n// Output: [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]]\n```\n\nHere, the spread operator (`...`) is used to convert the iterator returned by `entries()` into a new array of arrays.\n\n#### Using with Iterator Methods:\n\n```javascript\nconst letters = ['a', 'b', 'c'];\nconst iterator = letters.entries();\n\nconsole.log(iterator.next().value); // Output: [0, \"a\"]\nconsole.log(iterator.next().value); // Output: [1, \"b\"]\nconsole.log(iterator.next().value); // Output: [2, \"c\"]\nconsole.log(iterator.next().done);  // Output: true\n```\n\nThe iterator object has a `next()` method that returns the next value in the sequence along with a `done` property that indicates whether the iteration is complete.\n\n### Common Use Cases:\n\n1. **Creating a Map from an Array**:\n\n```javascript\nfunction arrayToMap(array) {\n  const map = new Map();\n  for (const [index, value] of array.entries()) {\n    map.set(index, value);\n  }\n  return map;\n}\n\nconst fruits = ['Apple', 'Banana', 'Orange'];\nconst fruitsMap = arrayToMap(fruits);\nconsole.log(fruitsMap.get(1)); // Output: \"Banana\"\n```\n\n2. **Filtering with Index Awareness**:\n\n```javascript\nfunction filterWithIndex(array, callback) {\n  const result = [];\n  for (const [index, value] of array.entries()) {\n    if (callback(value, index)) {\n      result.push(value);\n    }\n  }\n  return result;\n}\n\nconst numbers = [10, 20, 30, 40, 50];\nconst filteredNumbers = filterWithIndex(numbers, (value, index) => index % 2 === 0);\nconsole.log(filteredNumbers); // Output: [10, 30, 50]\n```\n\n3. **Creating an Object with Array Indices as Keys**:\n\n```javascript\nfunction arrayToObject(array) {\n  return Object.fromEntries(array.entries());\n}\n\nconst fruits = ['Apple', 'Banana', 'Orange'];\nconst fruitsObject = arrayToObject(fruits);\nconsole.log(fruitsObject);\n// Output: { 0: \"Apple\", 1: \"Banana\", 2: \"Orange\" }\n```\n\n### Comparison with Other Array Iterator Methods:\n\nJavaScript arrays provide three methods that return iterators:\n\n```javascript\nconst arr = ['a', 'b', 'c'];\n\n// entries() - returns [index, value] pairs\nconst entryIterator = arr.entries();\n// Output when iterated: [0, \"a\"], [1, \"b\"], [2, \"c\"]\n\n// keys() - returns indices\nconst keyIterator = arr.keys();\n// Output when iterated: 0, 1, 2\n\n// values() - returns values\nconst valueIterator = arr.values();\n// Output when iterated: \"a\", \"b\", \"c\"\n```\n\nBy using the `Array.entries()` method, you can efficiently iterate over both the indices and values of an array, which is particularly useful when you need to process elements while keeping track of their positions in the array. "
  },
  {
    "path": "src/content/docs/02-array/21_array-findlastindex.md",
    "content": "---\ntitle: 'Finding the Last Index'\ndescription: 'returns the last index of the element in the array that satisfies the provided testing function'\nsidebar:\n  label: Finding the Last Index\n---\n\n## Finding the index of the last element that passes a test: `findLastIndex()`\n\nThe `findLastIndex()` method of Array instances iterates the array in reverse order and returns the index of the first element that satisfies the provided testing function. If no elements satisfy the testing function, -1 is returned.\n\nThe `findLastIndex()` function accepts a single argument: a callback function that tests each element in the array. This callback function can be customized to define the condition that elements must meet to be considered.\n\n```js\n//Syntax\nfindLastIndex(callbackFn(currentVal, index, arr))\nfindLastIndex(callbackFn(currentVal, index, arr), thisArg)\n```\n\n- `callbackFn()`: A function to execute for each element in the array. It should return a truthy value to indicate a matching element has been found, and a falsy value otherwise. The function is called with the following arguments: currentVal, index, and arr.\n- `currentVal`: (Required) The current element being processed in the array.\n- `index`: (Optional) The index of the current element being processed in the array.\n- `arr`: (Optional) The array findLastIndex() was called upon.\n`thisArg`: (Optional) The value to use as this when executing the callback function. By default, it is undefined.\n\n### Examples\n\n_Example 1_, using `findLastIndex()` to get the index of the last element that passes the test:\n\n```js\nconst numbers = [5, 12, 8, 130, 44];\n\nlet lastIndex = numbers.findLastIndex(checkLargeNumber);\n\nfunction checkLargeNumber(num) {\n  return num > 10;\n}\n```\n\nIn this example:\n\n- A function checkLargeNumber() is passed as a callback to the findLastIndex() function.\n- The findLastIndex() function will execute checkLargeNumber() for each element in the numbers array, starting from the end.\n- The condition num > 10 holds true for the element 44 at index 4, so findLastIndex() returns 4.\n\n_Example 2_, `findLastIndex()` returns -1 when no element matches the condition:\n\n```js\nconst numbers = [1, 2, 3, 4, 5];\n\nlet lastIndex = numbers.findLastIndex(checkLargeNumber);\n\nfunction checkLargeNumber(num) {\n  return num > 10;\n}\n```\n\n- In this case, none of the elements in numbers satisfy the num > 10 condition, so the findLastIndex() function returns -1.\n\n### Notes\n\n- Executes the function on each array element, starting from the end of the array.\n- Returns the index (position) of the last element that passes the test.\n- Returns -1 if no match is found.\n- Does not execute the function for empty array elements.\n- Does not change the original array."
  },
  {
    "path": "src/content/docs/02-array/22-array-findlast.md",
    "content": "---\ntitle: 'Finding the Last Element'\ndescription: 'Returns the last element in the array that satisfies the provided testing function'\nsidebar:\n  label: Finding the Last Element\n---\n\n##  Finding the last element that passes a test: `findLast()`\n\nThe **`findLast()`** method of Array instances allows you to search through an array from the **end to the beginning**. It returns the value of the **first element** that satisfies the provided testing function (tha callback function). If no elements meet the criteria, `undefined` is returned.\n\n### 🔍 **Syntax**\n\n```js\n\narray.findLast(callbackFn(element, index, array))\narray.findLast(callbackFn(element, index, array), thisArg)\n\n```\n\ncallbackFn: A function that is executed for each element in the array. It should return a truthy value to indicate a match and a falsy value otherwise. The function is called with the following arguments:\n\n - `element`: The current element being processed.\n - `index`: The index of the current element (_optional_).\n - `array`: The array `findLast()` was called upon (_optional_).\n\n## 🌟 Examples\n\n### Example 1: Using `findLast()` to find the last number greater than a specified value in an array:\n\n```js\n\nconst numbers = [5, 12, 8, 130, 44];\nconst lastLargeNumber = numbers.findLast((element) => element > 10);\nconsole.log(lastLargeNumber); // Expected output: 44\n\n```\n\nIn the example above, the `findLast()` method is used to find the last number in the array that is greater than 10. It iterates through the array from right to left and returns the first element that meets the condition, which in this case is 44, the last element that is greater than 10.\n\n#### Understanding the callback function\n\nThe callback function has one main parameter, `element`, which represents the current value being processed in the array during each iteration. Here’s how it works:\n\n- As `findLast()` iterates over the array from the last element to the first, it passes each element of the array to the `element` parameter in the callback function.\n- The condition in the callback function, `element > 10`, checks if the current element is greater than the specified value (10 in this case).\n- The method stops as soon as it finds an element that satisfies the condition and returns that element. In this example, 44 is the last element in the array that is greater than 10.\n\n\n#### Handling cases when no element matches the condition\n\nIf no element satisfies the condition, `findLast()` would return `undefined`.\n\n```javascript\nconst numbers = [2, 4, 6, 8, 10];\nconst lastLargeNumber = numbers.findLast((element) => element > 20);\nconsole.log(lastLargeNumber); // Expected output: undefined\n```\n\nIn the example above, the `findLast()` method is used to find the last element in the array that is greater than 20. However, since none of the elements in the array `[2, 4, 6, 8, 10]` meet the condition `element > 20`, the method does not find any matching element.\n\nWhen `findLast()` cannot find an element that satisfies the provided condition, it returns `undefined`. This is useful for safely handling cases where the array doesn't contain any values that match the specified criteria.\n\nIn real-world applications, you can use this behavior to handle scenarios where a condition might not be met, and return a fallback value or log a message if needed.\n\nFor example:\n\n```javascript\nif (lastLargeNumber === undefined) {\n  console.log(\"No element found that matches the condition.\");\n}\n```\n\nThis additional check can help ensure your code handles edge cases gracefully, preventing errors or unexpected behavior when no elements satisfy the condition.\n\n### Example 2: finding the last occurrence of a specific element\n```js\nconst fruits = [\n  { name: 'apple', color: 'red' },\n  { name: 'lemon', color: 'yellow' },\n  { name: 'kiwi', color: 'green' },\n  { name: 'banana', color: 'yellow' },\n  { name: 'grape', color: 'purple' }\n];\n\nconst lastYelloFruit = fruits.findLast((fruit) => fruit.color === 'yellow');\nconsole.log(lastYellowFruit);\n// Expected output: { name: 'banana', color: 'yellow' }\n\n```\n\nIn this example, we have an array of fruit objects, where each object contains two properties: `name` (the type of fruit) and `color`. We want to find the last occurrence of the fruit with `yellow` color in the array.\n\n- The callback function checks if the `color` property of the `fruit` object is `'yellow'`.\n- The `findLast()` method starts searching from the end of the array and returns the last object where the `color` is `'yellow'`.\n- In this case, the last matched occurrence is `{ name: 'banana', color: 'yellow' }`.\n\nHere, `findLast()` helps us locate the last occurrence of yellow fruit in the array, returning the expected object.\n\n\n\n### Example 3: finding the last even number\n\n```js\nconst mixedNumbers = [3, 5, 7, 10, 12, 15, 20];\nconst lastEvenNumber = mixedNumbers.findLast((num) => num % 2 === 0);\nconsole.log(lastEvenNumber); // Expected output: 20\n\n```\n\n## ⚠️ Important Notes\n1. Executes the provided function once for each element of the array, in descending order.\n2. Returns undefined if no element satisfies the testing function.\n3. Does not modify the original array, ensuring immutability.\n4. Returns the value of the first element that satisfies the provided testing function.\n\n## 🔗 Conclusion\nThe `findLast()` method is a valuable tool for efficiently locating the last matching element in an array, making your code more readable and maintainable!"
  },
  {
    "path": "src/content/docs/02-array/23-array-copywithin.md",
    "content": "---\ntitle: 'Copy within an Array: `copyWithin()`'\nsidebar:\n  label: Copy within an Array\n---\n\n## Copy within an array: `copyWithin()`\n\nThe `copyWithin()` method in JavaScript shallow copies part of an array to another location within the same array, without modifying the array’s length.\n\nIt allows for in-place modification of the array, making it a useful function for rearranging or manipulating data in arrays without creating new arrays. This method is efficient and destructive, altering the original array.\n\nIt accepts up to three parameters, but only the first parameter is mandatory. Here's how each parameter works:\n\n```javascript\narray.copyWithin(target, start, end)\n```\n\n1. `target` (required): this is the only mandatory parameter. It specifies the index where the copying will begin (the destination index). Elements from another part of the array will be copied here. If the target is negative, it will be counted from the end of the array.\n\n2. `start` (optional): this is the index from which the copying will start (the source index). If omitted, the copying will start from the beginning of the array (index 0). If negative, it counts from the end of the array.\n    \n3. `end` (optional): this specifies the index where to stop copying (non-inclusive). If omitted, the copying continues until the end of the array. If negative, it also counts from the end of the array.\n\n### Example: basic syntax with one parameter\nWhen using one parameter with `copyWithin()`, this parameter indicates the target position from which the copied elements will be placed within the same array.\n\n```javascript\nconst arr = [1, 2, 3, 4, 5, 6];\narr.copyWithin(3)\n// arr is [ 1, 2, 3, 1, 2, 3 ]\n```\n\nIn this case, the target parameter is the index (remember arrays are 0 index base), where the copied elements will start to be placed. The elements will be copied from index 0 (the start of the array) and moved to `target`.\n\nAnother example:\n\n```javascript\nconst arr2 = [1, 2, 3, 4, 5, 6, 7];\narr2.copyWithin(3)\n// arr2 is [ 1, 2, 3, 1, 2, 3, 4 ]\n```\n\nThe initial part of the array is taken and copied from the `target` position.\n\nAn additional example, take a look at how are filled the 0s values:\n\n```javascript\nconst arr3 = [1, 2, 3, 4, 0, 0, 0];\n// the index 3         ^\narr3.copyWithin(3)\n```\nFrom the index 3 to the end of the array, there are 4 elements.\nSo `copyWithin` takes  the first four elements of the array and copies them from the  element at index 3\n\n\n### Example: basic syntax with two parameters, `target` and `start`\n\nSuppose you have an array of numbers, and you want to create a new array where you want to replace the elements from index 1 using items from index 3. You can use the `copyWithin()` method as shown in this example:\n```js\nconst numbers = [1, 2, 3, 4, 5]\nconsole.log('Original Array:', numbers) \n//expected output: [1, 2, 3, 4, 5]\n\n// Using copyWithin() method to create a new array \n// where method copies to index 1 all elements from index 3 to the end\nconsole.log('New Array:', numbers.copyWithin(1, 3)) \n//expected output: [1, 4, 5, 4, 5]\n```\n\n### Example about basic syntax with three  parameters: `target`, `start`, and `end`\n\nAnother example, suppose you want to create a new array where you want to replace the elements from index 1 using items from 0 to index 3:\n```js\nconst numbers = [1, 2, 3, 4, 5]\nconsole.log('Original Array:', numbers) \n//expected output: [1, 2, 3, 4, 5]\n\n// In this case, the method copies to index 1 all elements from index 0 to index 3\nconsole.log('New Array:', numbers.copyWithin(1, 0, 3)) \n//expected output: [1, 1, 2, 3, 5]\n```\n\n_Example 3_, `copyWithin()` allows the use negative values as parameters in this way:\n```js\nconst numbers = [1, 2, 3, 4, 5]\nconsole.log('Original Array:', numbers) \n//expected output: [1, 2, 3, 4, 5]\n\n\nconsole.log('New Array:', numbers.copyWithin(-2, -3, -1)) \n//expected output: [1, 2, 3, 3, 4]\n```\n\n### Negative parameters in `copyWithin()`\n\nUsing a negative `target` means copying elements starting from the beginning (`start` defaults to 0 if not specified) and pasting them starting from a position counted backward from the end.\n\n```javascript\nconst arr = [10, 20, 30, 40, 50];\narr.copyWithin(-2); // Copies elements from index 0 and pastes them starting at index -2\nconsole.log(arr); // Output: [10, 20, 30, 10, 20]\n```\n\nExplanation:\n\n- `target` equals to ` -2` refers to the second-to-last element of the array (index 3). The function copies from the beginning ([10, 20, 30]) and pastes it starting at the third-to-last position, replacing the last two elements with [10, 20].\n\nYou can specify a negative `start` to begin copying from an index counted backward from the end.\n\n```javascript\nconst arr = [10, 20, 30, 40, 50];\narr.copyWithin(0, -3); // Starts copying from index -3 (which is 30) and pastes at index 0\nconsole.log(arr); // Output: [30, 40, 50, 40, 50]\n```\n\nExplanation:\n\n- `start` equals to `-3` refers to the third-to-last element (index 2), which is 30.\nThe function copies from 30 to the end of the array ([30, 40, 50]) and pastes it at index 0, replacing the first three elements.\n\nYou can use a negative `end` to stop copying at an index counted backward from the end of the array. Note that `end` is non-inclusive, meaning it doesn’t include the element at that index.\n\n```javascript\nconst arr = [10, 20, 30, 40, 50];\narr.copyWithin(1, -4, -1); // Copies from index -4 (20) to -1 (50, non-inclusive) and pastes at index 1\nconsole.log(arr); // Output: [10, 20, 30, 40, 50]\n```\n\nExplanation:\n\n- `start` equals to `-4` refers to the fourth-to-last element (index 1), which is 20.\n- `end` equals to `-1` refers to the last element (index 4), but it's non-inclusive, so copying stops just before 50.\n- The function copies from 20 to 40 ([20, 30, 40]) and pastes it starting at index 1, but in this case, no values changed as it copied into the same positions.\n\n### Combined example: negative `target`, `start`, and `end`\nLet's see an example that uses all three parameters as negative values:\n\n```javascript\nconst arr = ['a', 'b', 'c', 'd', 'e'];\narr.copyWithin(-3, -4, -2); // Copies from index -4 (b) to -2 (d, non-inclusive) and pastes at index -3\nconsole.log(arr); // Output: ['a', 'b', 'b', 'c', 'e']\n```\n\nExplanation:\n\n- `target` equals to `-3`: This means copying starts at the third-to-last element (index 2).\n- `start` equals to `-4`: This refers to the fourth-to-last element (b at index 1).\n- `end` equals to `-2`: This refers to the second-to-last element (d at index 3), but it's non-inclusive, so copying stops before d.\n\nSo, elements from `start` = -4 ('b') to `end` = -2 ('c') are copied into positions starting at index -3 (the third-to-last position), resulting in ['a', 'b', 'b', 'c', 'e'].\n\n### Important considerations\n\n- **In-place modification**: `copyWithin()` modifies the original array. To keep the original array intact, clone it before using this method.\n- **Shallow copy**: `copyWithin()` performs a shallow copy. If the array contains objects, it will only copy references to them, not the objects themselves.\n- **Usefulness in algorithms**: This method can be particularly useful in algorithms that require in-place modifications to improve efficiency, such as avoiding creating new arrays when working with large datasets.\n"
  },
  {
    "path": "src/content/docs/02-array/24-array-entries.md",
    "content": "---\ntitle: 'Instances an Array iterator: `entries()`'\nsidebar:\n  label: Instances an Array iterator\n---\n\n## Instances an Array iterator: `entries()`\n\nThe `entries()` method in JavaScript instances an iterator object that contains the key/value pairs for each index in the array.\n\nAn iterator is a special object that allows you to \"navigate\" through the elements of the array. It does not directly return an array with all index/value pairs.\n\nIt has no input parameters and the syntax is as follows::\n\n```javascript\narray.entries()\n```\n\n### Example: basic iteration with index and element\nWhen using `entries()` method with `for` loop, it's possible manipulate the index and the item, like this:.\n\n```javascript\nconst fruits = [\"Banana\", \"Apple\", \"Mango\"];\n\nfor (const [index, fruit] of fruits.entries()) {\n  console.log(index, fruit);\n}\n\n// 0 'Banana'\n// 1 'Apple'\n// 2 'Mango'\n```\n\nIn this case, the `entries()` method on the `fruits` array is used and then the `for` loop is used JavaScript Destructuring.\n\n### Example: using a for...of loop\n\nAnother example, it's possible iterate an entries Array with for...of loop, in this way:  \n```js\nconst fruits = [\"Banana\", \"Apple\", \"Mango\"];\nconst fruitsEntries = fruits.entries();\n\nfor (const fruit of fruitsEntries) {\n  console.log(fruit);\n}\n\n// 0 'Banana'\n// 1 'Apple'\n// 2 'Mango'\n```\nIn the above example, the `entries()` method on the `fruits` array is used for memorize the result in a variable called `fruitsEntries` which is then used in the `for` loop.\n\n### Example: sparse arrays\n\n`entries()` method will visit empty slots and will consider it as `undefined`, in this way:\n\n```js\nfor (const fruit of [, \"Banana\"].entries()) {\n  console.log(fruit);\n}\n// [0, undefined]\n// [1, 'Banana']\n```\nIn this example, first index is empty and for `entries()` method the element is `undefined`.\n\n### The `next()` method \n\nAfter the iterator is created with `entries()` method, it possible access the `next()` method.\nWith this method is possible access each element one at a time, in this way:\n```js\nconst fruits = [\"Banana\", \"Apple\", \"Mango\"];\nconst fruitsEntries = fruits.entries();\n\nconsole.log(fruitsEntries.next().value + \" \" + fruitsEntries.next().value);\n// \"0,Banana 1,Apple\"\n```\nIn the above example, `next()` is called twice, this using the first two values of `fruitsEntries`.\n\n### `entries()` for Object and Map\n`entries()` method is also available for JavaScript [Object](/03-var/07_object-entries/). It's similar to Array, in this way:\n\n```js\nconst user = {\n    name: 'John',\n    age: 30\n}\nconsole.log(Object.entries(user)); // [['name', 'John'], ['age', 30]]\n```\nIt's available also for Map (Map object are collections of key-value pairs), for example:\n\n```js\nconst mapping = new Map();\nmapping.set(\"0\", \"Peach\");\nmapping.set(1, \"Mango\");\nmapping.set({}, \"Banana\");\n\nconst mapIter = mapping.entries();\n\nconsole.log(mapIter.next().value); // [\"0\", \"Peach\"]\nconsole.log(mapIter.next().value); // [1, \"Mango\"]\nconsole.log(mapIter.next().value); // [Object, \"Banana\"]\n```\n\n### Notes\n\n- **Return on object**: `entries()` method return an iterator object that contains the key/value.\n- **Access each element**: `next()` method allows the access to elements one at a time.\n- **Available also for other elements**: `entries()` method is also available for Object and Map.\n"
  },
  {
    "path": "src/content/docs/02-array/25_array-values.md",
    "content": "---\ntitle: \"Getting array values as an iterator\"\nsidebar:\n  label: Array values\n---\n\n## Array values: `Array.values()`\n\nThe **values()** method in JavaScript returns a new Array Iterator object that contains the values for each index in the array.\n\nSyntax:\n```javascript\narray.values()\n```\n\n### Parameters:\n\nThe `values()` method doesn't take any parameters.\n\n### Return Value:\n\nThe `values()` method returns a new Array Iterator object that contains the values for each index in the array.\n\n### Examples:\n\n#### Basic Usage:\n\n```javascript\nconst fruits = ['Apple', 'Banana', 'Orange'];\nconst iterator = fruits.values();\n\nfor (const value of iterator) {\n  console.log(value);\n}\n// Output:\n// \"Apple\"\n// \"Banana\"\n// \"Orange\"\n```\n\nIn this example, the `values()` method returns an iterator that provides the values of the array elements, which are then accessed using a for...of loop.\n\n#### Converting Iterator to Array:\n\n```javascript\nconst numbers = [1, 2, 3, 4, 5];\nconst iterator = numbers.values();\nconst valuesArray = [...iterator];\n\nconsole.log(valuesArray); // Output: [1, 2, 3, 4, 5]\n```\n\nHere, the spread operator (`...`) is used to convert the iterator returned by `values()` into a new array.\n\n#### Using with Iterator Methods:\n\n```javascript\nconst colors = ['red', 'green', 'blue'];\nconst iterator = colors.values();\n\nconsole.log(iterator.next().value); // Output: \"red\"\nconsole.log(iterator.next().value); // Output: \"green\"\nconsole.log(iterator.next().value); // Output: \"blue\"\nconsole.log(iterator.next().done);  // Output: true\n```\n\nThe iterator object has a `next()` method that returns the next value in the sequence along with a `done` property that indicates whether the iteration is complete.\n\n#### Iterating Over Sparse Arrays:\n\n```javascript\nconst sparseArray = [1, , 3, , 5];\nconst iterator = sparseArray.values();\n\nfor (const value of iterator) {\n  console.log(value);\n}\n// Output:\n// 1\n// undefined\n// 3\n// undefined\n// 5\n```\n\nWhen used with sparse arrays, the `values()` method includes `undefined` for missing elements.\n\n### Common Use Cases:\n\n1. **Iterating Over Array Values**:\n\n```javascript\nfunction processArrayValues(array) {\n  const iterator = array.values();\n  for (const value of iterator) {\n    // Process each value\n    console.log(`Processing: ${value}`);\n  }\n}\n\nprocessArrayValues(['a', 'b', 'c']);\n// Output:\n// \"Processing: a\"\n// \"Processing: b\"\n// \"Processing: c\"\n```\n\n2. **Creating Multiple Independent Iterators**:\n\n```javascript\nconst data = [10, 20, 30];\nconst iterator1 = data.values();\nconst iterator2 = data.values();\n\nconsole.log(iterator1.next().value); // Output: 10\nconsole.log(iterator1.next().value); // Output: 20\n\nconsole.log(iterator2.next().value); // Output: 10 (independent iterator)\n```\n\n3. **Working with Other Iteration Methods**:\n\n```javascript\nconst items = ['item1', 'item2', 'item3'];\nconst iterator = items.values();\n\n// Convert to array and apply array methods\nconst upperCaseItems = [...iterator].map(item => item.toUpperCase());\nconsole.log(upperCaseItems); // Output: [\"ITEM1\", \"ITEM2\", \"ITEM3\"]\n```\n\n### Comparison with Other Array Iterator Methods:\n\nJavaScript arrays provide three methods that return iterators:\n\n```javascript\nconst arr = ['a', 'b', 'c'];\n\n// values() - returns values\nconst valueIterator = arr.values();\n// Output when iterated: \"a\", \"b\", \"c\"\n\n// keys() - returns indices\nconst keyIterator = arr.keys();\n// Output when iterated: 0, 1, 2\n\n// entries() - returns [index, value] pairs\nconst entryIterator = arr.entries();\n// Output when iterated: [0, \"a\"], [1, \"b\"], [2, \"c\"]\n```\n\nBy using the `Array.values()` method, you can efficiently iterate over the values of an array, which is particularly useful when you need to process each element in sequence without needing their indices. "
  },
  {
    "path": "src/content/docs/02-array/26_array-sort.md",
    "content": "---\ntitle: \"Sorting array elements\"\nsidebar:\n  label: Array sort\n---\n\n## Array sort: `Array.sort()`\n\nThe **sort()** method in JavaScript sorts the elements of an array in place and returns the sorted array. The default sort order is ascending, built upon converting the elements into strings and comparing their sequences of UTF-16 code units values.\n\nSyntax:\n```javascript\narray.sort()\narray.sort(compareFn)\n```\n\n### Parameters:\n\n1. **compareFn (optional)**: A function that defines the sort order. If omitted, the array elements are converted to strings and sorted according to each character's Unicode code point value.\n   - If `compareFn(a, b)` returns less than 0, sort `a` before `b`.\n   - If `compareFn(a, b)` returns 0, leave `a` and `b` unchanged with respect to each other.\n   - If `compareFn(a, b)` returns greater than 0, sort `b` before `a`.\n\n### Return Value:\n\nThe `sort()` method returns the reference to the same array, now sorted. Note that the array is sorted in place, and no copy is made.\n\n### Examples:\n\n#### Basic Usage:\n\n```javascript\nconst fruits = ['Banana', 'Orange', 'Apple', 'Mango'];\nfruits.sort();\nconsole.log(fruits); // Output: [\"Apple\", \"Banana\", \"Mango\", \"Orange\"]\n```\n\nIn this example, the `sort()` method sorts the array of strings alphabetically.\n\n#### Sorting Numbers:\n\n```javascript\nconst numbers = [40, 100, 1, 5, 25, 10];\nnumbers.sort();\nconsole.log(numbers); // Output: [1, 10, 100, 25, 40, 5]\n```\n\nNote that without a compare function, numbers are converted to strings and sorted lexicographically, which may not give the expected result.\n\n#### Using a Compare Function for Numbers:\n\n```javascript\nconst numbers = [40, 100, 1, 5, 25, 10];\nnumbers.sort((a, b) => a - b);\nconsole.log(numbers); // Output: [1, 5, 10, 25, 40, 100]\n```\n\nWith a compare function, we can sort numbers in ascending order.\n\n#### Sorting in Descending Order:\n\n```javascript\nconst numbers = [40, 100, 1, 5, 25, 10];\nnumbers.sort((a, b) => b - a);\nconsole.log(numbers); // Output: [100, 40, 25, 10, 5, 1]\n```\n\nBy reversing the comparison, we can sort in descending order.\n\n### Common Use Cases:\n\n1. **Sorting Objects by Property**:\n\n```javascript\nconst people = [\n  { name: 'John', age: 30 },\n  { name: 'Alice', age: 25 },\n  { name: 'Bob', age: 35 }\n];\n\n// Sort by age\npeople.sort((a, b) => a.age - b.age);\nconsole.log(people);\n// Output: [\n//   { name: 'Alice', age: 25 },\n//   { name: 'John', age: 30 },\n//   { name: 'Bob', age: 35 }\n// ]\n\n// Sort by name\npeople.sort((a, b) => a.name.localeCompare(b.name));\nconsole.log(people);\n// Output: [\n//   { name: 'Alice', age: 25 },\n//   { name: 'Bob', age: 35 },\n//   { name: 'John', age: 30 }\n// ]\n```\n\n2. **Case-Insensitive Sorting**:\n\n```javascript\nconst cities = ['Vienna', 'berlin', 'Amsterdam', 'paris'];\ncities.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));\nconsole.log(cities); // Output: [\"Amsterdam\", \"berlin\", \"paris\", \"Vienna\"]\n```\n\n3. **Custom Sorting Logic**:\n\n```javascript\nconst items = [\n  { name: 'Edward', value: 21 },\n  { name: 'Sharpe', value: 37 },\n  { name: 'And', value: 45 },\n  { name: 'The', value: -12 },\n  { name: 'Magnetic', value: 13 },\n  { name: 'Zeros', value: 37 }\n];\n\n// Sort by value, then by name if values are equal\nitems.sort((a, b) => {\n  if (a.value !== b.value) {\n    return a.value - b.value;\n  }\n  return a.name.localeCompare(b.name);\n});\nconsole.log(items);\n```\n\n### Sorting with Internationalization:\n\nFor proper internationalization support, you can use the `Intl.Collator` object:\n\n```javascript\nconst names = ['Österreich', 'Andorra', 'Vietnam', 'Zaire', 'Åland'];\nconst collator = new Intl.Collator('en');\nnames.sort((a, b) => collator.compare(a, b));\nconsole.log(names); // Output: [\"Åland\", \"Andorra\", \"Österreich\", \"Vietnam\", \"Zaire\"]\n```\n\n### Stability of sort():\n\nThe `sort()` method in modern JavaScript is stable, which means that elements with equal sorting keys maintain their relative order:\n\n```javascript\nconst data = [\n  { id: 1, value: 'a' },\n  { id: 2, value: 'b' },\n  { id: 3, value: 'a' },\n  { id: 4, value: 'c' }\n];\n\n// Sort by value\ndata.sort((a, b) => a.value.localeCompare(b.value));\nconsole.log(data);\n// Output: The elements with value 'a' maintain their relative order (id 1 before id 3)\n```\n\nBy using the `Array.sort()` method effectively with custom compare functions, you can implement complex sorting logic to organize your data according to your specific requirements. "
  },
  {
    "path": "src/content/docs/02-array/27_array-reverse.md",
    "content": "---\ntitle: \"Reversing array elements\"\nsidebar:\n  label: Array reverse\n---\n\n## Array reverse: `Array.reverse()`\n\nThe **reverse()** method in JavaScript reverses the order of the elements in an array in place and returns the reference to the same array.\n\nSyntax:\n```javascript\narray.reverse()\n```\n\n### Parameters:\n\nThe `reverse()` method doesn't take any parameters.\n\n### Return Value:\n\nThe `reverse()` method returns the reference to the same array, now with elements in reversed order. Note that the array is reversed in place, and no copy is made.\n\n### Examples:\n\n#### Basic Usage:\n\n```javascript\nconst fruits = ['Apple', 'Banana', 'Orange', 'Mango'];\nfruits.reverse();\nconsole.log(fruits); // Output: [\"Mango\", \"Orange\", \"Banana\", \"Apple\"]\n```\n\nIn this example, the `reverse()` method reverses the order of the elements in the array.\n\n#### Reversing a Numeric Array:\n\n```javascript\nconst numbers = [1, 2, 3, 4, 5];\nnumbers.reverse();\nconsole.log(numbers); // Output: [5, 4, 3, 2, 1]\n```\n\nThe `reverse()` method works with any type of array elements.\n\n#### Chaining with Other Array Methods:\n\n```javascript\nconst numbers = [1, 2, 3, 4, 5];\nconst reversed = [...numbers].reverse();\nconsole.log(numbers); // Output: [1, 2, 3, 4, 5] (original array unchanged)\nconsole.log(reversed); // Output: [5, 4, 3, 2, 1] (new reversed array)\n```\n\nBy using the spread operator (`...`) to create a copy first, we can reverse an array without modifying the original.\n\n#### Reversing a String Using Array Methods:\n\n```javascript\nconst str = 'Hello World';\nconst reversedStr = str.split('').reverse().join('');\nconsole.log(reversedStr); // Output: \"dlroW olleH\"\n```\n\nWhile strings don't have a `reverse()` method, we can convert a string to an array, reverse it, and then join it back into a string.\n\n### Common Use Cases:\n\n1. **Reversing a Copy of an Array**:\n\n```javascript\nfunction reverseArrayCopy(array) {\n  return [...array].reverse();\n}\n\nconst original = [1, 2, 3, 4, 5];\nconst reversed = reverseArrayCopy(original);\nconsole.log(original); // Output: [1, 2, 3, 4, 5]\nconsole.log(reversed); // Output: [5, 4, 3, 2, 1]\n```\n\n2. **Implementing a Palindrome Check**:\n\n```javascript\nfunction isPalindrome(str) {\n  // Remove non-alphanumeric characters and convert to lowercase\n  const cleanStr = str.toLowerCase().replace(/[^a-z0-9]/g, '');\n  // Compare with its reverse\n  return cleanStr === cleanStr.split('').reverse().join('');\n}\n\nconsole.log(isPalindrome('A man, a plan, a canal: Panama')); // Output: true\nconsole.log(isPalindrome('race a car')); // Output: false\n```\n\n3. **Creating a Reverse Iterator**:\n\n```javascript\nfunction* reverseIterator(array) {\n  for (let i = array.length - 1; i >= 0; i--) {\n    yield array[i];\n  }\n}\n\nconst array = ['a', 'b', 'c', 'd'];\nfor (const item of reverseIterator(array)) {\n  console.log(item);\n}\n// Output:\n// \"d\"\n// \"c\"\n// \"b\"\n// \"a\"\n```\n\n### Reversing Nested Arrays:\n\nThe `reverse()` method only affects the order of elements in the top level of the array. Nested arrays remain intact:\n\n```javascript\nconst nestedArray = [[1, 2], [3, 4], [5, 6]];\nnestedArray.reverse();\nconsole.log(nestedArray); // Output: [[5, 6], [3, 4], [1, 2]]\n```\n\nTo reverse nested arrays as well, you would need to apply `reverse()` to each nested array:\n\n```javascript\nconst deepReversed = nestedArray.map(subArray => subArray.reverse()).reverse();\nconsole.log(deepReversed); // Output: [[6, 5], [4, 3], [2, 1]]\n```\n\n### Performance Considerations:\n\nThe `reverse()` method is efficient with a time complexity of O(n), where n is the length of the array. Since it operates in place, it doesn't require additional memory for a new array.\n\nBy using the `Array.reverse()` method, you can quickly and efficiently reverse the order of elements in an array, which is useful for many algorithms and data manipulations. "
  },
  {
    "path": "src/content/docs/02-array/28_array-push-pop.md",
    "content": "---\ntitle: \"Adding and removing elements from the end of an array\"\nsidebar:\n  label: Array push and pop\n---\n\n## Array push and pop: `Array.push()` and `Array.pop()`\n\nThe **push()** and **pop()** methods in JavaScript are used to add and remove elements from the end of an array, respectively. These methods are commonly used for implementing stack-like behavior in arrays.\n\n### Array.push()\n\nThe `push()` method adds one or more elements to the end of an array and returns the new length of the array.\n\nSyntax:\n```javascript\narray.push(element1, element2, ..., elementN)\n```\n\n#### Parameters:\n\n1. **element1, element2, ..., elementN**: The elements to add to the end of the array.\n\n#### Return Value:\n\nThe `push()` method returns the new length of the array after the elements have been added.\n\n### Array.pop()\n\nThe `pop()` method removes the last element from an array and returns that element.\n\nSyntax:\n```javascript\narray.pop()\n```\n\n#### Parameters:\n\nThe `pop()` method doesn't take any parameters.\n\n#### Return Value:\n\nThe `pop()` method returns the removed element from the array. If the array is empty, `undefined` is returned.\n\n### Examples:\n\n#### Basic Usage of push():\n\n```javascript\nconst fruits = ['Apple', 'Banana'];\nconst newLength = fruits.push('Orange');\n\nconsole.log(fruits); // Output: [\"Apple\", \"Banana\", \"Orange\"]\nconsole.log(newLength); // Output: 3\n```\n\nIn this example, the `push()` method adds 'Orange' to the end of the array and returns the new length of the array.\n\n#### Adding Multiple Elements with push():\n\n```javascript\nconst numbers = [1, 2];\nconst newLength = numbers.push(3, 4, 5);\n\nconsole.log(numbers); // Output: [1, 2, 3, 4, 5]\nconsole.log(newLength); // Output: 5\n```\n\nThe `push()` method can add multiple elements at once.\n\n#### Basic Usage of pop():\n\n```javascript\nconst fruits = ['Apple', 'Banana', 'Orange'];\nconst removedItem = fruits.pop();\n\nconsole.log(fruits); // Output: [\"Apple\", \"Banana\"]\nconsole.log(removedItem); // Output: \"Orange\"\n```\n\nIn this example, the `pop()` method removes 'Orange' from the end of the array and returns it.\n\n#### Popping from an Empty Array:\n\n```javascript\nconst emptyArray = [];\nconst removedItem = emptyArray.pop();\n\nconsole.log(emptyArray); // Output: []\nconsole.log(removedItem); // Output: undefined\n```\n\nWhen popping from an empty array, `undefined` is returned.\n\n### Common Use Cases:\n\n1. **Implementing a Stack Data Structure**:\n\n```javascript\nclass Stack {\n  constructor() {\n    this.items = [];\n  }\n  \n  push(element) {\n    return this.items.push(element);\n  }\n  \n  pop() {\n    if (this.items.length === 0) {\n      return \"Underflow\";\n    }\n    return this.items.pop();\n  }\n  \n  peek() {\n    return this.items[this.items.length - 1];\n  }\n  \n  isEmpty() {\n    return this.items.length === 0;\n  }\n  \n  size() {\n    return this.items.length;\n  }\n  \n  clear() {\n    this.items = [];\n  }\n}\n\nconst stack = new Stack();\nstack.push(10);\nstack.push(20);\nstack.push(30);\n\nconsole.log(stack.peek()); // Output: 30\nconsole.log(stack.pop()); // Output: 30\nconsole.log(stack.size()); // Output: 2\n```\n\n2. **Building and Managing a Task Queue**:\n\n```javascript\nconst taskQueue = [];\n\n// Add tasks to the queue\ntaskQueue.push('Task 1');\ntaskQueue.push('Task 2');\ntaskQueue.push('Task 3');\n\nconsole.log('Current queue:', taskQueue); // Output: [\"Task 1\", \"Task 2\", \"Task 3\"]\n\n// Process tasks in a LIFO (Last In, First Out) order\nwhile (taskQueue.length > 0) {\n  const currentTask = taskQueue.pop();\n  console.log('Processing:', currentTask);\n}\n\n// Output:\n// Processing: Task 3\n// Processing: Task 2\n// Processing: Task 1\n```\n\n3. **Manipulating a History Stack**:\n\n```javascript\nconst browserHistory = [];\n\n// Navigate to pages\nfunction navigateTo(page) {\n  browserHistory.push(page);\n  console.log(`Navigated to ${page}`);\n}\n\n// Go back one page\nfunction goBack() {\n  if (browserHistory.length > 1) {\n    browserHistory.pop(); // Remove current page\n    const previousPage = browserHistory[browserHistory.length - 1];\n    console.log(`Navigated back to ${previousPage}`);\n    return previousPage;\n  } else {\n    console.log('No previous page to navigate to');\n    return null;\n  }\n}\n\nnavigateTo('Home'); // Output: Navigated to Home\nnavigateTo('Products'); // Output: Navigated to Products\nnavigateTo('Product Details'); // Output: Navigated to Product Details\n\nconsole.log('Current page:', browserHistory[browserHistory.length - 1]); // Output: Product Details\n\ngoBack(); // Output: Navigated back to Products\n```\n\n### Performance Considerations:\n\nBoth `push()` and `pop()` operations are efficient with a time complexity of O(1) in most cases, as they only operate on the end of the array. This makes them ideal for stack-like operations.\n\nBy using the `Array.push()` and `Array.pop()` methods together, you can efficiently implement stack-like data structures and algorithms in JavaScript. "
  },
  {
    "path": "src/content/docs/02-array/29_array-shift-unshift.md",
    "content": "---\ntitle: \"Adding and removing elements from the beginning of an array\"\nsidebar:\n  label: Array shift and unshift\n---\n\n## Array shift and unshift: `Array.shift()` and `Array.unshift()`\n\nThe **shift()** and **unshift()** methods in JavaScript are used to remove and add elements from the beginning of an array, respectively. These methods are commonly used for implementing queue-like behavior in arrays.\n\n### Array.shift()\n\nThe `shift()` method removes the first element from an array and returns that element. This method changes the length of the array.\n\nSyntax:\n```javascript\narray.shift()\n```\n\n#### Parameters:\n\nThe `shift()` method doesn't take any parameters.\n\n#### Return Value:\n\nThe `shift()` method returns the removed element from the array. If the array is empty, `undefined` is returned.\n\n### Array.unshift()\n\nThe `unshift()` method adds one or more elements to the beginning of an array and returns the new length of the array.\n\nSyntax:\n```javascript\narray.unshift(element1, element2, ..., elementN)\n```\n\n#### Parameters:\n\n1. **element1, element2, ..., elementN**: The elements to add to the beginning of the array.\n\n#### Return Value:\n\nThe `unshift()` method returns the new length of the array after the elements have been added.\n\n### Examples:\n\n#### Basic Usage of shift():\n\n```javascript\nconst fruits = ['Apple', 'Banana', 'Orange'];\nconst removedItem = fruits.shift();\n\nconsole.log(fruits); // Output: [\"Banana\", \"Orange\"]\nconsole.log(removedItem); // Output: \"Apple\"\n```\n\nIn this example, the `shift()` method removes 'Apple' from the beginning of the array and returns it.\n\n#### Shifting from an Empty Array:\n\n```javascript\nconst emptyArray = [];\nconst removedItem = emptyArray.shift();\n\nconsole.log(emptyArray); // Output: []\nconsole.log(removedItem); // Output: undefined\n```\n\nWhen shifting from an empty array, `undefined` is returned.\n\n#### Basic Usage of unshift():\n\n```javascript\nconst fruits = ['Banana', 'Orange'];\nconst newLength = fruits.unshift('Apple');\n\nconsole.log(fruits); // Output: [\"Apple\", \"Banana\", \"Orange\"]\nconsole.log(newLength); // Output: 3\n```\n\nIn this example, the `unshift()` method adds 'Apple' to the beginning of the array and returns the new length of the array.\n\n#### Adding Multiple Elements with unshift():\n\n```javascript\nconst numbers = [3, 4, 5];\nconst newLength = numbers.unshift(1, 2);\n\nconsole.log(numbers); // Output: [1, 2, 3, 4, 5]\nconsole.log(newLength); // Output: 5\n```\n\nThe `unshift()` method can add multiple elements at once.\n\n### Common Use Cases:\n\n1. **Implementing a Queue Data Structure**:\n\n```javascript\nclass Queue {\n  constructor() {\n    this.items = [];\n  }\n  \n  enqueue(element) {\n    return this.items.push(element);\n  }\n  \n  dequeue() {\n    if (this.items.length === 0) {\n      return \"Underflow\";\n    }\n    return this.items.shift();\n  }\n  \n  front() {\n    if (this.items.length === 0) {\n      return \"No elements in Queue\";\n    }\n    return this.items[0];\n  }\n  \n  isEmpty() {\n    return this.items.length === 0;\n  }\n  \n  size() {\n    return this.items.length;\n  }\n  \n  clear() {\n    this.items = [];\n  }\n}\n\nconst queue = new Queue();\nqueue.enqueue(10);\nqueue.enqueue(20);\nqueue.enqueue(30);\n\nconsole.log(queue.front()); // Output: 10\nconsole.log(queue.dequeue()); // Output: 10\nconsole.log(queue.size()); // Output: 2\n```\n\n2. **Processing Tasks in Order**:\n\n```javascript\nconst taskQueue = [];\n\n// Add tasks to the queue\ntaskQueue.push('Task 1');\ntaskQueue.push('Task 2');\ntaskQueue.push('Task 3');\n\nconsole.log('Current queue:', taskQueue); // Output: [\"Task 1\", \"Task 2\", \"Task 3\"]\n\n// Process tasks in a FIFO (First In, First Out) order\nwhile (taskQueue.length > 0) {\n  const currentTask = taskQueue.shift();\n  console.log('Processing:', currentTask);\n}\n\n// Output:\n// Processing: Task 1\n// Processing: Task 2\n// Processing: Task 3\n```\n\n3. **Maintaining a Sliding Window**:\n\n```javascript\nfunction slidingWindow(arr, windowSize) {\n  const result = [];\n  const window = [];\n  \n  for (let i = 0; i < arr.length; i++) {\n    window.push(arr[i]); // Add new element\n    \n    // If window is full, process it\n    if (window.length === windowSize) {\n      result.push([...window]); // Store current window\n      window.shift(); // Remove oldest element\n    }\n  }\n  \n  return result;\n}\n\nconst data = [1, 2, 3, 4, 5, 6, 7];\nconsole.log(slidingWindow(data, 3));\n// Output: [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7]]\n```\n\n### Performance Considerations:\n\nUnlike `push()` and `pop()`, the `shift()` and `unshift()` methods have a time complexity of O(n), where n is the length of the array. This is because all elements in the array need to be reindexed when an element is added to or removed from the beginning of the array.\n\nFor large arrays, if you need to frequently add or remove elements from the beginning, consider using a more efficient data structure like a linked list or a specialized queue implementation.\n\nBy using the `Array.shift()` and `Array.unshift()` methods together, you can efficiently implement queue-like data structures and algorithms in JavaScript, but be mindful of the performance implications for large arrays. "
  },
  {
    "path": "src/content/docs/03-var/00_var-obj-const.md",
    "content": "---\ntitle: \"Objects, Variables and Constants\"\ndescription: Exploring JavaScript Objects and Variables\nsidebar:\n  label: Objs and Vars\n---\n\n# Exploring JavaScript Objects and Variables\n\nIn this chapter, we dive into essential tools and methods for working with objects and variables in JavaScript.\n\nJavaScript provides a versatile set of tools for managing data through objects, variables, and constants. Objects allow us to structure and group related data, making complex logic easier to implement and maintain. Variables and constants, on the other hand, help us store and manipulate data with varying or immutable values throughout our code.\n\nWhen building cross-platform applications, it's crucial to account for differences between operating systems. Functions like `os.EOL` and `path.sep` are indispensable for creating portable code that handles file paths and line endings correctly, regardless of whether the application is running on Windows, macOS, or Linux. These utilities ensure that our logic works seamlessly across different environments, avoiding common pitfalls related to system-specific quirks.\n\nIn this chapter, we’ll explore how to effectively use these foundational concepts and tools, equipping you to write more reliable and maintainable JavaScript code.\n\n\n\n"
  },
  {
    "path": "src/content/docs/03-var/01_op-typeof.md",
    "content": "---\ntitle: Getting the type of a variable\nsidebar:\n  label: Determine the type of a variable\n---\n\n## Getting the type of a variable using `typeof`\n\nThe `typeof` operator returns a string indicating the type of the operand's value.\n\n```javascript\nconsole.log(typeof 12) // \"number\"\n\nconsole.log(typeof 'open source') //\"string\"\n\nconsole.log(typeof true) // \"boolean\"\n```\n"
  },
  {
    "path": "src/content/docs/03-var/02_path-sep.md",
    "content": "---\ntitle: 'Getting the path separator'\nsidebar:\n  label: Path Separator\n---\n\n## Path separator: `sep`\n\nThe `path.sep` property is a platform-specific path segment separator used in file system paths. It provides a string representing the character used to separate directories or folders in a file path. The value of `path.sep` varies depending on the operating system.\n\n:::note\nOn *Unix-based* systems (Linux, macOS), the path separator is `/`.\nOn *Windows* systems, the path separator is `\\`.\n:::\n\nThis property is particularly useful when working with file paths in a cross-platform manner, as it ensures that the appropriate separator is used based on the underlying operating system.\n\n### Example\n\nIn the below example, `path.sep` is used to concatenate the folder and file name with the appropriate separator for the current platform. This ensures that the file path is generated correctly regardless of whether you are running the code on a Unix-based system or Windows:\n\n```javascript\nconst path = require('path');\n\nconst folderName = 'documents';\nconst fileName = 'file.txt';\n\nconst filePath = `user${path.sep}${folderName}${path.sep}${fileName}`;\n\nconsole.log(`File Path: ${filePath}`);\n//Linux: File Path: user/documents/file.txt\n//Windows: File Path: user\\documents\\file.txt\n\n//Another example of creating filePath using path.sep along with join function\nconsole.log(['user', folderName, fileName].join(path.sep));\n```\n"
  },
  {
    "path": "src/content/docs/03-var/03_os-eol.md",
    "content": "---\ntitle: 'Getting the portable end of line'\nsidebar:\n  label: End Of Line\n---\n\n## The portable end of line: `os.EOL`\n`os.EOL` is a constant in the Node.js `os` module that represents the end-of-line(EOL) marker for the current operating system. It provides a <b>platform-specific string</b> for the end of a line in a file or text stream. The value of os.EOL varies depending on the operating system:\n\n:::note\nOn *Unix-based* systems (Linux, macOS), os.EOL is `\\n` (line feed).<br/>\nOn *Windows* systems, os.EOL is `\\r\\n` (carriage return + line feed).\n:::\n\nThis constant is particularly useful when working with text files or manipulating strings in a cross-platform environment. It ensures that line endings in files are appropriate for the platform being used, preventing issues with file compatibility.\n\n### Example\n\nHere's an example demonstrating the use of `os.EOL` to write content to a file with proper line endings:\n\n```javascript\nconst os = require('os');\n\nconst text = 'This is the first line' + os.EOL + 'This is the second line';\nconsole.log(text);\n```\n`os.EOL` is used to ensure that the line breaks in the `text` variable are compatible with the current operating system, resulting in consistent line endings when the output is viewed in different platforms."
  },
  {
    "path": "src/content/docs/03-var/04_object-getOwnPropertyNames.md",
    "content": "---\ntitle: 'Getting the object properties'\nsidebar:\n  label: The object property names\n---\n\n## Getting the property names of an object: `getOwnPropertyNames()`\n\nThe `getOwnPropertyNames()` method is a built-in JavaScript function that <b>returns an array of all non-inherited, enumerable properties of an object.</b> These properties are the object's own properties, which have been defined directly on the object, and are not inherited from its prototype chain.\n\nThe `getOwnPropertyNames()` method is useful when you need to obtain a list of an object's own properties for various purposes, such as serialization, copying, or enumeration.\n\n### Example\n\nHere's an example demonstrating the use of `getOwnPropertyNames()` to retrieve all the own property names:\n\n```javascript\nconst person = {\n  firstName: 'Sarah',\n  lastName: 'Connor',\n  age: 25,\n}\n\n// Addition of an own property\nperson.country = 'USA'\n\n// Retrieving own property names\nconst ownPropertyNames = Object.getOwnPropertyNames(person)\n\nconsole.log(ownPropertyNames)\n```\n"
  },
  {
    "path": "src/content/docs/03-var/05_object-keys.md",
    "content": "---\ntitle: 'Getting all the object properties/attributes'\nsidebar:\n  label: The object keys\n---\n\n## Getting all the properties of an object\n\nThe `Object.keys()` method returns an array containing all the keys/properties of a given object.\n\n```js\nconst user = {\n  name: 'John',\n  age: 30,\n}\n\nconsole.log(Object.keys(user)) // ['name', 'age']\n```\n\n## Usecases\n\n- If you need to check whether a specific property exists in an object, you can use `Object.keys()` and then search for the property in the resulting array.\n\n```js\nconst user = {\n  name: 'John',\n  age: 30,\n}\n\nconst propertyToCheck = 'name'\nconst isExit = Object.keys(user).includes(propertyToCheck)\n  ? 'Exists'\n  : 'Does not exist'\n\nconsole.log(`The property \"${propertyToCheck}\" ${isExit}.`)\n```\n- If you need to get all the properties of an object, you can use `Object.keys()` and then loop through the resulting array.\n```js\nfor (const key of Object.keys(user)) {\n  console.log(user[key])\n}\n```\n"
  },
  {
    "path": "src/content/docs/03-var/06_object-values.md",
    "content": "---\ntitle: 'Getting all the object values'\nsidebar:\n  label: The object values\n---\n\n\n## Getting all the values of an object using `Object.values()`\n\nThe `Object.values()` method gives you an array with all the values linked to an object's properties.\n\n```js\nconst user = {\n    name: 'John',\n    age: 30,\n}\nconsole.log(Object.values(user)); // ['John', 30]\n```\n\n## Usecase\n`Object.values()` is particularly valuable in scenarios where you need to search for specific values within an object\n\nConsider a library of books. You want to find all the books by a specific author.\n```js\n// Sample library of books\nconst library = {\n  book1: {\n    title: 'The Great Gatsby',\n    author: 'F. Scott Fitzgerald',\n    genre: 'Classics',\n  },\n  book2: {\n    title: 'To Kill a Mockingbird',\n    author: 'Harper Lee',\n    genre: 'Classics',\n  },\n};\n\nconst libraryValues = Object.values(library);\n\nfunction findBooksByAuthor(author) {\n  return libraryValues.filter((book) => book.author === author);\n}\nconst author = 'Harper Lee';\nconst book = findBooksByAuthor(author); // Finding books by \"Harper Lee\"\nconsole.log(author, book);\n\n```\n"
  },
  {
    "path": "src/content/docs/03-var/07_object-entries.md",
    "content": "---\ntitle: 'Getting all the object entries'\nsidebar:\n  label: The object entries\n---\n\n## Getting key-value pairs of an object using `Object.entries()`\n\nThe `Object.entries()` method returns an array of key-value pairs for each element in the object.\n\n```js\nconst user = {\n    name: 'John',\n    age: 30\n}\nconsole.log(Object.entries(user)); // [['name', 'John'], ['age', 30]]\n```\n\n## Usecases\n- If you want to determine the number of key-value pairs in an object, you can use the `Object.entries()` method.\n```js\nconsole.log(Object.entries(user).length); // 2\n```\n- If you want to get the keys of an object then you can use the `Object.entries()`method.\n```js\nconsole.log(Object.entries(user).map(item => item[0])); // ['name', 'age']\n```\n- If you want to get the `values` of an object then you can use the `Object.entries()`method.\n```js\nconsole.log(Object.entries(user).map(item => item[1])); // ['John', 30]\n```\n- If you want to check if an object has a specific key then you can use the `Object.entries()`method.\n```js\nconsole.log(Object.entries(user).some(item => item[0] === 'name')); // true\n```\nIf you're wondering why we can use array methods with `Object.entries()`, remember that the `Object.entries()` method returns an array of key-value pairs. We can then apply methods like `map()`, `some()`, and `length` to this array to access or manipulate its values.\n"
  },
  {
    "path": "src/content/docs/03-var/08_object-freeze.md",
    "content": "---\ntitle: 'Freezing an object'\nsidebar:\n  label: Freezing an object\n---\n\n## Prevent modification of an object using `Object.freeze()`\n\nThe `Object.freeze()` method freezes an object. A frozen object can no longer be changed,prevents new properties from being added to it and existing properties from being removed.\n\n```js\nconst user = {\n  name: 'John',\n  age: 30,\n}\n\nObject.freeze(user) // Freeze the 'user' object\n```\n\nAfter calling `Object.freeze(user)`, attempting to modify the user object will have no effect:\n\n```js\nuser.name = 'Jane' // This change will be ignored\n```\n### Use Case\n\nThe most common use case is in a web server configuration. When configuring a web server, it's often necessary to provide settings that are not expected to change. As a result, we freeze the configuration object to ensure its immutability.\n\n```js\nconst serverConfig = {\n  port: 8080,\n  host: 'example.com',\n  database: {\n    username: 'dbUser',\n    password: 'dbPassword',\n    name: 'dbName',\n  },\n};\n\n// Freeze the server configuration to prevent changes\nObject.freeze(serverConfig);\n\n// Attempting to modify the configuration will be ignored\nserverConfig.port = 8888; // This change will be ignored\nserverConfig.database.password = 'newPassword'; // This change will be ignored\n\nconsole.log(serverConfig);\n\n```\nHere we used `const` and `freeze` both because, In JavaScript, it’s important not to confuse const, with immutability, `const` creates a variable name binding which can’t be reassigned after creation. `const` does not create immutable objects. For example, if you have a `const` variable that holds an object, you can't make it point to a different object, but you can still modify the properties or contents of the object it points to. This is why const doesn't make objects themselves immutable, only the variable holding the object. Thats why we need to freeze the object to make it immutable.\n\n### Advantages\n\n1. Freezing an object can improve performance in some cases, since the JavaScript engine does not need to check whether the object has been modified before performing certain operations.\n2. It can also help prevent accidental changes to an object that is shared between multiple parts of the application.\n"
  },
  {
    "path": "src/content/docs/03-var/09_object-seal.md",
    "content": "---\ntitle: 'Sealing an object'\nsidebar:\n  label: Sealing an object\n---\n\n\n## Sealing Objects with `Object.seal()`\n\nThe `Object.seal()` method allows you to seal an object, preventing the addition or deletion of properties while still allowing property values to be changed.\n\n\n```js\nconst user = {\n    name: 'John',\n    age: 30,\n}\n\nObject.seal(user);\n\n// Attempt to add a new property (won't work)\nuser.country = 'USA';\n\n// Attempt to delete a property (won't work)\ndelete user.age;\n\n// Changing an existing property value (will work)\nuser.name = 'Alice';\n\nconsole.log(user);\n```\n### Use Cases\n`Object.seal()` is useful when you want to restrict modifications to an object but still allow for property value changes. For example, consider a user profile object:\n\n\n```js\nconst userProfile = {\n  username: 'jsmith',\n  email: 'jsmith@example.com',\n  isAdmin: false,\n};\n\nObject.seal(userProfile);\n\n// Attempting to add a new property or delete a property won't work.\n// However, you can change the values of existing properties.\n\n```\nBy sealing the userProfile object, you ensure that the structure remains constant, but you can update user details as needed."
  },
  {
    "path": "src/content/docs/03-var/10_object-isFrozen.md",
    "content": "---\ntitle: 'Checking for Object Immutability in JavaScript'\nsidebar:\n  label: Object Immutability\n---\n\n## Verifying Object Immutability with `Object.isFrozen()`\n\nThe `Object.isFrozen()` method enables you to check whether an object is completely immutable, meaning that none of its properties can be added, removed, or altered.\n\n```js\nconst book = {\n    title: 'The Catcher in the Rye',\n    author: 'J.D. Salinger',\n}\n\nObject.freeze(book);\n\nconsole.log(Object.isFrozen(book)); // true\n```\n\n## Use Cases\n\n`Object.isFrozen()` is valuable when you need to confirm whether an object is entirely unchangeable. For instance, consider a configuration object for a web application:\n\n```js\nconst config = {\n  theme: 'dark',\n  language: 'en',\n  mode: 'light',\n};\n\nObject.freeze(config);\n\n// Checking if the 'config' object is frozen.\nif (Object.isFrozen(config)) {\n  console.log('The configuration is immutable.');\n} else {\n  console.log('The configuration can still be altered.');\n}\n```\n\nBy using `Object.isFrozen()`, you can ensure that an object remains unchanged, maintaining data integrity in your applications.\n\n"
  },
  {
    "path": "src/content/docs/03-var/11_object-isSealed.md",
    "content": "---\ntitle: 'Checking for Object Sealing in JavaScript'\nsidebar:\n  label: Object Sealing\n---\n\n## Determining Object Sealing with `Object.isSealed()`\n\nThe `Object.isSealed()` method allows you to check whether an object is sealed, which means that properties cannot be added or removed, but existing properties can still have their values changed.\n\n```js\nconst car = {\n    make: 'Toyota',\n    model: 'Camry',\n}\n\nObject.seal(car);\n\nconsole.log(Object.isSealed(car)); // true\n```\n\n## Use Cases\n\n`Object.isSealed()` is valuable when you need to confirm whether an object is sealed, restricting changes to its structure while permitting alterations to property values. For example, consider a user account object:\n\n```js\nconst userAccount = {\n  username: 'jsmith',\n  email: 'jsmith@example.com',\n  isAdmin: false,\n};\n\nObject.seal(userAccount);\n\n// Checking if the 'userAccount' object is sealed.\nif (Object.isSealed(userAccount)) {\n  console.log('The user account is sealed.');\n} else {\n  console.log('The user account structure can still be modified.');\n}\n```\n\nBy using `Object.isSealed()`, you can ensure that the object's structure remains constant, providing data consistency within your applications."
  },
  {
    "path": "src/content/docs/03-var/12_object-groupby.md",
    "content": "---\ntitle: 'Grouping array elements'\ndescription: 'Groups elements of an array based on a function, returning an object'\nsidebar:\n  label: Grouping elements\n---\n\n\n## Introduction\nThe `Object.groupBy()` method is used to group elements of an array based on a given function. It returns an object where the keys are the result of the grouping function, and the values are arrays containing the elements that correspond to each key.\n\n## Syntax\n```javascript\nObject.groupBy(array, callbackFn)\n```\n\n### Parameters\n- `array`: The array of elements you want to group.\n- `callbackFn`: A function that accepts up to three arguments. The `groupBy()` method calls the `callbackFn` function once for each element in the array.\n\n### Return value\nAn object where each key is the result of the `callbackFn` function, and the corresponding value is an array of elements from the original array that produced that result.\n\n## Description\nThe `groupBy()` method executes the provided `callbackFn` function once for each element in the array. It then groups the array elements according to the returned values from the `callbackFn`.\n\n## Examples\n\n### Example 1: grouping fruits by type\n\n``` javascript\nconst fruits = [\n  { name: 'Apple', type: 'Citrus', quantity: 15 },\n  { name: 'Banana', type: 'Tropical', quantity: 10 },\n  { name: 'Orange', type: 'Citrus', quantity: 8 },\n  { name: 'Mango', type: 'Tropical', quantity: 5 },\n  { name: 'Lemon', type: 'Citrus', quantity: 12 }\n];\n\nconst groupedByType = Object.groupBy(fruits, fruit => fruit.type);\nconsole.log(groupedByType);\n/*\n{\n  Citrus: [\n    { name: 'Apple', type: 'Citrus', quantity: 15 },\n    { name: 'Orange', type: 'Citrus', quantity: 8 },\n    { name: 'Lemon', type: 'Citrus', quantity: 12 }\n  ],\n  Tropical: [\n    { name: 'Banana', type: 'Tropical', quantity: 10 },\n    { name: 'Mango', type: 'Tropical', quantity: 5 }\n  ]\n}\n*/\n```\n\nIn this example, `Object.groupBy()` groups the fruits by their type into two categories: 'Citrus' and 'Tropical'. Each key in the resulting object is the fruit type, and the values are arrays of fruit objects with that type.\n\n### Example 2: Grouping fruits by quantity range\n\n```javascript\nconst fruits = [\n  { name: 'Apple', type: 'Citrus', quantity: 15 },\n  { name: 'Banana', type: 'Tropical', quantity: 10 },\n  { name: 'Orange', type: 'Citrus', quantity: 8 },\n  { name: 'Mango', type: 'Tropical', quantity: 5 },\n  { name: 'Lemon', type: 'Citrus', quantity: 12 }\n];\n\nconst groupedByQuantityRange = Object.groupBy(fruits, fruit => {\n  if (fruit.quantity < 10) return 'Low';\n  if (fruit.quantity < 15) return 'Medium';\n  return 'High';\n});\n\nconsole.log(groupedByQuantityRange);\n/*\n{\n  Low: [\n    { name: 'Orange', type: 'Citrus', quantity: 8 },\n    { name: 'Mango', type: 'Tropical', quantity: 5 }\n  ],\n  Medium: [\n    { name: 'Banana', type: 'Tropical', quantity: 10 },\n    { name: 'Lemon', type: 'Citrus', quantity: 12 }\n  ],\n  High: [\n    { name: 'Apple', type: 'Citrus', quantity: 15 }\n  ]\n}\n*/\n```\n\nThis example groups fruits by their quantity into three ranges: 'Low' (less than 10), 'Medium' (between 10 and 14), and 'High' (15 or more). The result is an object where each key corresponds to a quantity range, and the values are arrays of fruits in that range.\n\n### Example 3: grouping fruits by the length of the name\n\n```javascript\nconst fruits = [\n  { name: 'Apple', type: 'Citrus', quantity: 15 },\n  { name: 'Banana', type: 'Tropical', quantity: 10 },\n  { name: 'Orange', type: 'Citrus', quantity: 8 },\n  { name: 'Mango', type: 'Tropical', quantity: 5 },\n  { name: 'Lemon', type: 'Citrus', quantity: 12 }\n];\n\nconst groupedByNameLength = Object.groupBy(fruits, fruit => fruit.name.length);\nconsole.log(groupedByNameLength);\n/*\n{\n  5: [\n    { name: 'Apple', type: 'Citrus', quantity: 15 },\n    { name: 'Mango', type: 'Tropical', quantity: 5 },\n    { name: 'Lemon', type: 'Citrus', quantity: 12 }\n  ],\n  6: [\n    { name: 'Banana', type: 'Tropical', quantity: 10 },\n    { name: 'Orange', type: 'Citrus', quantity: 8 }\n  ]\n}\n*/\n\n```\n\n In this case, fruits are grouped based on the length of their name property. The result is an object where the keys represent the number of characters in the fruit's name (5 for 'Apple', 'Mango', and 'Lemon'; 6 for 'Banana' and 'Orange'), and the values are arrays of fruits that fall into each length category.\n\n\n### Summary of the use cases\n- Grouping by type: Organizes items based on a predefined category or classification.\n- Grouping by quantity range: Segments data by numeric values, useful when you need to classify items into ranges (e.g., \"low\", \"medium\", \"high\").\n- Grouping by name length: Categorizes based on string properties, ideal for text analysis or string manipulation tasks.\n\n## Notes\n- The `groupBy()` method is a relatively new addition to JavaScript and may not be supported in all environments. Check for compatibility before using it in production.\n- If you need to support older environments, you can achieve similar functionality using `reduce()` or other array methods.\n\n## See also\n- [Array.prototype.reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)\n- [Object.groupBy()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/groupBy)\n"
  },
  {
    "path": "src/content/docs/04-functions/00_functions.md",
    "content": "---\ntitle: \"Functions\"\ndescription: The chapter will cover several types of functions we can use in JavaScript\nsidebar:\n  label: Introduction\n---\n\n# Functions\n\nThe chapter will cover several functions we can use in JavaScript, such as named functions, anonymous functions, arrow functions, IIFE (Immediately Invoked Function Expressions), generators, recursive, and Higher-Order functions.\n"
  },
  {
    "path": "src/content/docs/05-string/00_string.md",
    "content": "---\ntitle: \"Strings\"\ndescription: The chapter will cover several JavaScript string functions\nsidebar:\n  label: Introduction\n---\n\n# Managing the strings\n\nStrings are the lifeblood of any programming language, serving as the foundation for handling textual data. This chapter delves deep into the world of string functions, powerful tools that allow us to manipulate and transform text with precision and efficiency. From basic operations like concatenation to more advanced techniques such as pattern matching and substitution, you'll uncover some nice JavaScript functions\n"
  },
  {
    "path": "src/content/docs/05-string/01_str-concat.md",
    "content": "---\ntitle: \"Concatenating strings\"\nsidebar:\n  label: Concatenate strings\n---\n\nConcatenating strings in JavaScript allows you to combine multiple strings into a single string. The String.concat() method is one way to achieve this by joining two or more strings together.\n\n## Concatenating strings: `String.concat()`\n\nThe concat() method in JavaScript is used to concatenate one or more strings and return a new string resulting from the combination of these strings.\n\nSyntax:\n```javascript\n\nstring.concat(string1, string2, ..., stringN)\n\n```\n\n### Parameters:\n\n`string1, string2, ..., stringN`: These are the strings that you want to concatenate with the original string. You can provide one or more strings as arguments to this method. Each string is concatenated to the end of the original string in the order they are provided.\n\n### Return Value:\n\nThe `concat()` method returns a new string that is created by concatenating the original string with the strings provided as arguments. It does not modify the original string; instead, it creates and returns a new string.\n\n### Example:\n\nSyntax:\n```javascript\n\nconst str1 = 'Hello, ';\nconst str2 = 'world';\nconst str3 = '!';\n\nconst result = str1.concat(str2, str3);\n\nconsole.log(result); // Output: \"Hello, world!\"\n\n```\n\nIn this example, the concat() method combines the strings `str1`, `str2`, and `str3` to create a new string, which is stored in the `result` variable.\n\nBy using the String.concat() method, you can easily concatenate multiple strings together to form a single, larger string, which is a common operation in many JavaScript applications."
  },
  {
    "path": "src/content/docs/05-string/02_str-padding.md",
    "content": "---\ntitle: \"Padding strings\"\nsidebar:\n  label: Padding strings\n---\n\nThe padding function in JavaScript allows you to add a specified number of characters (spaces or any other defined characters) to the beginning or end of a string, ensuring it reaches a desired length.\n\n## Padding from the start of the string: `String.padStart()`\n\nThe padStart() method in JavaScript serves the purpose of extending a string by adding another string to it until it reaches a specified length. This padding operation occurs at the left end of the original string.\n\nSyntax:\n```javascript\n\nstring.padStart(targetLength, padString)\n\n```\n\n### Parameters:\n\ntargetLength: This parameter represents the desired length of the resulting string after the original string has been padded. If the provided value is smaller than the length of the original string, the original string remains unchanged.\n\npadString: This is the string that gets added to the original string for padding. If the padString is longer than what can fit within the targetLength, it will be truncated from the end. By default, a space character (\" \") is used as the padding string.\n\n### Return Value:\nThe method returns the extended string, padded with the specified string, resulting in the desired length.\n\n\n\n## Padding from the start of the string: `String.padEnd()`\n\nThe padEnd() method in JavaScript serves the purpose of expanding a string by appending another string to it until it reaches a specified length. The padding operation takes place at the right end of the original string.\n\nSyntax:\n```javascript\n\nstring.padEnd(targetLength, padString)\n\n```\n### Parameters:\n\ntargetLength: This parameter defines the intended length of the resulting string after the original string has been padded. If the provided value is smaller than the length of the original string, the original string remains unchanged.\n\npadString: This is the string that is added to the original string for padding. If the length of the padString exceeds what can fit within the targetLength, it is truncated.\n\n### Return Value:\nThe method returns the extended string, padded with the specified string to the desired length.\n\n"
  },
  {
    "path": "src/content/docs/05-string/03_str-includes.md",
    "content": "---\ntitle: \"Checking if a string includes a specific substring\"\nsidebar:\n  label: String includes\n---\n## String includes: `String.includes()`\n\nThe **includes()** method in JavaScript is used to determine whether one string can be found within another string. This method returns true if the specified string is found, and false otherwise.\n\nSyntax:\n```javascript\nstring.includes(searchString, position)\n```\n\n### The parameters\n\n1. **searchString**: The string to search for within the original string;\n2. **position(optional)**: The position within the original string at which to begin searching for the searchString. It is an optional parameter, and if not specified, the search starts from the beginning of the string.\n\n### Return Value:\n\nThe `includes()` method returns a boolean value:\n1. returns `true` if the searchString is found within the original string.\n2. returns `false` if the searchString is not found.\n\n### Example\n\n```javascript\nconst str = 'Hello, world!';\nconst isWorldPresent = str.includes('world');\nconsole.log(isWorldPresent);\n// Output: true\nconst isUniversePresent = str.includes('universe');\nconsole.log(isUniversePresent);\n// Output: false\n```\n\nIn this example, the `includes()` method is used to check if the string `'world'` is present in the original string str. The first console.log statement outputs `true` because `'world'` is found in the string. The second `console.log` statement outputs `false` as `'universe'` is not present.\n\n```javascript\nconst str = 'Hello, world!';\nconst isWorldPresentFromIndex = str.includes('world', 7);\nconsole.log(isWorldPresentFromIndex);\n// Output: false\n```\n\nIn the example above, the `includes()` method is called with both the `searchString` (`'world'`) and the `position` (`7`) parameters. The position parameter specifies the index at which the search should begin. The console.log statement outputs `false` because, starting from index 7, the `'world'` string is not found in the remaining portion of the string.\n\nThe position parameter is 0-index.\nFor example for indicating the first character of the string you need to use the value 0 as position.\n\n```javascript\nconst str = 'Hello, world!';\nstr.includes('Hello', 1)\n// false\nstr.includes('Hello', 0)\n// true\n```\nBy using the `String.includes()` method, you can efficiently determine whether a particular substring exists within a given string, providing a convenient way to handle string containment checks in JavaScript applications.\n"
  },
  {
    "path": "src/content/docs/05-string/04_str-slice.md",
    "content": "---\ntitle: \"Extracting a substring from a string\"\nsidebar:\n  label: String slice\n---\n## String slice: `String.slice()`\n\nThe `slice()` method in JavaScript is used to extract a portion of a string and return it as a new string without modifying the original string.\n\nSyntax:\n```javascript\nstring.slice(start, end)\n```\n\n### The parameters\n\n1. **start**: The index at which the extraction will begin. If negative, it counts from the end of the string.\n\n2. **end (optional)**: The index at which the extraction will end. If not specified, the extraction goes to the end of the string. If negative, it counts from the end of the string.\n\n:::note\nThe character at the **end** index is **not included** in the returned string.\n:::\n\n### Return Value:\n\nThe `slice()` method returns **a new string** representing the extracted portion of the original string.\n\n### Example\n\n```javascript\n// Using only the start parameter\nconst str = 'Hello, world!';\n\nconst slicedString = str.slice(7);\nconsole.log(slicedString);\n// Output: \"world!\"\n```\n\nIn the example above, The `slice()` method extracts the portion of the string starting from index `7` to the end `(str.length - 1)`. The extracted substring, `'world!'`, is stored in the variable slicedString.\n\n```javascript\n// Using both start and end parameters\nconst str = 'Hello, world!';\n\nconst slicedString = str.slice(1, 4);\nconsole.log(slicedString);\n// Output: \"ell\"\n```\n\nIn the example above, The `slice()` method extracts the portion of the string starting from index `1` and ending at index `4(exclusive)`. The extracted substring, `'ell'`, is stored in the variable slicedString.\n\n```javascript\n// Using negative indices with only start parameter\nconst str = 'Hello, world!';\n\nconst slicedString = str.slice(-6);\nconsole.log(slicedString);\n// Output: \"world!\"\n```\n\nIn the example above, The `slice()` method extracts the portion of the string starting from the 6th character from the end to the end of the string. The extracted substring, `'world!'`, is stored in the variable slicedString.\n\n```javascript\n// Using negative indices with both start and end parameter\nconst str = 'Hello, world!';\n\nconst slicedString = str.slice(-6, -3);\nconsole.log(slicedString);\n// Output: \"wor\"\n```\n\nIn the example above, The `slice()` method extracts the portion of the string starting from the 6th character from the end to the 3rd character from the end (exclusive). The extracted substring, `'wor'`, is stored in the variable slicedString.\n\nBy using the `String.slice()` method, you can efficiently extract substrings from a given string based on the specified indices, noting that the character at the end index is not included in the returned string."
  },
  {
    "path": "src/content/docs/05-string/05_str-indexOf.md",
    "content": "---\ntitle: \"Finding the Index of a Substring in a String\"\nsidebar:\n  label: String indexOf\n---\n## String indexOf: `String.indexOf()`\n\nThe `indexOf()` method in JavaScript is used to find the index of the **first occurrence** of a specified substring within a string.\n\nSyntax:\n```javascript\nstring.indexOf(searchValue, startIndex)\n```\n\n### The parameters\n\n1. **searchValue**: The substring to search for within the original string.\n\n2. **startIndex (optional)**: The index at which to start the search. If not specified, the search starts from the beginning of the string.\n\n### Return Value:\n\nThe `indexOf()` method returns **an integer** representing the index of the first occurrence of the specified substring. If the substring is **not found**, it returns `-1`.\n\n### Example\n\n```javascript\n// Finding the index of a substring\nconst str = 'Hello, world!';\n\nconst index = str.indexOf('world');\nconsole.log(index);\n// Output: 7\n```\n\nIn the example above, The `indexOf()` method is used to find the index of the first occurrence of the substring 'world' within the original string str. The resulting index, `7`, is stored in the variable index.\n\n```javascript\n// Finding the index of a substring with a specified start index\nconst str = 'Hello, world!';\n\nconst index = str.indexOf('o', 5);\nconsole.log(index);\n// Output: 8\n```\n\nIn the example above, The `indexOf()` method is used to find the index of the first occurrence of the character 'o' within the original string **str**. The search starts from index `5`. The resulting index, `8`, is stored in the variable index.\n\n```javascript\n// Finding the index of a substring that is not present\nconst str = 'Hello, world!';\n\nconst index = str.indexOf('universe');\nconsole.log(index);\n// Output: -1\n```\n\nIn the example above, The `indexOf()`  method is used to find the index of the first occurrence of the substring **'universe'** within the original string str. Since 'universe' is not present in the string, the method returns `-1`, which is stored in the variable index.\n\nBy using the `String.indexOf()` method, you can efficiently determine the position of a specified substring within a given string, allowing for various string manipulation operations in JavaScript."
  },
  {
    "path": "src/content/docs/05-string/06_str-repeat.md",
    "content": "---\ntitle: \"Repeating a String\"\nsidebar:\n  label: Repeating a String\n---\n## String repeat: `String.repeat()`\n\nThe `repeat()` method in JavaScript is used to create a new string by repeating the original string a specified number of times.\n\nSyntax:\n```javascript\nstring.repeat(count)\n```\n\n### The parameters\n\n1. **count**: The number of times to repeat the original string. Must be a non-negative integer.\n\n### Return Value:\n\nThe `repeat()` method returns a new string representing the original string repeated the specified number of times.\n\n### Example\n\n```javascript\n// Repeating a string multiple times\nconst str = 'Hello, ';\n\nconst repeatedString = str.repeat(3);\nconsole.log(repeatedString);\n// Output: \"Hello, Hello, Hello, \"\n```\n\nIn the example above, the `repeat()` method is used to create a **new string** by repeating the original string 'Hello, ' `three` times. The resulting string, \"Hello, Hello, Hello, \", is stored in the variable repeatedString.\n\n```javascript\n// Repeating a string zero times\nconst str = 'Hello Javascript!';\n\nconst repeatedString = str.repeat(0);\nconsole.log(repeatedString);\n// Output: \"\"\n```\n\nIn this example, the `repeat()` method is used to create a new string by repeating the original string 'Hello Javascript!' `zero` times. The resulting string is an `empty string, \"\",` as the count is zero.\n\n```javascript\n// Repeating a string with a non-integer count\nconst str = 'repeatString()';\n\nconst repeatedString = str.repeat(2.5);\nconsole.log(repeatedString);\n// Output: \"repeatString()repeatString()\"\n```\n\nIn this example, the `repeat()` method is used with a non-integer count of `2.5`. The method automatically converts the count to an `integer (2 in this case)` and repeats the original string `'repeatString()'` accordingly. The resulting string, \"repeatString()repeatString()\", is stored in the variable repeatedString.\n\nBy using the `String.repeat()` method, you can easily generate repeated strings, providing a convenient way to handle string repetition in JavaScript."
  },
  {
    "path": "src/content/docs/05-string/07_str-split.md",
    "content": "---\ntitle: \"Splitting a String into an Array\"\nsidebar:\n  label: Splitting a String into an Array\n---\n## String split: `String.split()`\n\nThe `split()` method in JavaScript is used to split a string into an array of substrings based on a specified delimiter.\n\nSyntax:\n```javascript\nstring.split(separator, limit)\n```\n\n### The parameters\n\n1. **separator**: The character or **regular expression** used to specify where to split the string. If an empty string is used (''), the string is split into an array of individual characters.\n2. **limit (optional)**: An integer that specifies the maximum number of splits. The array will contain at most limit + 1 elements. If not specified or is negative, there is no limit to the number of splits.\n\n### Return Value:\n\nThe `split()` method returns an array of substrings resulting from the split.\n\n### Example\n\n```javascript\n// Splitting a string based on a space separator\nconst str = 'Hello, world!';\n\nconst splitArray = str.split(' ');\nconsole.log(splitArray);\n// Output: [\"Hello,\", \"world!\"]\n```\n\nIn the example above, the `split()` method is used to split the string 'Hello, world!' into an array of substrings based on the `space separator`. The resulting array, [\"Hello,\", \"world!\"], is stored in the variable splitArray.\n\n```javascript\n// Splitting a string based on a comma separator with a specified limit\nconst str = 'apple,orange,banana,grape';\n\nconst splitArray = str.split(',', 2);\nconsole.log(splitArray);\n// Output: [\"apple\", \"orange\"]\n```\n\nIn this example, the `split()` method is used to split the string 'apple,orange,banana,grape' into an array of substrings based on the `comma` separator. The specified `limit of 2` restricts the number of splits to at most two. The resulting array, [\"apple\", \"orange\"], is stored in the variable splitArray.\n\n```javascript\n// Splitting a string into individual characters\nconst str = 'Hello';\n\nconst splitArray = str.split('');\nconsole.log(splitArray);\n// Output: [\"H\", \"e\", \"l\", \"l\", \"o\"]\n```\n\nIn this example, the `split()` method is used to split the string 'Hello' into an array of `individual` characters by using `an empty string` as the separator. The resulting array, [\"H\", \"e\", \"l\", \"l\", \"o\"], is stored in the variable splitArray.\n\nBy using the `String.split()` method, you can easily convert a string into an array of substrings, providing a versatile way to manipulate and process string data in JavaScript."
  },
  {
    "path": "src/content/docs/05-string/08_str-toUppercase.md",
    "content": "---\ntitle: \"Converting a String to Uppercase\"\nsidebar:\n  label: Converting a String to Uppercase\n---\n## String uppercase: `String.toUpperCase()`\n\nThe `toUpperCase()` method in JavaScript is used to convert all characters in a string to uppercase. This is particularly useful when you want to standardize the case of characters for consistent comparison or display.\n\nSyntax:\n```javascript\nstring.toUpperCase()\n```\n\n### Return Value:\n\nThe `toUpperCase()` method returns a new string with all alphabetic characters converted to uppercase.\n\n### Example\n\n```javascript\n// Converting a string to uppercase\nconst str = 'Hello, world!';\n\nconst upperCasedString = str.toUpperCase();\nconsole.log(upperCasedString);\n// Output: \"HELLO, WORLD!\"\n```\n\nIn the example above, the `toUpperCase()` method is applied to the string 'Hello, world!' to convert all characters to uppercase. The resulting string, \"HELLO, WORLD!\", is stored in the variable upperCasedString.\n\nBy using the `String.toUpperCase()` method, you can easily ensure a consistent uppercase format for strings in your JavaScript applications. This is particularly useful for scenarios where case-insensitive comparisons or standardized formatting are required."
  },
  {
    "path": "src/content/docs/05-string/09_str-toLowercase.md",
    "content": "---\ntitle: \"Converting a String to Lowercase\"\nsidebar:\n  label: Converting a String to Lowercase\n---\n## String lowercase: `String.toLowerCase()`\n\nThe `toLowerCase()` method in JavaScript is used to convert all characters in a string to lowercase. This can be beneficial for ensuring consistency in **character casing, aiding in comparisons** and display.\n\nSyntax:\n```javascript\nstring.toLowerCase()\n```\n\n### Return Value:\n\nThe `toLowerCase()` method returns a new string with all alphabetic characters converted to `lowercase`.\n\n### Example\n\n```javascript\n// Converting a string to lowercase\nconst str = 'Hello, World!';\n\nconst lowercasedString = str.toLowerCase();\nconsole.log(lowercasedString);\n// Output: \"hello, world!\"\n```\n\nIn the example above, the `toLowerCase()` method is applied to the string 'Hello, World!' to convert all characters to `lowercase`. The resulting string, \"hello, world!\", is stored in the variable lowercasedString.\n\nBy using the String.`toLowerCase()` method, you can easily achieve a consistent `lowercase` format for strings in your JavaScript applications. This is particularly useful for scenarios where case-insensitive comparisons or standardized formatting are required."
  },
  {
    "path": "src/content/docs/05-string/10_str-startsWith.md",
    "content": "---\ntitle: \"Checking if a String Starts With a Substring\"\nsidebar:\n  label: String startsWith\n---\n## String startsWith: `String.startsWith()`\n\nThe `startsWith()` method in JavaScript is used to determine whether a string begins with the characters of a specified substring. It returns a `boolean` value indicating the result of the comparison.\n\nSyntax:\n```javascript\nstring.startsWith(searchString, position)\n```\n\n### The parameters\n\n1. **searchString**: The substring to search for at the `beginning` of the string.\n2. **position (optional)**: The position in the string to begin the search. It is an integer value, the default is 0. If a **negative** value is provided, it is **treated as 0**.\n\n### Return Value:\n\nThe `startsWith()` method returns true if the string starts with the specified substring; otherwise, it returns `false`.\n\n### Example\n\n```javascript\n// Checking if a string starts with a specific substring\nconst str = 'Hello, world!';\n\nconst startsWithHello = str.startsWith('Hello');\nconsole.log(startsWithHello);\n// Output: true\n```\n\nIn the example above, the `startsWith()` method is used to check if the string 'Hello, world!' starts with the substring 'Hello'. The result, `true`, is stored in the variable startsWithHello.\n\n```javascript\n// Checking if a string starts with a substring at a specific position\nconst str = 'Hello, world!';\n\nconst startsWithWorld = str.startsWith('world', 7);\nconsole.log(startsWithWorld);\n// Output: true\n\nconst startsWithHello = str.startsWith('hello', 7)\nconsole.log(startsWithHello);\n// Output: false\n```\n\nIn this example, the `startsWith()` method is used to check if the substring 'world' starts at position `7` in the string 'Hello, world!'. The result, `true`, is stored in the variable startsWithWorld.\n\nIn a second example, the `startsWith()` method is again used, but this time to check if the substring 'hello' starts at `position 7` in the string 'Hello, world!'. The startsWithHello variable will be assigned the value `false` because, starting from position `7`, the substring 'hello' is **not found** at the beginning of the **remaining part** of the string.\n\n:::note\nthe comparison is case-sensitive, so 'Hello' and 'hello' are considered different in this context.\n:::\n\n```javascript\n// Checking if a string starts with a substring at a position beyond the string length\nconst str = 'Hello, world!';\n\nconst startsWithBeyondLength = str.startsWith('world', 15);\nconsole.log(startsWithBeyondLength);\n// Output: false\n```\n\nIn this example, the `startsWith()` method is used to check if the substring 'world' starts at position `15` in the string 'Hello, world!'. Since the position is **beyond the length** of the string, the result is `false`, which is stored in the variable startsWithBeyondLength.\n\n```javascript\n// Checking if a string starts with a substring using a negative position\nconst str = 'Hello, world!';\n\nconst startsWithUniverseNegative = str.startsWith('universe', -20);\nconsole.log(startsWithUniverseNegative);\n// Output: false\n\nconst startsWithHelloNegative = str.startsWith('Hello', -20);\nconsole.log(startsWithHelloNegative);\n// Output: true\n```\n\n:::note\nIf a **negative** value is provided, it is **treated as 0**. so, the search starts from the beginning of the string.\n:::\n\nIn this example, the `startsWith()` method is used to check if the string 'Hello, world!' starts with the substring 'universe' when starting the search from the beginning. The result, `false`, is stored in the variable startsWithHelloNegative.\n\nIn this second example, the `startsWith()` method is used to check if the string 'Hello, world!' starts with the substring 'Hello' when starting the search from beginning. Since 'Hello' is found at **default index 0**, the result is `true`.\n\nBy using the `String.startsWith()` method, you can efficiently check if a string begins with a specified substring, providing a useful tool for string comparison in JavaScript."
  },
  {
    "path": "src/content/docs/05-string/11_str-replaceAll.md",
    "content": "---\ntitle: \"Replacing All Occurrences of a Substring\"\nsidebar:\n  label: String replaceAll\n---\n## String replaceAll: `String.replaceAll()`\n\nThe `replaceAll()` method in JavaScript is used to replace all occurrences of a specified substring with another substring. It returns a new string with all matches of the substring replaced.\n\nSyntax:\n```javascript\nstring.replaceAll(searchValue, newValue)\n```\n\n### The parameters\n\n1. **searchValue**: The substring or regular expression to search for within the string.\n2. **newValue**: The string to replace each match of searchValue with.\n\n### Return Value:\n\nThe `replaceAll()` method returns a new string where all occurrences of the `searchValue` have been replaced by the `newValue`.\n\n### Example\n\n```javascript\n// Replacing all occurrences of a substring\nconst str = 'Hello, world! Hello again, world!';\n\nconst replacedHello = str.replaceAll('Hello', 'Hi');\nconsole.log(replacedHello);\n// Output: \"Hi, world! Hi again, world!\"\n```\n\nIn this example, the `replaceAll()` method is used to replace all occurrences of the substring 'Hello' with 'Hi'. The result, `\"Hi, world! Hi again, world!\"`, is stored in the variable `replacedHello`.\n\n```javascript\n// Replacing all occurrences of a substring that's not found\nconst str = 'Hello, world!';\n\nconst replacedUniverse = str.replaceAll('universe', 'galaxy');\nconsole.log(replacedUniverse);\n// Output: \"Hello, world!\"\n```\n\nIn this example, the `replaceAll()` method is used to attempt to replace the substring 'universe', which is not present in the string 'Hello, world!'. Since 'universe' is not found, the original string is returned unchanged.\n\n```javascript\n// Replacing using a regular expression\nconst str = 'Hello, world! Hello again, world!';\n\nconst replacedWorldWithRegex = str.replaceAll(/world/g, 'earth');\nconsole.log(replacedWorldWithRegex);\n// Output: \"Hello, earth! Hello again, earth!\"\n```\n\nIn this example, a regular expression `/world/g` is used with the `replaceAll()` method to replace all occurrences of 'world' with 'earth'. The result is `\"Hello, earth! Hello again, earth!\"`.\n\n```javascript\n// Replacing case-sensitive strings\nconst str = 'Hello, world!';\n\nconst replacedCaseSensitive = str.replaceAll('hello', 'Hi');\nconsole.log(replacedCaseSensitive);\n// Output: \"Hello, world!\"\n```\n\nIn this example, the `replaceAll()` method attempts to replace the lowercase 'hello' in the string 'Hello, world!'. Since the method is case-sensitive, no replacement occurs, and the original string is returned.\n\n```javascript\n// Replacing special characters\nconst strWithSymbols = 'This is a $test$ string with $symbols$';\n\nconst replacedSymbols = strWithSymbols.replaceAll('$', '#');\nconsole.log(replacedSymbols);\n// Output: \"This is a #test# string with #symbols#\"\n```\n\nIn this example, the `replaceAll()` method is used to replace the special character `$` with `#` in the string. All occurrences of `$` are replaced.\n\n```javascript\n// Replacing a substring with an empty string\nconst str = 'Hello, world! Hello again, world!';\n\nconst removedWorld = str.replaceAll('world', '');\nconsole.log(removedWorld);\n// Output: \"Hello, ! Hello again, !\"\n```\n\nIn this example, the `replaceAll()` method is used to remove all occurrences of 'world' by replacing them with an empty string `''`. The result is `\"Hello, ! Hello again, !\"`.\n\n### See also\n\n- [String.prototype.replaceAll()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll)\n"
  },
  {
    "path": "src/content/docs/05-string/12_str-trimstart-trimend.md",
    "content": "---\ntitle: 'Trimming Whitespace from the Start and End of a String'\ndescription: 'Removes whitespace from the beginning or end of a string without altering the original content'\nsidebar:\n  label: Trimming Whitespace\n---\n\n## Removing Whitespace from the Start: `trimStart()`\n\nThe `trimStart()` method of String instances removes whitespace from the beginning (leading whitespace) of a string. This method returns a new string without modifying the original string.\n\n\n```js\n//Syntax\ntrimStart()\n```\n\n- The method does not modify the original string but returns a new string with trailing whitespace removed.\n\n### Example : \n\nUsing `trimStart()` to remove leading whitespace:\n\n```js\nconst str = \"   Hello, World!   \";\n\nlet trimmedStr = str.trimStart();\n\nconsole.log(trimmedStr); \n// \"Hello, World!   \"\n\n```\n\nIn this example:\n\n- The original string has leading whitespace before the text `“Hello, World!”`.\n- The `trimStart()` function removes this leading whitespace, leaving the rest of the string intact.\n\n## Removing Whitespace from the End: `trimEnd()`\n\nThe `trimEnd()` method of String instances removes whitespace from the end (trailing whitespace) of a string. This method returns a new string without modifying the original string.\n\n\n```js\n//Syntax\ntrimEnd()\n```\n\n- The method does not modify the original string but returns a new string with trailing whitespace removed.\n\n### Example: \n\nUsing `trimEnd()` to remove trailing whitespace:\n\n\n```js\nconst str = \"   Hello, World!   \";\n\nlet trimmedStr = str.trimEnd();\n\nconsole.log(trimmedStr); \n// \"   Hello, World!\"\n\n```\n\nIn this example:\n\n- The original string has trailing whitespace after the text `“Hello, World!”`.\n- The `trimEnd()` function removes this trailing whitespace, leaving the rest of the string intact.\n\n\n\n\n### Notes\n\n- The `trimStart()` method removes whitespace only from the beginning of the string.\n- The `trimEnd()` method removes whitespace only from the end of the string.\n- Neither method changes the original string; they return a new string instead.\n- `trimLeft()` and `trimRight()` are aliases for `trimStart()` and `trimEnd()` respectively."
  },
  {
    "path": "src/content/docs/05-string/13_str-trim.md",
    "content": "---\ntitle: \"Removing whitespace from both ends of a string\"\nsidebar:\n  label: String trim\n---\n\n## String trim: `String.trim()`\n\nThe **trim()** method in JavaScript removes whitespace from both ends of a string. Whitespace characters include spaces, tabs, no-break spaces, and all line terminator characters (such as line feed, carriage return, etc.).\n\nSyntax:\n```javascript\nstring.trim()\n```\n\n### Parameters:\n\nThe `trim()` method doesn't take any parameters.\n\n### Return Value:\n\nThe `trim()` method returns a new string with whitespace removed from both ends of the original string. It does not modify the original string.\n\n### Examples:\n\n#### Basic Usage:\n\n```javascript\nconst greeting = '   Hello world!   ';\nconsole.log(greeting.trim());\n// Output: \"Hello world!\"\n```\n\nIn this example, the `trim()` method removes the spaces from both the beginning and the end of the string.\n\n#### Removing Various Whitespace Characters:\n\n```javascript\nconst text = '\\t\\n  JavaScript is awesome!  \\n\\r';\nconsole.log(text.trim());\n// Output: \"JavaScript is awesome!\"\n```\n\nThis example demonstrates how `trim()` removes all types of whitespace characters, including tabs (`\\t`), line feeds (`\\n`), and carriage returns (`\\r`).\n\n#### Chaining with Other String Methods:\n\n```javascript\nconst userInput = '   hello@example.com   ';\nconst normalizedEmail = userInput.trim().toLowerCase();\nconsole.log(normalizedEmail);\n// Output: \"hello@example.com\"\n```\n\nHere, we first remove the whitespace using `trim()` and then convert the string to lowercase using `toLowerCase()`.\n\n### Common Use Cases:\n\n1. **Form Validation**: When validating user input from forms, `trim()` is commonly used to remove accidental spaces that users might have entered.\n\n```javascript\nfunction validateUsername(username) {\n  const trimmedUsername = username.trim();\n  return trimmedUsername.length >= 3;\n}\n\nconsole.log(validateUsername('   user   ')); // true\nconsole.log(validateUsername('  ab  ')); // false\n```\n\n2. **Data Cleaning**: When processing data from external sources, `trim()` helps in cleaning up the data by removing unnecessary whitespace.\n\n```javascript\nconst csvData = ['  name ', ' age ', ' city  '];\nconst cleanData = csvData.map(item => item.trim());\nconsole.log(cleanData);\n// Output: [\"name\", \"age\", \"city\"]\n```\n\nBy using the `String.trim()` method, you can easily remove unwanted whitespace from the beginning and end of strings, which is particularly useful for cleaning user input and processing data in JavaScript applications. "
  },
  {
    "path": "src/content/docs/05-string/14_str-endsWith.md",
    "content": "---\ntitle: \"Checking if a string ends with a specific substring\"\nsidebar:\n  label: String endsWith\n---\n\n## String endsWith: `String.endsWith()`\n\nThe **endsWith()** method in JavaScript determines whether a string ends with the characters of a specified string. This method returns true if the string ends with the specified string, and false otherwise.\n\nSyntax:\n```javascript\nstring.endsWith(searchString, length)\n```\n\n### Parameters:\n\n1. **searchString**: The characters to be searched for at the end of the string.\n2. **length (optional)**: The length of the string to search within. This allows you to specify a portion of the string to check. If omitted, the default is the length of the string.\n\n### Return Value:\n\nThe `endsWith()` method returns a boolean value:\n- `true` if the string ends with the characters of the searchString\n- `false` if the string does not end with the characters of the searchString\n\n### Examples:\n\n#### Basic Usage:\n\n```javascript\nconst sentence = 'This is a complete sentence.';\nconsole.log(sentence.endsWith('sentence.')); // Output: true\nconsole.log(sentence.endsWith('question.')); // Output: false\n```\n\nIn this example, the `endsWith()` method checks if the string ends with 'sentence.' (which it does) and 'question.' (which it doesn't).\n\n#### Using the Length Parameter:\n\n```javascript\nconst filename = 'document.pdf';\nconsole.log(filename.endsWith('pdf')); // Output: true\n\n// Check if the first 8 characters end with 'doc'\nconsole.log(filename.endsWith('doc', 8)); // Output: true\n```\n\nIn this example, we first check if the filename ends with 'pdf'. Then, by specifying a length of 8, we check if the first 8 characters ('document') end with 'doc'.\n\n#### Case Sensitivity:\n\n```javascript\nconst text = 'JavaScript is awesome!';\nconsole.log(text.endsWith('awesome!')); // Output: true\nconsole.log(text.endsWith('AWESOME!')); // Output: false\n```\n\nThe `endsWith()` method is case-sensitive, so 'awesome!' and 'AWESOME!' are treated as different strings.\n\n### Common Use Cases:\n\n1. **File Extension Validation**: Check if a file has a specific extension.\n\n```javascript\nfunction isImageFile(filename) {\n  const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];\n  return imageExtensions.some(ext => filename.toLowerCase().endsWith(ext));\n}\n\nconsole.log(isImageFile('vacation.jpg')); // Output: true\nconsole.log(isImageFile('document.pdf')); // Output: false\n```\n\n2. **URL Validation**: Verify if a URL ends with a specific domain or path.\n\n```javascript\nfunction isSecureGoogleUrl(url) {\n  return url.toLowerCase().endsWith('.google.com') && url.startsWith('https://');\n}\n\nconsole.log(isSecureGoogleUrl('https://www.google.com')); // Output: true\nconsole.log(isSecureGoogleUrl('http://www.google.com')); // Output: false\n```\n\n3. **String Formatting Validation**: Check if text follows a specific format or ends with expected characters.\n\n```javascript\nfunction endsWithPunctuation(text) {\n  const punctuation = ['.', '!', '?'];\n  return punctuation.some(p => text.endsWith(p));\n}\n\nconsole.log(endsWithPunctuation('Hello world!')); // Output: true\nconsole.log(endsWithPunctuation('Hello world')); // Output: false\n```\n\nBy using the `String.endsWith()` method, you can easily check if a string ends with specific characters, which is particularly useful for validating file types, URL formats, and ensuring proper string formatting in JavaScript applications.\n"
  },
  {
    "path": "src/content/docs/05-string/15_str-substring.md",
    "content": "---\ntitle: \"Extracting parts of a string\"\nsidebar:\n  label: String substring\n---\n\n## String substring: `String.substring()`\n\nThe **substring()** method in JavaScript extracts characters from a string between two specified indices and returns a new string. This method extracts characters from the start index up to (but not including) the end index.\n\nSyntax:\n```javascript\nstring.substring(startIndex, endIndex)\n```\n\n### Parameters:\n\n1. **startIndex**: The position where extraction begins. If startIndex is negative, it is treated as 0.\n2. **endIndex (optional)**: The position where extraction ends (up to but not including the character at this index). If omitted, extraction continues to the end of the string.\n\n### Return Value:\n\nThe `substring()` method returns a new string containing the extracted characters. It does not modify the original string.\n\n### Examples:\n\n#### Basic Usage:\n\n```javascript\nconst text = 'JavaScript';\nconsole.log(text.substring(0, 4)); // Output: \"Java\"\nconsole.log(text.substring(4)); // Output: \"Script\"\n```\n\nIn this example, the first call extracts characters from index 0 to (but not including) index 4, resulting in \"Java\". The second call extracts characters from index 4 to the end of the string, resulting in \"Script\".\n\n#### Handling Out-of-Range Indices:\n\n```javascript\nconst text = 'Hello';\nconsole.log(text.substring(-3, 2)); // Output: \"He\"\nconsole.log(text.substring(2, 10)); // Output: \"llo\"\n```\n\nIf startIndex is negative, it is treated as 0. If endIndex is greater than the string's length, extraction continues to the end of the string.\n\n#### Swapping Parameters:\n\n```javascript\nconst text = 'JavaScript';\nconsole.log(text.substring(4, 0)); // Output: \"Java\"\n```\n\nIf startIndex is greater than endIndex, the `substring()` method swaps the two arguments. This is different from the `slice()` method, which returns an empty string in such cases.\n\n### Comparison with slice():\n\nThe `substring()` and `slice()` methods are similar, but they handle negative indices differently:\n\n```javascript\nconst text = 'JavaScript';\nconsole.log(text.substring(-3)); // Output: \"JavaScript\" (treats -3 as 0)\nconsole.log(text.slice(-3)); // Output: \"ipt\" (counts from the end)\n```\n\nThe `substring()` method treats negative indices as 0, while the `slice()` method counts from the end of the string.\n\n### Common Use Cases:\n\n1. **Extracting a Portion of Text**:\n\n```javascript\nfunction truncateText(text, maxLength) {\n  if (text.length <= maxLength) {\n    return text;\n  }\n  return text.substring(0, maxLength) + '...';\n}\n\nconst longText = 'This is a very long text that needs to be truncated';\nconsole.log(truncateText(longText, 20)); // Output: \"This is a very long...\"\n```\n\n2. **Parsing URL Components**:\n\n```javascript\nfunction getDomainFromUrl(url) {\n  // Remove protocol\n  let domain = url;\n  if (url.indexOf('://') > -1) {\n    domain = url.substring(url.indexOf('://') + 3);\n  }\n  \n  // Remove path\n  if (domain.indexOf('/') > -1) {\n    domain = domain.substring(0, domain.indexOf('/'));\n  }\n  \n  return domain;\n}\n\nconsole.log(getDomainFromUrl('https://example.com/path')); // Output: \"example.com\"\n```\n\n3. **Removing Specific Characters**:\n\n```javascript\nfunction removeFirstAndLastChar(text) {\n  return text.substring(1, text.length - 1);\n}\n\nconsole.log(removeFirstAndLastChar('\"quoted\"')); // Output: \"quoted\"\n```\n\nBy using the `String.substring()` method, you can efficiently extract portions of strings, which is a common operation in text processing, data parsing, and user interface development in JavaScript applications. "
  },
  {
    "path": "src/content/docs/05-string/16_str-replace.md",
    "content": "---\ntitle: \"Replacing substrings in a string\"\nsidebar:\n  label: String replace\n---\n\n## String replace: `String.replace()`\n\nThe **replace()** method in JavaScript returns a new string with some or all matches of a pattern replaced by a replacement. The pattern can be a string or a regular expression, and the replacement can be a string or a function.\n\nSyntax:\n```javascript\nstring.replace(pattern, replacement)\n```\n\n### Parameters:\n\n1. **pattern**: A string or regular expression that is matched against the string. If it's a string, only the first occurrence will be replaced.\n2. **replacement**: The string that replaces the substring matched by the pattern. It can also be a function that returns the replacement string.\n\n### Return Value:\n\nThe `replace()` method returns a new string with some or all matches of the pattern replaced by the replacement. The original string is left unchanged.\n\n### Examples:\n\n#### Basic Usage with String Pattern:\n\n```javascript\nconst text = 'Hello, world!';\nconst newText = text.replace('world', 'JavaScript');\nconsole.log(newText); // Output: \"Hello, JavaScript!\"\n```\n\nIn this example, the string 'world' is replaced with 'JavaScript'. Note that only the first occurrence is replaced.\n\n#### Using Regular Expression:\n\n```javascript\nconst text = 'The quick brown fox jumps over the lazy dog.';\nconst newText = text.replace(/fox|dog/g, 'animal');\nconsole.log(newText); // Output: \"The quick brown animal jumps over the lazy animal.\"\n```\n\nBy using a regular expression with the global flag (`g`), all occurrences of 'fox' and 'dog' are replaced with 'animal'.\n\n#### Case-Insensitive Replacement:\n\n```javascript\nconst text = 'JavaScript is awesome. javascript is fun.';\nconst newText = text.replace(/javascript/i, 'TypeScript');\nconsole.log(newText); // Output: \"TypeScript is awesome. javascript is fun.\"\n```\n\nThe `i` flag makes the regular expression case-insensitive, but only the first occurrence is replaced because we didn't use the global flag.\n\n#### Using Function as Replacement:\n\n```javascript\nconst text = 'the apple, the orange, and the banana';\nconst newText = text.replace(/apple|orange|banana/g, match => match.toUpperCase());\nconsole.log(newText); // Output: \"the APPLE, the ORANGE, and the BANANA\"\n```\n\nHere, a function is used as the replacement, which converts each matched fruit name to uppercase.\n\n### Common Use Cases:\n\n1. **Text Formatting**:\n\n```javascript\nfunction formatPhoneNumber(phoneNumber) {\n  // Format: XXX-XXX-XXXX\n  return phoneNumber.replace(/(\\d{3})(\\d{3})(\\d{4})/, '$1-$2-$3');\n}\n\nconsole.log(formatPhoneNumber('1234567890')); // Output: \"123-456-7890\"\n```\n\n2. **Sanitizing User Input**:\n\n```javascript\nfunction sanitizeHTML(text) {\n  const map = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#039;'\n  };\n  return text.replace(/[&<>\"']/g, m => map[m]);\n}\n\nconsole.log(sanitizeHTML('<script>alert(\"XSS\")</script>')); \n// Output: \"&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;\"\n```\n\n3. **URL Slug Creation**:\n\n```javascript\nfunction createSlug(title) {\n  return title\n    .toLowerCase()\n    .replace(/\\s+/g, '-')     // Replace spaces with -\n    .replace(/[^\\w-]+/g, '')  // Remove all non-word chars\n    .replace(/--+/g, '-')     // Replace multiple - with single -\n    .replace(/^-+/, '')       // Trim - from start of text\n    .replace(/-+$/, '');      // Trim - from end of text\n}\n\nconsole.log(createSlug('Hello World! This is a Title')); // Output: \"hello-world-this-is-a-title\"\n```\n\nBy using the `String.replace()` method, you can efficiently perform string substitutions and transformations, which is essential for text processing, data cleaning, and formatting in JavaScript applications.\n"
  },
  {
    "path": "src/content/docs/05-string/17_str-lastIndexOf.md",
    "content": "---\ntitle: \"Finding the last occurrence of a substring\"\nsidebar:\n  label: String lastIndexOf\n---\n\n## String lastIndexOf: `String.lastIndexOf()`\n\nThe **lastIndexOf()** method in JavaScript returns the index of the last occurrence of a specified value in a string. It searches the string from the end to the beginning and returns the position where the specified value is found. If the value is not found, it returns -1.\n\nSyntax:\n```javascript\nstring.lastIndexOf(searchValue, fromIndex)\n```\n\n### Parameters:\n\n1. **searchValue**: The string to search for.\n2. **fromIndex (optional)**: The position in the string at which to begin searching backward. If omitted, the default is the length of the string, which means the entire string is searched.\n\n### Return Value:\n\nThe `lastIndexOf()` method returns the index of the last occurrence of the specified value in the string, searching backward from the specified position. If the value is not found, it returns -1.\n\n### Examples:\n\n#### Basic Usage:\n\n```javascript\nconst text = 'JavaScript is amazing. JavaScript is fun.';\nconst lastIndex = text.lastIndexOf('JavaScript');\nconsole.log(lastIndex); // Output: 25\n```\n\nIn this example, the `lastIndexOf()` method finds the last occurrence of 'JavaScript' in the string, which starts at index 25.\n\n#### Using fromIndex Parameter:\n\n```javascript\nconst text = 'JavaScript is amazing. JavaScript is fun.';\nconst lastIndex = text.lastIndexOf('JavaScript', 20);\nconsole.log(lastIndex); // Output: 0\n```\n\nBy specifying a `fromIndex` of 20, the search starts from position 20 and goes backward. The first occurrence of 'JavaScript' (starting from index 0) is found.\n\n#### Searching for a Character:\n\n```javascript\nconst text = 'Hello, world!';\nconst lastIndex = text.lastIndexOf('o');\nconsole.log(lastIndex); // Output: 8\n```\n\nThe last occurrence of the character 'o' is at index 8.\n\n#### Not Found Case:\n\n```javascript\nconst text = 'Hello, world!';\nconst lastIndex = text.lastIndexOf('z');\nconsole.log(lastIndex); // Output: -1\n```\n\nSince the character 'z' is not in the string, the method returns -1.\n\n### Common Use Cases:\n\n1. **File Extension Extraction**:\n\n```javascript\nfunction getFileExtension(filename) {\n  const dotIndex = filename.lastIndexOf('.');\n  return dotIndex === -1 ? '' : filename.substring(dotIndex + 1);\n}\n\nconsole.log(getFileExtension('document.pdf')); // Output: \"pdf\"\nconsole.log(getFileExtension('image.large.jpg')); // Output: \"jpg\"\nconsole.log(getFileExtension('noextension')); // Output: \"\"\n```\n\n2. **Finding the Last Word in a Sentence**:\n\n```javascript\nfunction getLastWord(sentence) {\n  const lastSpaceIndex = sentence.lastIndexOf(' ');\n  return lastSpaceIndex === -1 ? sentence : sentence.substring(lastSpaceIndex + 1);\n}\n\nconsole.log(getLastWord('Hello, world!')); // Output: \"world!\"\nconsole.log(getLastWord('JavaScript')); // Output: \"JavaScript\"\n```\n\n3. **Checking if a String Ends with a Specific Substring**:\n\n```javascript\nfunction endsWith(str, suffix) {\n  const position = str.lastIndexOf(suffix);\n  return position !== -1 && position === str.length - suffix.length;\n}\n\nconsole.log(endsWith('Hello, world!', 'world!')); // Output: true\nconsole.log(endsWith('Hello, world!', 'Hello')); // Output: false\n```\n\nNote: Modern JavaScript has the built-in `endsWith()` method which is preferred for this use case.\n\nBy using the `String.lastIndexOf()` method, you can efficiently locate the last occurrence of a substring within a string, which is particularly useful for parsing file paths, extracting extensions, and performing other string manipulation tasks in JavaScript applications. "
  },
  {
    "path": "src/content/docs/05-string/18_str-match.md",
    "content": "---\ntitle: \"Matching strings against regular expressions\"\nsidebar:\n  label: String match\n---\n\n## String match: `String.match()`\n\nThe **match()** method in JavaScript retrieves the result of matching a string against a regular expression. It returns an array of matches or null if no matches are found.\n\nSyntax:\n```javascript\nstring.match(regexp)\n```\n\n### Parameters:\n\n1. **regexp**: A regular expression object. If not a regular expression, it is implicitly converted to one using `new RegExp(regexp)`.\n\n### Return Value:\n\nThe `match()` method returns an array with the matches, or null if no matches are found. The returned array has the following properties:\n\n- If the regular expression doesn't have the global flag (`g`), the array contains the first match found and any capturing groups.\n- If the regular expression has the global flag (`g`), the array contains all matches but no capturing groups.\n\n### Examples:\n\n#### Basic Usage:\n\n```javascript\nconst text = 'The rain in Spain stays mainly in the plain';\nconst matches = text.match(/ain/g);\nconsole.log(matches); // Output: [\"ain\", \"ain\", \"ain\"]\n```\n\nIn this example, the `match()` method finds all occurrences of 'ain' in the string and returns them as an array.\n\n#### Without Global Flag:\n\n```javascript\nconst text = 'The rain in Spain stays mainly in the plain';\nconst match = text.match(/ain/);\nconsole.log(match);\n// Output: [\"ain\", index: 5, input: \"The rain in Spain stays mainly in the plain\", groups: undefined]\n```\n\nWithout the global flag, `match()` returns an array with the first match and additional properties like the index where the match was found.\n\n#### Using Capturing Groups:\n\n```javascript\nconst text = 'JavaScript was created in 1995';\nconst match = text.match(/(\\w+) was created in (\\d+)/);\nconsole.log(match);\n// Output: [\"JavaScript was created in 1995\", \"JavaScript\", \"1995\", index: 0, input: \"JavaScript was created in 1995\", groups: undefined]\n```\n\nThe first element is the entire match, followed by each captured group.\n\n#### No Match Case:\n\n```javascript\nconst text = 'Hello, world!';\nconst matches = text.match(/xyz/);\nconsole.log(matches); // Output: null\n```\n\nWhen no matches are found, `match()` returns null.\n\n### Common Use Cases:\n\n1. **Extracting Information from Text**:\n\n```javascript\nfunction extractEmails(text) {\n  const emailRegex = /[\\w.-]+@[\\w.-]+\\.\\w+/g;\n  return text.match(emailRegex) || [];\n}\n\nconst content = 'Contact us at support@example.com or sales@example.com for assistance.';\nconsole.log(extractEmails(content)); \n// Output: [\"support@example.com\", \"sales@example.com\"]\n```\n\n2. **Parsing Data from Formatted Text**:\n\n```javascript\nfunction parseCSVLine(line) {\n  return line.match(/(\".*?\"|[^,]+)(?=,|$)/g)\n    .map(item => item.replace(/^\"|\"$/g, ''));\n}\n\nconst csvLine = 'John,\"Doe,Jr\",42,\"New York, NY\"';\nconsole.log(parseCSVLine(csvLine)); \n// Output: [\"John\", \"Doe,Jr\", \"42\", \"New York, NY\"]\n```\n\n3. **Validating Input Format**:\n\n```javascript\nfunction isValidUsername(username) {\n  // Alphanumeric, 3-16 characters\n  const match = username.match(/^[a-z0-9]{3,16}$/i);\n  return match !== null;\n}\n\nconsole.log(isValidUsername('user123')); // Output: true\nconsole.log(isValidUsername('us')); // Output: false (too short)\nconsole.log(isValidUsername('user@123')); // Output: false (invalid character)\n```\n\n### Using match() with String Methods:\n\nThe `match()` method is often combined with other string methods for more complex text processing:\n\n```javascript\nfunction countWords(text) {\n  const words = text.toLowerCase().match(/\\b\\w+\\b/g) || [];\n  return words.length;\n}\n\nconst paragraph = 'The quick brown fox jumps over the lazy dog.';\nconsole.log(countWords(paragraph)); // Output: 9\n```\n\nBy using the `String.match()` method, you can perform powerful pattern matching and text extraction operations using regular expressions, which is essential for data validation, parsing, and text analysis in JavaScript applications. "
  },
  {
    "path": "src/content/docs/06-files/00_files.md",
    "content": "---\ntitle: \"File handling in JavaScript: essential functions for efficient file management\"\ndescription: Discover essential JavaScript functions for handling files with ease. Learn how to read, write, and manage files effectively in Node.js to build robust, cross-platform applications. Improve your data persistence and automation skills with our comprehensive guide to JavaScript file handling.\nsidebar:\n  label: Introduction\n---\n\n## File Handling in JavaScript\n\nWorking with files is fundamental to many JavaScript applications, from reading and writing data to managing configurations and logs. Mastering file handling allows developers to build more versatile and dynamic applications, whether for server-side scripting with Node.js or developing tools that require interaction with the file system.\n\nIn this chapter, we’ll explore a range of powerful JavaScript functions designed to handle files efficiently. Understanding these functions is crucial for tasks such as reading from or writing to files, managing directories, and performing file operations like renaming or deleting.\n\nEffective file handling is essential for creating applications that can manage data persistence, automate workflows, and process large datasets. Whether you're building a simple script or a complex application, having a solid grasp of these file-handling techniques will greatly enhance your ability to develop robust and scalable solutions in JavaScript."
  },
  {
    "path": "src/content/docs/06-files/01_files-cwd.md",
    "content": "---\ntitle: 'Getting the Current Working Directory'\ndescription: 'Using process.cwd() to retrieve the current working directory'\nsidebar:\n  label: Current Directory\n---\n\n## Getting the current working directory with `process.cwd()`\n\nThe `process.cwd()` method returns the current working directory of the process.\n\n## Syntax\n\n```javascript\nprocess.cwd()\n```\n\n### Parameters\n\nThis method doesn't take any parameters.\n\n### Return Value\n\nReturns a string representing the current working directory of the process.\n\n## Use Cases\n\n### 1. Accessing Files Relative to the Current Directory\n\n```javascript\nconst fs = require('fs');\nconst path = require('path');\n\nconst currentDir = process.cwd();\nconst filePath = path.join(currentDir, 'example.txt');\n\nfs.readFile(filePath, 'utf8', (err, data) => {\n  if (err) throw err;\n  console.log(data);\n});\n```\n\n### 2. Logging the Current Working Directory\n\n```javascript\nconsole.log(`The current working directory is: ${process.cwd()}`);\n```\n\n## Common Pitfalls\n\n1. **Assuming it's the Script's Directory**: `process.cwd()` returns the directory from which the JavaScript process was launched, not necessarily the directory of the script being executed.\n2. **Not Accounting for Symbolic Links**: If your application is run from a symbolic link, `process.cwd()` will return the real path, not the path of the symbolic link.\n\n## Additional Resources\n\n- [Node.js Documentation: process.cwd()](https://nodejs.org/api/process.html#processcwd)\n- [Node.js Documentation: process.chdir()](https://nodejs.org/api/process.html#processchdirdirectory)\n- [Working with File Paths in Node.js](https://nodejs.org/api/path.html)"
  },
  {
    "path": "src/content/docs/index.mdx",
    "content": "---\ntitle: Some drops of JavaScript\ndescription: Book that collects some useful, unknown, underrated JavaScript functions or stuff discovered, used, and learned during JavaScript daily use.\ntemplate: splash\n---\n\nimport { CardGrid, Card } from '@astrojs/starlight/components';\nimport AboutBlock from '../../components/about-block.astro'\nimport Hero from '../../components/hero.astro'\n\n<Hero />\n\n<CardGrid >\n\t<Card title=\"Open Source\" icon=\"open-book\">\n\t\tThis book is open source, meaning that both its content and the tools used for rendering the website are accessible. You can find it in [the GitHub repository](https://github.com/roberto-butti/some-drops-of-javascript).\n\t</Card>\n\t<Card title=\"Learn JavaScript functions\" icon=\"rocket\">\n\t\tStart reading the e-book for free and start learning the JavaScript language.\n    [Read the book](/00-intro/00_intro)\n\t</Card>\n\t<Card title=\"Collaborate\" icon=\"document\">\n\t\tWe deeply appreciate your willingness to contribute to the open-source book “Some Drops of JavaScript”. Your efforts make a significant impact on the JavaScript community, and we're grateful for your support.\n    [Collaborate](/00-intro/01_contributing/)\n\t</Card>\n\t<Card title=\"Join the Conversation\" icon=\"puzzle\">\n\t\tHave questions or want to discuss your contributions? Join us on the [repository issue section](https://github.com/roberto-butti/some-drops-of-javascript/issues), where you can create issues but also create suggestions, and feature requests.\n\t</Card>\n</CardGrid>\n\n<AboutBlock title=\"This book is about JavaScript\">\nJavaScript is a versatile scripting language\nwith a wide range of applications beyond\nits primary use in web development.\n<br/>\nOverall, JavaScript's versatility and wide adoption make it a powerful tool for a variety of applications beyond web development, including command-line tools, desktop and mobile applications, and even game development.\n<br/>\n[Learn about JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)\n\n</AboutBlock>\n\n<p align=\"center\">\n<a href=\"https://starlight.astro.build\"><img src=\"https://astro.badg.es/v2/built-with-starlight/small.svg\" alt=\"Built with Starlight\" width=\"224\" height=\"32\" /></a>\n</p>\n"
  },
  {
    "path": "src/content.config.ts",
    "content": "import { defineCollection } from 'astro:content';\nimport { docsLoader } from '@astrojs/starlight/loaders';\nimport { docsSchema } from '@astrojs/starlight/schema';\n\nexport const collections = {\n\tdocs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),\n};\n"
  },
  {
    "path": "src/env.d.ts",
    "content": "/// <reference path=\"../.astro/types.d.ts\" />\n/// <reference types=\"astro/client\" />\n"
  },
  {
    "path": "src/styles/custom.css",
    "content": "/* Dark mode colors. */\n@import url('https://fonts.googleapis.com/css2?family=Montserrat&display=swap');\n@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap');\nbody {\n  font-family: Montserrat;\n  font-size: large;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n.line {\n  font-family: 'JetBrains Mono', monospace;\n  font-size: larger;\n}\ncode {\n  font-family: 'JetBrains Mono', monospace;\n\n  margin: 0 0;\n  padding: 0.1em 0.4em;\n  line-height: normal;\n  border-radius: 0.8em 0.3em;\n  background: transparent;\n  background-image: linear-gradient(to right,\n      rgba(255, 225, 0, 0.1),\n      rgba(255, 225, 0, 0.7) 4%,\n      rgba(255, 225, 0, 0.3));\n  -webkit-box-decoration-break: clone;\n  box-decoration-break: clone;\n}\n\n/* Dark mode colors. */\n:root {\n  --sl-color-accent-low: #36113e;\n  --sl-color-accent: #a400c0;\n  --sl-color-accent-high: #e3b6ed;\n  --sl-color-white: #ffffff;\n  --sl-color-gray-1: #f2e9fd;\n  --sl-color-gray-2: #c7bdd5;\n  --sl-color-gray-3: #9581ae;\n  --sl-color-gray-4: #614e78;\n  --sl-color-gray-5: #412e55;\n  --sl-color-gray-6: #2f1c42;\n  --sl-color-black: #1c1425;\n}\n\n/* Light mode colors. */\n:root[data-theme='light'] {\n  --sl-color-accent-low: #ebc9f3;\n  --sl-color-accent: #a700c3;\n  --sl-color-accent-high: #4e0e5b;\n  --sl-color-white: #1c1425;\n  --sl-color-gray-1: #2f1c42;\n  --sl-color-gray-2: #412e55;\n  --sl-color-gray-3: #614e78;\n  --sl-color-gray-4: #9581ae;\n  --sl-color-gray-5: #c7bdd5;\n  --sl-color-gray-6: #f2e9fd;\n  --sl-color-gray-7: #f8f4fe;\n  --sl-color-black: #ffffff;\n}\n"
  },
  {
    "path": "src/styles/tailwind.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n"
  },
  {
    "path": "tailwind.config.mjs",
    "content": "import starlightPlugin from '@astrojs/starlight-tailwind'\n\n/** @type {import('tailwindcss').Config} */\nexport default {\n  content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],\n  darkMode: 'class',\n  theme: {\n    extend: {},\n  },\n  plugins: [starlightPlugin(), require('daisyui')],\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"extends\": \"astro/tsconfigs/strict\",\n  \"compilerOptions\": {\n    \"types\": [\n      \"bun-types\"\n    ]\n  }\n}"
  },
  {
    "path": "vercel.json",
    "content": "{\n  \"redirects\": [\n    {\n      \"source\": \"/00-intro/01_hacktoberfest/\",\n      \"destination\": \"/00-intro/01_contributing/\",\n      \"permanent\": true\n    }\n  ]\n}\n"
  }
]