This is page 5 of 14. Use http://codebase.md/shashankss1205/codegraphcontext?page={x} to view the full context.
# Directory Structure
```
├── .github
│ └── workflows
│ ├── e2e-tests.yml
│ ├── post_discord_invite.yml
│ ├── test.yml
│ └── update-contributors.yml
├── .gitignore
├── CONTRIBUTING.md
├── contributors.md
├── docs
│ ├── docs
│ │ ├── architecture.md
│ │ ├── cli.md
│ │ ├── contributing_languages.md
│ │ ├── contributing.md
│ │ ├── cookbook.md
│ │ ├── core.md
│ │ ├── future_work.md
│ │ ├── images
│ │ │ ├── 1.png
│ │ │ ├── 11.png
│ │ │ ├── 12.png
│ │ │ ├── 13.png
│ │ │ ├── 14.png
│ │ │ ├── 16.png
│ │ │ ├── 19.png
│ │ │ ├── 2.png
│ │ │ ├── 20.png
│ │ │ ├── 21.png
│ │ │ ├── 22.png
│ │ │ ├── 23.png
│ │ │ ├── 24.png
│ │ │ ├── 26.png
│ │ │ ├── 28.png
│ │ │ ├── 29.png
│ │ │ ├── 3.png
│ │ │ ├── 30.png
│ │ │ ├── 31.png
│ │ │ ├── 32.png
│ │ │ ├── 33.png
│ │ │ ├── 34.png
│ │ │ ├── 35.png
│ │ │ ├── 36.png
│ │ │ ├── 38.png
│ │ │ ├── 39.png
│ │ │ ├── 4.png
│ │ │ ├── 40.png
│ │ │ ├── 41.png
│ │ │ ├── 42.png
│ │ │ ├── 43.png
│ │ │ ├── 44.png
│ │ │ ├── 5.png
│ │ │ ├── 6.png
│ │ │ ├── 7.png
│ │ │ ├── 8.png
│ │ │ ├── 9.png
│ │ │ ├── Indexing.gif
│ │ │ ├── tool_images
│ │ │ │ ├── 1.png
│ │ │ │ ├── 2.png
│ │ │ │ └── 3.png
│ │ │ └── Usecase.gif
│ │ ├── index.md
│ │ ├── installation.md
│ │ ├── license.md
│ │ ├── server.md
│ │ ├── tools.md
│ │ ├── troubleshooting.md
│ │ └── use_cases.md
│ ├── mkdocs.yml
│ └── site
│ ├── 404.html
│ ├── architecture
│ │ └── index.html
│ ├── assets
│ │ ├── images
│ │ │ └── favicon.png
│ │ ├── javascripts
│ │ │ ├── bundle.f55a23d4.min.js
│ │ │ ├── bundle.f55a23d4.min.js.map
│ │ │ ├── lunr
│ │ │ │ ├── min
│ │ │ │ │ ├── lunr.ar.min.js
│ │ │ │ │ ├── lunr.da.min.js
│ │ │ │ │ ├── lunr.de.min.js
│ │ │ │ │ ├── lunr.du.min.js
│ │ │ │ │ ├── lunr.el.min.js
│ │ │ │ │ ├── lunr.es.min.js
│ │ │ │ │ ├── lunr.fi.min.js
│ │ │ │ │ ├── lunr.fr.min.js
│ │ │ │ │ ├── lunr.he.min.js
│ │ │ │ │ ├── lunr.hi.min.js
│ │ │ │ │ ├── lunr.hu.min.js
│ │ │ │ │ ├── lunr.hy.min.js
│ │ │ │ │ ├── lunr.it.min.js
│ │ │ │ │ ├── lunr.ja.min.js
│ │ │ │ │ ├── lunr.jp.min.js
│ │ │ │ │ ├── lunr.kn.min.js
│ │ │ │ │ ├── lunr.ko.min.js
│ │ │ │ │ ├── lunr.multi.min.js
│ │ │ │ │ ├── lunr.nl.min.js
│ │ │ │ │ ├── lunr.no.min.js
│ │ │ │ │ ├── lunr.pt.min.js
│ │ │ │ │ ├── lunr.ro.min.js
│ │ │ │ │ ├── lunr.ru.min.js
│ │ │ │ │ ├── lunr.sa.min.js
│ │ │ │ │ ├── lunr.stemmer.support.min.js
│ │ │ │ │ ├── lunr.sv.min.js
│ │ │ │ │ ├── lunr.ta.min.js
│ │ │ │ │ ├── lunr.te.min.js
│ │ │ │ │ ├── lunr.th.min.js
│ │ │ │ │ ├── lunr.tr.min.js
│ │ │ │ │ ├── lunr.vi.min.js
│ │ │ │ │ └── lunr.zh.min.js
│ │ │ │ ├── tinyseg.js
│ │ │ │ └── wordcut.js
│ │ │ └── workers
│ │ │ ├── search.973d3a69.min.js
│ │ │ └── search.973d3a69.min.js.map
│ │ └── stylesheets
│ │ ├── main.2a3383ac.min.css
│ │ ├── main.2a3383ac.min.css.map
│ │ ├── palette.06af60db.min.css
│ │ └── palette.06af60db.min.css.map
│ ├── cli
│ │ └── index.html
│ ├── contributing
│ │ └── index.html
│ ├── contributing_languages
│ │ └── index.html
│ ├── cookbook
│ │ └── index.html
│ ├── core
│ │ └── index.html
│ ├── future_work
│ │ └── index.html
│ ├── images
│ │ ├── 1.png
│ │ ├── 11.png
│ │ ├── 12.png
│ │ ├── 13.png
│ │ ├── 14.png
│ │ ├── 16.png
│ │ ├── 19.png
│ │ ├── 2.png
│ │ ├── 20.png
│ │ ├── 21.png
│ │ ├── 22.png
│ │ ├── 23.png
│ │ ├── 24.png
│ │ ├── 26.png
│ │ ├── 28.png
│ │ ├── 29.png
│ │ ├── 3.png
│ │ ├── 30.png
│ │ ├── 31.png
│ │ ├── 32.png
│ │ ├── 33.png
│ │ ├── 34.png
│ │ ├── 35.png
│ │ ├── 36.png
│ │ ├── 38.png
│ │ ├── 39.png
│ │ ├── 4.png
│ │ ├── 40.png
│ │ ├── 41.png
│ │ ├── 42.png
│ │ ├── 43.png
│ │ ├── 44.png
│ │ ├── 5.png
│ │ ├── 6.png
│ │ ├── 7.png
│ │ ├── 8.png
│ │ ├── 9.png
│ │ ├── Indexing.gif
│ │ ├── tool_images
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ └── 3.png
│ │ └── Usecase.gif
│ ├── index.html
│ ├── installation
│ │ └── index.html
│ ├── license
│ │ └── index.html
│ ├── search
│ │ └── search_index.json
│ ├── server
│ │ └── index.html
│ ├── sitemap.xml
│ ├── sitemap.xml.gz
│ ├── tools
│ │ └── index.html
│ ├── troubleshooting
│ │ └── index.html
│ └── use_cases
│ └── index.html
├── images
│ ├── 1.png
│ ├── 11.png
│ ├── 12.png
│ ├── 13.png
│ ├── 14.png
│ ├── 16.png
│ ├── 19.png
│ ├── 2.png
│ ├── 20.png
│ ├── 21.png
│ ├── 22.png
│ ├── 23.png
│ ├── 24.png
│ ├── 26.png
│ ├── 28.png
│ ├── 29.png
│ ├── 3.png
│ ├── 30.png
│ ├── 31.png
│ ├── 32.png
│ ├── 33.png
│ ├── 34.png
│ ├── 35.png
│ ├── 36.png
│ ├── 38.png
│ ├── 39.png
│ ├── 4.png
│ ├── 40.png
│ ├── 41.png
│ ├── 42.png
│ ├── 43.png
│ ├── 44.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ ├── 8.png
│ ├── 9.png
│ ├── Indexing.gif
│ ├── tool_images
│ │ ├── 1.png
│ │ ├── 2.png
│ │ └── 3.png
│ └── Usecase.gif
├── LICENSE
├── MANIFEST.in
├── organizer
│ ├── CONTRIBUTING_LANGUAGES.md
│ ├── cookbook.md
│ ├── docs.md
│ ├── language_specific_nodes.md
│ ├── Tools_Exploration.md
│ └── troubleshoot.md
├── package-lock.json
├── pyproject.toml
├── README.md
├── scripts
│ ├── generate_lang_contributors.py
│ └── post_install_fix.sh
├── SECURITY.md
├── src
│ └── codegraphcontext
│ ├── __init__.py
│ ├── __main__.py
│ ├── cli
│ │ ├── __init__.py
│ │ ├── cli_helpers.py
│ │ ├── main.py
│ │ ├── setup_macos.py
│ │ └── setup_wizard.py
│ ├── core
│ │ ├── __init__.py
│ │ ├── database.py
│ │ ├── jobs.py
│ │ └── watcher.py
│ ├── prompts.py
│ ├── server.py
│ ├── tools
│ │ ├── __init__.py
│ │ ├── advanced_language_query_tool.py
│ │ ├── code_finder.py
│ │ ├── graph_builder.py
│ │ ├── languages
│ │ │ ├── c.py
│ │ │ ├── cpp.py
│ │ │ ├── go.py
│ │ │ ├── java.py
│ │ │ ├── javascript.py
│ │ │ ├── python.py
│ │ │ ├── ruby.py
│ │ │ ├── rust.py
│ │ │ └── typescript.py
│ │ ├── package_resolver.py
│ │ ├── query_tool_languages
│ │ │ ├── c_toolkit.py
│ │ │ ├── cpp_toolkit.py
│ │ │ ├── go_toolkit.py
│ │ │ ├── java_toolkit.py
│ │ │ ├── javascript_toolkit.py
│ │ │ ├── python_toolkit.py
│ │ │ ├── ruby_toolkit.py
│ │ │ ├── rust_toolkit.py
│ │ │ └── typescript_toolkit.py
│ │ └── system.py
│ └── utils
│ └── debug_log.py
├── tests
│ ├── __init__.py
│ ├── conftest.py
│ ├── sample_project
│ │ ├── advanced_calls.py
│ │ ├── advanced_classes.py
│ │ ├── advanced_classes2.py
│ │ ├── advanced_functions.py
│ │ ├── advanced_imports.py
│ │ ├── async_features.py
│ │ ├── callbacks_decorators.py
│ │ ├── circular1.py
│ │ ├── circular2.py
│ │ ├── class_instantiation.py
│ │ ├── cli_and_dunder.py
│ │ ├── complex_classes.py
│ │ ├── comprehensions_generators.py
│ │ ├── context_managers.py
│ │ ├── control_flow.py
│ │ ├── datatypes.py
│ │ ├── dynamic_dispatch.py
│ │ ├── dynamic_imports.py
│ │ ├── edge_cases
│ │ │ ├── comments_only.py
│ │ │ ├── docstring_only.py
│ │ │ ├── empty.py
│ │ │ ├── hardcoded_secrets.py
│ │ │ ├── long_functions.py
│ │ │ └── syntax_error.py
│ │ ├── function_chains.py
│ │ ├── generators.py
│ │ ├── import_reexports.py
│ │ ├── mapping_calls.py
│ │ ├── module_a.py
│ │ ├── module_b.py
│ │ ├── module_c
│ │ │ ├── __init__.py
│ │ │ ├── submodule1.py
│ │ │ └── submodule2.py
│ │ ├── namespace_pkg
│ │ │ └── ns_module.py
│ │ ├── pattern_matching.py
│ │ └── typing_examples.py
│ ├── sample_project_c
│ │ ├── cgc_sample
│ │ ├── include
│ │ │ ├── config.h
│ │ │ ├── math
│ │ │ │ └── vec.h
│ │ │ ├── module.h
│ │ │ ├── platform.h
│ │ │ └── util.h
│ │ ├── Makefile
│ │ ├── README.md
│ │ └── src
│ │ ├── main.c
│ │ ├── math
│ │ │ └── vec.c
│ │ ├── module.c
│ │ └── util.c
│ ├── sample_project_cpp
│ │ ├── class_features.cpp
│ │ ├── classes.cpp
│ │ ├── control_flow.cpp
│ │ ├── edge_cases.cpp
│ │ ├── enum_struct_union.cpp
│ │ ├── exceptions.cpp
│ │ ├── file_io.cpp
│ │ ├── function_chain.cpp
│ │ ├── function_chain.h
│ │ ├── function_types.cpp
│ │ ├── main.cpp
│ │ ├── main.exe
│ │ ├── namespaces.cpp
│ │ ├── raii_example.cpp
│ │ ├── README.md
│ │ ├── sample_project.exe
│ │ ├── stl_usage.cpp
│ │ ├── templates.cpp
│ │ └── types_variable_assignments.cpp
│ ├── sample_project_go
│ │ ├── advanced_types.go
│ │ ├── basic_functions.go
│ │ ├── embedded_composition.go
│ │ ├── error_handling.go
│ │ ├── generics.go
│ │ ├── go.mod
│ │ ├── goroutines_channels.go
│ │ ├── interfaces.go
│ │ ├── packages_imports.go
│ │ ├── README.md
│ │ ├── structs_methods.go
│ │ └── util
│ │ └── helpers.go
│ ├── sample_project_java
│ │ ├── out
│ │ │ └── com
│ │ │ └── example
│ │ │ └── app
│ │ │ ├── annotations
│ │ │ │ └── Logged.class
│ │ │ ├── Main.class
│ │ │ ├── misc
│ │ │ │ ├── Outer.class
│ │ │ │ └── Outer$Inner.class
│ │ │ ├── model
│ │ │ │ ├── Role.class
│ │ │ │ └── User.class
│ │ │ ├── service
│ │ │ │ ├── AbstractGreeter.class
│ │ │ │ ├── GreetingService.class
│ │ │ │ └── impl
│ │ │ │ └── GreetingServiceImpl.class
│ │ │ └── util
│ │ │ ├── CollectionUtils.class
│ │ │ └── IOHelper.class
│ │ ├── README.md
│ │ ├── sources.txt
│ │ └── src
│ │ └── com
│ │ └── example
│ │ └── app
│ │ ├── annotations
│ │ │ └── Logged.java
│ │ ├── Main.java
│ │ ├── misc
│ │ │ └── Outer.java
│ │ ├── model
│ │ │ ├── Role.java
│ │ │ └── User.java
│ │ ├── service
│ │ │ ├── AbstractGreeter.java
│ │ │ ├── GreetingService.java
│ │ │ └── impl
│ │ │ └── GreetingServiceImpl.java
│ │ └── util
│ │ ├── CollectionUtils.java
│ │ └── IOHelper.java
│ ├── sample_project_javascript
│ │ ├── arrays.js
│ │ ├── asyncAwait.js
│ │ ├── classes.js
│ │ ├── dom.js
│ │ ├── errorHandling.js
│ │ ├── events.js
│ │ ├── exporter.js
│ │ ├── fetchAPI.js
│ │ ├── fixtures
│ │ │ └── js
│ │ │ └── accessors.js
│ │ ├── functions.js
│ │ ├── importer.js
│ │ ├── objects.js
│ │ ├── promises.js
│ │ ├── README.md
│ │ └── variables.js
│ ├── sample_project_misc
│ │ ├── index.html
│ │ ├── README.md
│ │ ├── styles.css
│ │ ├── tables.css
│ │ └── tables.html
│ ├── sample_project_php
│ │ ├── classes_objects.php
│ │ ├── database.php
│ │ ├── edgecases.php
│ │ ├── error_handling.php
│ │ ├── file_handling.php
│ │ ├── functions.php
│ │ ├── generators_iterators.php
│ │ ├── globals_superglobals.php
│ │ ├── Inheritance.php
│ │ ├── interface_traits.php
│ │ └── README.md
│ ├── sample_project_ruby
│ │ ├── class_example.rb
│ │ ├── enumerables.rb
│ │ ├── error_handling.rb
│ │ ├── file_io.rb
│ │ ├── inheritance_example.rb
│ │ ├── main.rb
│ │ ├── metaprogramming.rb
│ │ ├── mixins_example.rb
│ │ ├── module_example.rb
│ │ └── tests
│ │ ├── test_mixins.py
│ │ └── test_sample.rb
│ ├── sample_project_rust
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ └── src
│ │ ├── basic_functions.rs
│ │ ├── concurrency.rs
│ │ ├── error_handling.rs
│ │ ├── generics.rs
│ │ ├── iterators_closures.rs
│ │ ├── lib.rs
│ │ ├── lifetimes_references.rs
│ │ ├── modules.rs
│ │ ├── smart_pointers.rs
│ │ ├── structs_enums.rs
│ │ └── traits.rs
│ ├── sample_project_typescript
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── src
│ │ │ ├── advanced-types.ts
│ │ │ ├── async-promises.ts
│ │ │ ├── classes-inheritance.ts
│ │ │ ├── decorators-metadata.ts
│ │ │ ├── error-validation.ts
│ │ │ ├── functions-generics.ts
│ │ │ ├── index.ts
│ │ │ ├── modules-namespaces.ts
│ │ │ ├── types-interfaces.ts
│ │ │ └── utilities-helpers.ts
│ │ └── tsconfig.json
│ ├── test_cpp_parser.py
│ ├── test_database_validation.py
│ ├── test_end_to_end.py
│ ├── test_graph_indexing_js.py
│ ├── test_graph_indexing.py
│ ├── test_tree_sitter
│ │ ├── __init__.py
│ │ ├── class_instantiation.py
│ │ ├── complex_classes.py
│ │ └── test_file.py
│ └── test_typescript_parser.py
└── website
├── .example.env
├── .gitignore
├── api
│ └── pypi.ts
├── bun.lockb
├── components.json
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│ ├── favicon.ico
│ ├── placeholder.svg
│ └── robots.txt
├── README.md
├── src
│ ├── App.css
│ ├── App.tsx
│ ├── assets
│ │ ├── function-calls.png
│ │ ├── graph-total.png
│ │ ├── hero-graph.jpg
│ │ └── hierarchy.png
│ ├── components
│ │ ├── ComparisonTable.tsx
│ │ ├── CookbookSection.tsx
│ │ ├── DemoSection.tsx
│ │ ├── ExamplesSection.tsx
│ │ ├── FeaturesSection.tsx
│ │ ├── Footer.tsx
│ │ ├── HeroSection.tsx
│ │ ├── InstallationSection.tsx
│ │ ├── MoveToTop.tsx
│ │ ├── ShowDownloads.tsx
│ │ ├── ShowStarGraph.tsx
│ │ ├── TestimonialSection.tsx
│ │ ├── ThemeProvider.tsx
│ │ ├── ThemeToggle.tsx
│ │ └── ui
│ │ ├── accordion.tsx
│ │ ├── alert-dialog.tsx
│ │ ├── alert.tsx
│ │ ├── aspect-ratio.tsx
│ │ ├── avatar.tsx
│ │ ├── badge.tsx
│ │ ├── breadcrumb.tsx
│ │ ├── button.tsx
│ │ ├── calendar.tsx
│ │ ├── card.tsx
│ │ ├── carousel.tsx
│ │ ├── chart.tsx
│ │ ├── checkbox.tsx
│ │ ├── collapsible.tsx
│ │ ├── command.tsx
│ │ ├── context-menu.tsx
│ │ ├── dialog.tsx
│ │ ├── drawer.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── form.tsx
│ │ ├── hover-card.tsx
│ │ ├── input-otp.tsx
│ │ ├── input.tsx
│ │ ├── label.tsx
│ │ ├── menubar.tsx
│ │ ├── navigation-menu.tsx
│ │ ├── orbiting-circles.tsx
│ │ ├── pagination.tsx
│ │ ├── popover.tsx
│ │ ├── progress.tsx
│ │ ├── radio-group.tsx
│ │ ├── resizable.tsx
│ │ ├── scroll-area.tsx
│ │ ├── select.tsx
│ │ ├── separator.tsx
│ │ ├── sheet.tsx
│ │ ├── sidebar.tsx
│ │ ├── skeleton.tsx
│ │ ├── slider.tsx
│ │ ├── sonner.tsx
│ │ ├── switch.tsx
│ │ ├── table.tsx
│ │ ├── tabs.tsx
│ │ ├── textarea.tsx
│ │ ├── toast.tsx
│ │ ├── toaster.tsx
│ │ ├── toggle-group.tsx
│ │ ├── toggle.tsx
│ │ ├── tooltip.tsx
│ │ └── use-toast.ts
│ ├── hooks
│ │ ├── use-mobile.tsx
│ │ └── use-toast.ts
│ ├── index.css
│ ├── lib
│ │ └── utils.ts
│ ├── main.tsx
│ ├── pages
│ │ ├── Index.tsx
│ │ └── NotFound.tsx
│ └── vite-env.d.ts
├── tailwind.config.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
├── vercel.json
└── vite.config.ts
```
# Files
--------------------------------------------------------------------------------
/tests/sample_project_typescript/src/functions-generics.ts:
--------------------------------------------------------------------------------
```typescript
/**
* Functions and Generics
* Demonstrates TypeScript's function types, overloads, generics, constraints,
* higher-order functions, and advanced function patterns
*/
// ========== Basic Function Types ==========
export function simpleFunction(x: number, y: number): number {
return x + y;
}
// Optional parameters
export function greet(name: string, greeting?: string): string {
return `${greeting || "Hello"}, ${name}!`;
}
// Default parameters
export function createUser(name: string, active: boolean = true): { name: string; active: boolean } {
return { name, active };
}
// Rest parameters
export function sum(...numbers: number[]): number {
return numbers.reduce((total, num) => total + num, 0);
}
// ========== Function Overloads ==========
export function parseValue(value: string): number;
export function parseValue(value: number): string;
export function parseValue(value: boolean): string;
export function parseValue(value: string | number | boolean): string | number {
if (typeof value === "string") {
return parseInt(value, 10);
} else if (typeof value === "number") {
return value.toString();
} else {
return value.toString();
}
}
// Complex overloads
export function processData(data: string[]): string[];
export function processData(data: number[]): number[];
export function processData<T>(data: T[], processor: (item: T) => T): T[];
export function processData<T>(
data: T[],
processor?: (item: T) => T
): T[] {
if (processor) {
return data.map(processor);
}
return [...data];
}
// ========== Arrow Functions ==========
export const multiply = (x: number, y: number): number => x * y;
export const isEven = (n: number): boolean => n % 2 === 0;
// Higher-order arrow function
export const createMultiplier = (factor: number) => (value: number) => value * factor;
// ========== Generic Functions ==========
export function identity<T>(arg: T): T {
return arg;
}
export function getFirstElement<T>(array: T[]): T | undefined {
return array[0];
}
// Generic with multiple type parameters
export function merge<T, U>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}
// Generic with default type parameter
export function createArray<T = string>(length: number, defaultValue: T): T[] {
return Array(length).fill(defaultValue);
}
// ========== Generic Constraints ==========
// Constraint using extends
export function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// Constraint with interface
interface Lengthwise {
length: number;
}
export function logLength<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
// Constraint with conditional types
export function processItem<T extends string | number>(
item: T
): T extends string ? string : number {
if (typeof item === "string") {
return item.toUpperCase() as T extends string ? string : number;
}
return (item * 2) as T extends string ? string : number;
}
// ========== Advanced Generic Patterns ==========
// Generic factory function
export interface Constructable<T = {}> {
new (...args: any[]): T;
}
export function createInstance<T>(constructor: Constructable<T>, ...args: any[]): T {
return new constructor(...args);
}
// Generic with constraint and default
export function sortBy<T, K extends keyof T = keyof T>(
array: T[],
key: K,
ascending: boolean = true
): T[] {
return array.sort((a, b) => {
const valueA = a[key];
const valueB = b[key];
if (valueA < valueB) return ascending ? -1 : 1;
if (valueA > valueB) return ascending ? 1 : -1;
return 0;
});
}
// ========== Function Types ==========
export type UnaryFunction<T, R> = (arg: T) => R;
export type BinaryFunction<T, U, R> = (arg1: T, arg2: U) => R;
export type Predicate<T> = (arg: T) => boolean;
export type Mapper<T, R> = (item: T, index: number, array: T[]) => R;
// Function that accepts function types
export function pipe<T, R1, R2>(
input: T,
fn1: UnaryFunction<T, R1>,
fn2: UnaryFunction<R1, R2>
): R2 {
return fn2(fn1(input));
}
// ========== Higher-Order Functions ==========
export function memoize<T extends (...args: any[]) => any>(fn: T): T {
const cache = new Map();
return ((...args: any[]) => {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn(...args);
cache.set(key, result);
return result;
}) as T;
}
export function debounce<T extends (...args: any[]) => any>(
fn: T,
delay: number
): T {
let timeoutId: NodeJS.Timeout;
return ((...args: any[]) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn(...args), delay);
}) as T;
}
export function throttle<T extends (...args: any[]) => any>(
fn: T,
limit: number
): T {
let inThrottle: boolean;
return ((...args: any[]) => {
if (!inThrottle) {
fn(...args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
}) as T;
}
// ========== Generic Data Structures ==========
export class Stack<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
peek(): T | undefined {
return this.items[this.items.length - 1];
}
isEmpty(): boolean {
return this.items.length === 0;
}
size(): number {
return this.items.length;
}
}
export class Queue<T> {
private items: T[] = [];
enqueue(item: T): void {
this.items.push(item);
}
dequeue(): T | undefined {
return this.items.shift();
}
front(): T | undefined {
return this.items[0];
}
isEmpty(): boolean {
return this.items.length === 0;
}
size(): number {
return this.items.length;
}
}
// Generic with multiple constraints
export interface Comparable<T> {
compareTo(other: T): number;
}
export class PriorityQueue<T extends Comparable<T>> {
private items: T[] = [];
enqueue(item: T): void {
this.items.push(item);
this.items.sort((a, b) => a.compareTo(b));
}
dequeue(): T | undefined {
return this.items.shift();
}
peek(): T | undefined {
return this.items[0];
}
isEmpty(): boolean {
return this.items.length === 0;
}
}
// ========== Utility Functions with Generics ==========
export function arrayChunk<T>(array: T[], size: number): T[][] {
const chunks: T[][] = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
}
export function arrayUnique<T>(array: T[]): T[] {
return [...new Set(array)];
}
export function arrayGroupBy<T, K extends string | number | symbol>(
array: T[],
keyFn: (item: T) => K
): Record<K, T[]> {
return array.reduce((groups, item) => {
const key = keyFn(item);
groups[key] = groups[key] || [];
groups[key]!.push(item);
return groups;
}, {} as Record<K, T[]>);
}
// Curried functions
export const curriedAdd = (x: number) => (y: number) => x + y;
export const curriedFilter = <T>(predicate: Predicate<T>) => (array: T[]) =>
array.filter(predicate);
// ========== Generic Utility Types Functions ==========
export function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
const result = {} as Pick<T, K>;
keys.forEach(key => {
result[key] = obj[key];
});
return result;
}
export function omit<T, K extends keyof T>(obj: T, ...keys: K[]): Omit<T, K> {
const result = { ...obj };
keys.forEach(key => {
delete result[key];
});
return result as Omit<T, K>;
}
export function deepClone<T>(obj: T): T {
if (obj === null || typeof obj !== "object") {
return obj;
}
if (obj instanceof Date) {
return new Date(obj.getTime()) as T;
}
if (obj instanceof Array) {
return obj.map(item => deepClone(item)) as T;
}
if (typeof obj === "object") {
const copy = {} as T;
Object.keys(obj).forEach(key => {
(copy as any)[key] = deepClone((obj as any)[key]);
});
return copy;
}
return obj;
}
// ========== Function Composition ==========
export function compose<T, R1, R2>(
fn1: (arg: T) => R1,
fn2: (arg: R1) => R2
): (arg: T) => R2;
export function compose<T, R1, R2, R3>(
fn1: (arg: T) => R1,
fn2: (arg: R1) => R2,
fn3: (arg: R2) => R3
): (arg: T) => R3;
export function compose(...fns: Function[]) {
return (arg: any) => fns.reduce((result, fn) => fn(result), arg);
}
// ========== Usage Examples ==========
export const functionExamples = {
// Basic functions
basicSum: sum(1, 2, 3, 4, 5),
parsedString: parseValue("123"),
parsedNumber: parseValue(456),
// Generics
identityString: identity("hello"),
identityNumber: identity(42),
mergedObject: merge({ name: "John" }, { age: 30 }),
// Data structures
numberStack: new Stack<number>(),
stringQueue: new Queue<string>(),
// Higher-order functions
double: createMultiplier(2),
memoizedFib: memoize((n: number): number => {
if (n <= 1) return n;
return functionExamples.memoizedFib(n - 1) + functionExamples.memoizedFib(n - 2);
}),
// Array utilities
chunkedArray: arrayChunk([1, 2, 3, 4, 5, 6, 7], 3),
uniqueArray: arrayUnique([1, 2, 2, 3, 3, 3, 4]),
groupedItems: arrayGroupBy(
[{ type: "fruit", name: "apple" }, { type: "fruit", name: "banana" }, { type: "vegetable", name: "carrot" }],
item => item.type
)
};
// Initialize some examples
functionExamples.numberStack.push(1);
functionExamples.numberStack.push(2);
functionExamples.numberStack.push(3);
functionExamples.stringQueue.enqueue("first");
functionExamples.stringQueue.enqueue("second");
functionExamples.stringQueue.enqueue("third");
```
--------------------------------------------------------------------------------
/src/codegraphcontext/core/watcher.py:
--------------------------------------------------------------------------------
```python
# src/codegraphcontext/core/watcher.py
"""
This module implements the live file-watching functionality using the `watchdog` library.
It observes directories for changes and triggers updates to the code graph.
"""
import threading
from pathlib import Path
import typing
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
if typing.TYPE_CHECKING:
from codegraphcontext.tools.graph_builder import GraphBuilder
from codegraphcontext.core.jobs import JobManager
from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger
class RepositoryEventHandler(FileSystemEventHandler):
"""
A dedicated event handler for a single repository being watched.
This handler is stateful. It performs an initial scan of the repository
to build a baseline and then uses this cached state to perform efficient
updates when files are changed, created, or deleted.
"""
def __init__(self, graph_builder: "GraphBuilder", repo_path: Path, debounce_interval=2.0, perform_initial_scan: bool = True):
"""
Initializes the event handler.
Args:
graph_builder: An instance of the GraphBuilder to perform graph operations.
repo_path: The absolute path to the repository directory to watch.
debounce_interval: The time in seconds to wait for more changes before processing an event.
perform_initial_scan: Whether to perform an initial scan of the repository.
"""
super().__init__()
self.graph_builder = graph_builder
self.repo_path = repo_path
self.debounce_interval = debounce_interval
self.timers = {} # A dictionary to manage debounce timers for file paths.
# Caches for the repository's state.
self.all_file_data = []
self.imports_map = {}
# Perform the initial scan and linking when the watcher is created.
if perform_initial_scan:
self._initial_scan()
def _initial_scan(self):
"""Scans the entire repository, parses all files, and builds the initial graph."""
info_logger(f"Performing initial scan for watcher: {self.repo_path}")
supported_extensions = self.graph_builder.parsers.keys()
all_files = [f for f in self.repo_path.rglob("*") if f.is_file() and f.suffix in supported_extensions]
# 1. Pre-scan all files to get a global map of where every symbol is defined.
self.imports_map = self.graph_builder._pre_scan_for_imports(all_files)
# 2. Parse all files in detail and cache the parsed data.
for f in all_files:
parsed_data = self.graph_builder.parse_file(self.repo_path, f)
if "error" not in parsed_data:
self.all_file_data.append(parsed_data)
# 3. After all files are parsed, create the relationships (e.g., function calls) between them.
self.graph_builder._create_all_function_calls(self.all_file_data, self.imports_map)
self.graph_builder._create_all_inheritance_links(self.all_file_data, self.imports_map)
info_logger(f"Initial scan and graph linking complete for: {self.repo_path}")
def _debounce(self, event_path, action):
"""
Schedules an action to run after a debounce interval.
This prevents the handler from firing on every single file save event in rapid
succession, which is common in IDEs. It waits for a quiet period before processing.
"""
# If a timer already exists for this path, cancel it.
if event_path in self.timers:
self.timers[event_path].cancel()
# Create and start a new timer.
timer = threading.Timer(self.debounce_interval, action)
timer.start()
self.timers[event_path] = timer
def _handle_modification(self, event_path_str: str):
"""
Orchestrates the complete update cycle for a modified or created file.
This involves re-scanning the entire repo to update cross-file relationships.
"""
info_logger(f"File change detected, starting full repository refresh for: {event_path_str}")
modified_path = Path(event_path_str)
# 1. Get all supported files in the repository.
supported_extensions = self.graph_builder.parsers.keys()
all_files = [f for f in self.repo_path.rglob("*") if f.is_file() and f.suffix in supported_extensions]
# 2. Re-scan all files to get a fresh, global map of all symbols.
self.imports_map = self.graph_builder._pre_scan_for_imports(all_files)
info_logger("Refreshed global imports map.")
# 3. Update the specific file that changed in the graph.
# This deletes old nodes and adds new ones for the single file.
self.graph_builder.update_file_in_graph(
modified_path, self.repo_path, self.imports_map
)
# 4. Re-parse all files to have a complete, in-memory representation for the linking pass.
# This is necessary because a change in one file can affect relationships in others.
self.all_file_data = []
for f in all_files:
parsed_data = self.graph_builder.parse_file(self.repo_path, f)
if "error" not in parsed_data:
self.all_file_data.append(parsed_data)
info_logger("Refreshed in-memory cache of all file data.")
# 5. CRITICAL: Re-link the entire graph using the fully updated cache and imports map.
info_logger("Re-linking the entire graph for calls and inheritance...")
self.graph_builder._create_all_function_calls(self.all_file_data, self.imports_map)
self.graph_builder._create_all_inheritance_links(self.all_file_data, self.imports_map)
info_logger(f"Graph refresh for change in {event_path_str} complete! ✅")
# The following methods are called by the watchdog observer when a file event occurs.
def on_created(self, event):
if not event.is_directory and Path(event.src_path).suffix in self.graph_builder.parsers:
self._debounce(event.src_path, lambda: self._handle_modification(event.src_path))
def on_modified(self, event):
if not event.is_directory and Path(event.src_path).suffix in self.graph_builder.parsers:
self._debounce(event.src_path, lambda: self._handle_modification(event.src_path))
def on_deleted(self, event):
if not event.is_directory and Path(event.src_path).suffix in self.graph_builder.parsers:
self._debounce(event.src_path, lambda: self._handle_modification(event.src_path))
def on_moved(self, event):
if not event.is_directory:
if Path(event.src_path).suffix in self.graph_builder.parsers:
self._debounce(event.src_path, lambda: self._handle_modification(event.src_path))
if Path(event.dest_path).suffix in self.graph_builder.parsers:
self._debounce(event.dest_path, lambda: self._handle_modification(event.dest_path))
class CodeWatcher:
"""
Manages the file system observer thread. It can watch multiple directories,
assigning a separate `RepositoryEventHandler` to each one.
"""
def __init__(self, graph_builder: "GraphBuilder", job_manager= "JobManager"):
self.graph_builder = graph_builder
self.observer = Observer()
self.watched_paths = set() # Keep track of paths already being watched.
self.watches = {} # Store watch objects to allow unscheduling
def watch_directory(self, path: str, perform_initial_scan: bool = True):
"""Schedules a directory to be watched for changes."""
path_obj = Path(path).resolve()
path_str = str(path_obj)
if path_str in self.watched_paths:
info_logger(f"Path already being watched: {path_str}")
return {"message": f"Path already being watched: {path_str}"}
# Create a new, dedicated event handler for this specific repository path.
event_handler = RepositoryEventHandler(self.graph_builder, path_obj, perform_initial_scan=perform_initial_scan)
watch = self.observer.schedule(event_handler, path_str, recursive=True)
self.watches[path_str] = watch
self.watched_paths.add(path_str)
info_logger(f"Started watching for code changes in: {path_str}")
return {"message": f"Started watching {path_str}."}
def unwatch_directory(self, path: str):
"""Stops watching a directory for changes."""
path_obj = Path(path).resolve()
path_str = str(path_obj)
if path_str not in self.watched_paths:
warning_logger(f"Attempted to unwatch a path that is not being watched: {path_str}")
return {"error": f"Path not currently being watched: {path_str}"}
watch = self.watches.pop(path_str, None)
if watch:
self.observer.unschedule(watch)
self.watched_paths.discard(path_str)
info_logger(f"Stopped watching for code changes in: {path_str}")
return {"message": f"Stopped watching {path_str}."}
def list_watched_paths(self) -> list:
"""Returns a list of all currently watched directory paths."""
return list(self.watched_paths)
def start(self):
"""Starts the observer thread."""
if not self.observer.is_alive():
self.observer.start()
info_logger("Code watcher observer thread started.")
def stop(self):
"""Stops the observer thread gracefully."""
if self.observer.is_alive():
self.observer.stop()
self.observer.join() # Wait for the thread to terminate.
info_logger("Code watcher observer thread stopped.")
```
--------------------------------------------------------------------------------
/src/codegraphcontext/core/database.py:
--------------------------------------------------------------------------------
```python
# src/codegraphcontext/core/database.py
"""
This module provides a thread-safe singleton manager for the Neo4j database connection.
"""
import os
import re
import threading
from typing import Optional, Tuple
from neo4j import GraphDatabase, Driver
from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger
class DatabaseManager:
"""
Manages the Neo4j database driver as a singleton to ensure only one
connection pool is created and shared across the application.
This pattern is crucial for performance and resource management in a
multi-threaded or asynchronous application.
"""
_instance = None
_driver: Optional[Driver] = None
_lock = threading.Lock() # Lock to ensure thread-safe initialization.
def __new__(cls):
"""Standard singleton pattern implementation."""
if cls._instance is None:
with cls._lock:
# Double-check locking to prevent race conditions.
if cls._instance is None:
cls._instance = super(DatabaseManager, cls).__new__(cls)
return cls._instance
def __init__(self):
"""
Initializes the manager by reading credentials from environment variables.
The `_initialized` flag prevents re-initialization on subsequent calls.
"""
if hasattr(self, '_initialized'):
return
self.neo4j_uri = os.getenv('NEO4J_URI')
self.neo4j_username = os.getenv('NEO4J_USERNAME', 'neo4j')
self.neo4j_password = os.getenv('NEO4J_PASSWORD')
self._initialized = True
def get_driver(self) -> Driver:
"""
Gets the Neo4j driver instance, creating it if it doesn't exist.
This method is thread-safe.
Raises:
ValueError: If Neo4j credentials are not set in environment variables.
Returns:
The active Neo4j Driver instance.
"""
if self._driver is None:
with self._lock:
if self._driver is None:
# Ensure all necessary credentials are provided.
if not all([self.neo4j_uri, self.neo4j_username, self.neo4j_password]):
raise ValueError(
"Neo4j credentials must be set via environment variables:\n"
"- NEO4J_URI\n"
"- NEO4J_USERNAME\n"
"- NEO4J_PASSWORD"
)
#validating the config before creating the driver/attempting connection
is_valid, validation_error = self.validate_config(
self.neo4j_uri,
self.neo4j_username,
self.neo4j_password
)
if not is_valid:
error_logger(f"Configuration validation failed: {validation_error}")
raise ValueError(validation_error)
info_logger(f"Creating Neo4j driver connection to {self.neo4j_uri}")
self._driver = GraphDatabase.driver(
self.neo4j_uri,
auth=(self.neo4j_username, self.neo4j_password)
)
# Test the connection immediately to fail fast if credentials are wrong.
try:
with self._driver.session() as session:
session.run("RETURN 1").consume()
info_logger("Neo4j connection established successfully")
except Exception as e:
# Use detailed error messages from test_connection
_, detailed_error = self.test_connection(
self.neo4j_uri,
self.neo4j_username,
self.neo4j_password
)
error_logger(f"Failed to connect to Neo4j: {e}")
if self._driver:
self._driver.close()
self._driver = None
raise
return self._driver
def close_driver(self):
"""Closes the Neo4j driver connection if it exists."""
if self._driver is not None:
with self._lock:
if self._driver is not None:
info_logger("Closing Neo4j driver")
self._driver.close()
self._driver = None
def is_connected(self) -> bool:
"""Checks if the database connection is currently active."""
if self._driver is None:
return False
try:
with self._driver.session() as session:
session.run("RETURN 1").consume()
return True
except Exception:
return False
@staticmethod
def validate_config(uri: str, username: str, password: str) -> Tuple[bool, Optional[str]]:
"""
Validates Neo4j configuration parameters.
Returns:
Tuple[bool, Optional[str]]: (is_valid, error_message)
"""
# Validate URI format
uri_pattern = r'^(neo4j|neo4j\+s|neo4j\+ssc|bolt|bolt\+s|bolt\+ssc)://[^:]+:\d+$'
if not re.match(uri_pattern, uri):
return False, (
"Invalid Neo4j URI format.\n"
"Expected format: neo4j://host:port or bolt://host:port\n"
"Example: neo4j://localhost:7687\n"
"Common mistake: Missing 'neo4j://' or 'bolt://' prefix"
)
# Validate username
if not username or len(username.strip()) == 0:
return False, (
"Username cannot be empty.\n"
"Default Neo4j username is 'neo4j'"
)
# Validate password
if not password or len(password.strip()) == 0:
return False, (
"Password cannot be empty.\n"
"Tip: If you just set up Neo4j, use the password you configured during setup"
)
return True, None
@staticmethod
def test_connection(uri: str, username: str, password: str) -> Tuple[bool, Optional[str]]:
"""
Tests the Neo4j database connection.
Returns:
Tuple[bool, Optional[str]]: (is_connected, error_message)
"""
try:
from neo4j import GraphDatabase
import socket
# First, test if the host is reachable
try:
# Extract host and port from URI
host_port = uri.split('://')[1]
host = host_port.split(':')[0]
port = int(host_port.split(':')[1])
# Test socket connection
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
result = sock.connect_ex((host, port))
sock.close()
if result != 0:
return False, (
f"Cannot reach Neo4j server at {host}:{port}\n"
"Troubleshooting:\n"
" • Is Neo4j running? Check with: docker ps (for Docker)\n"
" • Is the port correct? Default is 7687\n"
" • Is there a firewall blocking the connection?\n"
f" • Try: docker compose up -d (if using Docker)"
)
except Exception as e:
return False, f"Error parsing URI or checking connectivity: {str(e)}"
# Now test Neo4j authentication
driver = GraphDatabase.driver(uri, auth=(username, password))
with driver.session() as session:
result = session.run("RETURN 'Connection successful' as status")
result.single()
driver.close()
return True, None
except Exception as e:
error_msg = str(e).lower()
# Provide specific error messages for common issues
if "authentication" in error_msg or "unauthorized" in error_msg:
return False, (
"Authentication failed - Invalid username or password\n"
"Troubleshooting:\n"
" • Default username is 'neo4j'\n"
" • Did you change the password during initial setup?\n"
" • If you forgot the password, you may need to reset Neo4j:\n"
" - Stop: docker compose down\n"
" - Remove data: docker volume rm <volume_name>\n"
" - Restart: docker compose up -d"
)
elif "serviceunAvailable" in error_msg or "failed to establish connection" in error_msg:
return False, (
"Neo4j service is not available\n"
"Troubleshooting:\n"
" • Is Neo4j running? Check: docker ps\n"
" • Start Neo4j: docker compose up -d\n"
" • Check logs: docker compose logs neo4j\n"
" • Wait 30-60 seconds after starting for Neo4j to initialize"
)
elif "unable to retrieve routing information" in error_msg:
return False, (
"Cannot connect to Neo4j routing\n"
"Troubleshooting:\n"
" • Try using 'bolt://' instead of 'neo4j://' in the URI\n"
" • Example: bolt://localhost:7687"
)
else:
return False, f"Connection failed: {str(e)}"
```
--------------------------------------------------------------------------------
/website/src/components/ui/chart.tsx:
--------------------------------------------------------------------------------
```typescript
import * as React from "react";
import * as RechartsPrimitive from "recharts";
import { cn } from "@/lib/utils";
// Format: { THEME_NAME: CSS_SELECTOR }
const THEMES = { light: "", dark: ".dark" } as const;
export type ChartConfig = {
[k in string]: {
label?: React.ReactNode;
icon?: React.ComponentType;
} & ({ color?: string; theme?: never } | { color?: never; theme: Record<keyof typeof THEMES, string> });
};
type ChartContextProps = {
config: ChartConfig;
};
const ChartContext = React.createContext<ChartContextProps | null>(null);
function useChart() {
const context = React.useContext(ChartContext);
if (!context) {
throw new Error("useChart must be used within a <ChartContainer />");
}
return context;
}
const ChartContainer = React.forwardRef<
HTMLDivElement,
React.ComponentProps<"div"> & {
config: ChartConfig;
children: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>["children"];
}
>(({ id, className, children, config, ...props }, ref) => {
const uniqueId = React.useId();
const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
return (
<ChartContext.Provider value={{ config }}>
<div
data-chart={chartId}
ref={ref}
className={cn(
"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",
className,
)}
{...props}
>
<ChartStyle id={chartId} config={config} />
<RechartsPrimitive.ResponsiveContainer>{children}</RechartsPrimitive.ResponsiveContainer>
</div>
</ChartContext.Provider>
);
});
ChartContainer.displayName = "Chart";
const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
const colorConfig = Object.entries(config).filter(([_, config]) => config.theme || config.color);
if (!colorConfig.length) {
return null;
}
return (
<style
dangerouslySetInnerHTML={{
__html: Object.entries(THEMES)
.map(
([theme, prefix]) => `
${prefix} [data-chart=${id}] {
${colorConfig
.map(([key, itemConfig]) => {
const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] || itemConfig.color;
return color ? ` --color-${key}: ${color};` : null;
})
.join("\n")}
}
`,
)
.join("\n"),
}}
/>
);
};
const ChartTooltip = RechartsPrimitive.Tooltip;
const ChartTooltipContent = React.forwardRef<
HTMLDivElement,
React.ComponentProps<typeof RechartsPrimitive.Tooltip> &
React.ComponentProps<"div"> & {
hideLabel?: boolean;
hideIndicator?: boolean;
indicator?: "line" | "dot" | "dashed";
nameKey?: string;
labelKey?: string;
}
>(
(
{
active,
payload,
className,
indicator = "dot",
hideLabel = false,
hideIndicator = false,
label,
labelFormatter,
labelClassName,
formatter,
color,
nameKey,
labelKey,
},
ref,
) => {
const { config } = useChart();
const tooltipLabel = React.useMemo(() => {
if (hideLabel || !payload?.length) {
return null;
}
const [item] = payload;
const key = `${labelKey || item.dataKey || item.name || "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
const value =
!labelKey && typeof label === "string"
? config[label as keyof typeof config]?.label || label
: itemConfig?.label;
if (labelFormatter) {
return <div className={cn("font-medium", labelClassName)}>{labelFormatter(value, payload)}</div>;
}
if (!value) {
return null;
}
return <div className={cn("font-medium", labelClassName)}>{value}</div>;
}, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);
if (!active || !payload?.length) {
return null;
}
const nestLabel = payload.length === 1 && indicator !== "dot";
return (
<div
ref={ref}
className={cn(
"grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
className,
)}
>
{!nestLabel ? tooltipLabel : null}
<div className="grid gap-1.5">
{payload.map((item, index) => {
const key = `${nameKey || item.name || item.dataKey || "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
const indicatorColor = color || item.payload.fill || item.color;
return (
<div
key={item.dataKey}
className={cn(
"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
indicator === "dot" && "items-center",
)}
>
{formatter && item?.value !== undefined && item.name ? (
formatter(item.value, item.name, item, index, item.payload)
) : (
<>
{itemConfig?.icon ? (
<itemConfig.icon />
) : (
!hideIndicator && (
<div
className={cn("shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]", {
"h-2.5 w-2.5": indicator === "dot",
"w-1": indicator === "line",
"w-0 border-[1.5px] border-dashed bg-transparent": indicator === "dashed",
"my-0.5": nestLabel && indicator === "dashed",
})}
style={
{
"--color-bg": indicatorColor,
"--color-border": indicatorColor,
} as React.CSSProperties
}
/>
)
)}
<div
className={cn(
"flex flex-1 justify-between leading-none",
nestLabel ? "items-end" : "items-center",
)}
>
<div className="grid gap-1.5">
{nestLabel ? tooltipLabel : null}
<span className="text-muted-foreground">{itemConfig?.label || item.name}</span>
</div>
{item.value && (
<span className="font-mono font-medium tabular-nums text-foreground">
{item.value.toLocaleString()}
</span>
)}
</div>
</>
)}
</div>
);
})}
</div>
</div>
);
},
);
ChartTooltipContent.displayName = "ChartTooltip";
const ChartLegend = RechartsPrimitive.Legend;
const ChartLegendContent = React.forwardRef<
HTMLDivElement,
React.ComponentProps<"div"> &
Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {
hideIcon?: boolean;
nameKey?: string;
}
>(({ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey }, ref) => {
const { config } = useChart();
if (!payload?.length) {
return null;
}
return (
<div
ref={ref}
className={cn("flex items-center justify-center gap-4", verticalAlign === "top" ? "pb-3" : "pt-3", className)}
>
{payload.map((item) => {
const key = `${nameKey || item.dataKey || "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
return (
<div
key={item.value}
className={cn("flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground")}
>
{itemConfig?.icon && !hideIcon ? (
<itemConfig.icon />
) : (
<div
className="h-2 w-2 shrink-0 rounded-[2px]"
style={{
backgroundColor: item.color,
}}
/>
)}
{itemConfig?.label}
</div>
);
})}
</div>
);
});
ChartLegendContent.displayName = "ChartLegend";
// Helper to extract item config from a payload.
function getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key: string) {
if (typeof payload !== "object" || payload === null) {
return undefined;
}
const payloadPayload =
"payload" in payload && typeof payload.payload === "object" && payload.payload !== null
? payload.payload
: undefined;
let configLabelKey: string = key;
if (key in payload && typeof payload[key as keyof typeof payload] === "string") {
configLabelKey = payload[key as keyof typeof payload] as string;
} else if (
payloadPayload &&
key in payloadPayload &&
typeof payloadPayload[key as keyof typeof payloadPayload] === "string"
) {
configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string;
}
return configLabelKey in config ? config[configLabelKey] : config[key as keyof typeof config];
}
export { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent, ChartStyle };
```
--------------------------------------------------------------------------------
/docs/site/assets/javascripts/lunr/min/lunr.pt.min.js:
--------------------------------------------------------------------------------
```javascript
/*!
* Lunr languages, `Portuguese` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(k,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("a~");continue;case 2:z.slice_from("o~");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function n(){if(z.out_grouping(y,97,250)){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!0;z.cursor++}return!1}return!0}function i(){if(z.in_grouping(y,97,250))for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return g=z.cursor,!0}function o(){var e,r,s=z.cursor;if(z.in_grouping(y,97,250))if(e=z.cursor,n()){if(z.cursor=e,i())return}else g=z.cursor;if(z.cursor=s,z.out_grouping(y,97,250)){if(r=z.cursor,n()){if(z.cursor=r,!z.in_grouping(y,97,250)||z.cursor>=z.limit)return;z.cursor++}g=z.cursor}}function t(){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return!0}function a(){var e=z.cursor;g=z.limit,b=g,h=g,o(),z.cursor=e,t()&&(b=z.cursor,t()&&(h=z.cursor))}function u(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(q,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("ã");continue;case 2:z.slice_from("õ");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function w(){return g<=z.cursor}function m(){return b<=z.cursor}function c(){return h<=z.cursor}function l(){var e;if(z.ket=z.cursor,!(e=z.find_among_b(F,45)))return!1;switch(z.bra=z.cursor,e){case 1:if(!c())return!1;z.slice_del();break;case 2:if(!c())return!1;z.slice_from("log");break;case 3:if(!c())return!1;z.slice_from("u");break;case 4:if(!c())return!1;z.slice_from("ente");break;case 5:if(!m())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(j,4),e&&(z.bra=z.cursor,c()&&(z.slice_del(),1==e&&(z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del()))));break;case 6:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(C,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 7:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(P,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 8:if(!c())return!1;z.slice_del(),z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del());break;case 9:if(!w()||!z.eq_s_b(1,"e"))return!1;z.slice_from("ir")}return!0}function f(){var e,r;if(z.cursor>=g){if(r=z.limit_backward,z.limit_backward=g,z.ket=z.cursor,e=z.find_among_b(S,120))return z.bra=z.cursor,1==e&&z.slice_del(),z.limit_backward=r,!0;z.limit_backward=r}return!1}function d(){var e;z.ket=z.cursor,(e=z.find_among_b(W,7))&&(z.bra=z.cursor,1==e&&w()&&z.slice_del())}function v(e,r){if(z.eq_s_b(1,e)){z.bra=z.cursor;var s=z.limit-z.cursor;if(z.eq_s_b(1,r))return z.cursor=z.limit-s,w()&&z.slice_del(),!1}return!0}function p(){var e;if(z.ket=z.cursor,e=z.find_among_b(L,4))switch(z.bra=z.cursor,e){case 1:w()&&(z.slice_del(),z.ket=z.cursor,z.limit-z.cursor,v("u","g")&&v("i","c"));break;case 2:z.slice_from("c")}}function _(){if(!l()&&(z.cursor=z.limit,!f()))return z.cursor=z.limit,void d();z.cursor=z.limit,z.ket=z.cursor,z.eq_s_b(1,"i")&&(z.bra=z.cursor,z.eq_s_b(1,"c")&&(z.cursor=z.limit,w()&&z.slice_del()))}var h,b,g,k=[new r("",-1,3),new r("ã",0,1),new r("õ",0,2)],q=[new r("",-1,3),new r("a~",0,1),new r("o~",0,2)],j=[new r("ic",-1,-1),new r("ad",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],C=[new r("ante",-1,1),new r("avel",-1,1),new r("ível",-1,1)],P=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],F=[new r("ica",-1,1),new r("ância",-1,1),new r("ência",-1,4),new r("ira",-1,9),new r("adora",-1,1),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,8),new r("eza",-1,1),new r("logía",-1,2),new r("idade",-1,7),new r("ante",-1,1),new r("mente",-1,6),new r("amente",12,5),new r("ável",-1,1),new r("ível",-1,1),new r("ución",-1,3),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,1),new r("imento",-1,1),new r("ivo",-1,8),new r("aça~o",-1,1),new r("ador",-1,1),new r("icas",-1,1),new r("ências",-1,4),new r("iras",-1,9),new r("adoras",-1,1),new r("osas",-1,1),new r("istas",-1,1),new r("ivas",-1,8),new r("ezas",-1,1),new r("logías",-1,2),new r("idades",-1,7),new r("uciones",-1,3),new r("adores",-1,1),new r("antes",-1,1),new r("aço~es",-1,1),new r("icos",-1,1),new r("ismos",-1,1),new r("osos",-1,1),new r("amentos",-1,1),new r("imentos",-1,1),new r("ivos",-1,8)],S=[new r("ada",-1,1),new r("ida",-1,1),new r("ia",-1,1),new r("aria",2,1),new r("eria",2,1),new r("iria",2,1),new r("ara",-1,1),new r("era",-1,1),new r("ira",-1,1),new r("ava",-1,1),new r("asse",-1,1),new r("esse",-1,1),new r("isse",-1,1),new r("aste",-1,1),new r("este",-1,1),new r("iste",-1,1),new r("ei",-1,1),new r("arei",16,1),new r("erei",16,1),new r("irei",16,1),new r("am",-1,1),new r("iam",20,1),new r("ariam",21,1),new r("eriam",21,1),new r("iriam",21,1),new r("aram",20,1),new r("eram",20,1),new r("iram",20,1),new r("avam",20,1),new r("em",-1,1),new r("arem",29,1),new r("erem",29,1),new r("irem",29,1),new r("assem",29,1),new r("essem",29,1),new r("issem",29,1),new r("ado",-1,1),new r("ido",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("indo",-1,1),new r("ara~o",-1,1),new r("era~o",-1,1),new r("ira~o",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("ir",-1,1),new r("as",-1,1),new r("adas",47,1),new r("idas",47,1),new r("ias",47,1),new r("arias",50,1),new r("erias",50,1),new r("irias",50,1),new r("aras",47,1),new r("eras",47,1),new r("iras",47,1),new r("avas",47,1),new r("es",-1,1),new r("ardes",58,1),new r("erdes",58,1),new r("irdes",58,1),new r("ares",58,1),new r("eres",58,1),new r("ires",58,1),new r("asses",58,1),new r("esses",58,1),new r("isses",58,1),new r("astes",58,1),new r("estes",58,1),new r("istes",58,1),new r("is",-1,1),new r("ais",71,1),new r("eis",71,1),new r("areis",73,1),new r("ereis",73,1),new r("ireis",73,1),new r("áreis",73,1),new r("éreis",73,1),new r("íreis",73,1),new r("ásseis",73,1),new r("ésseis",73,1),new r("ísseis",73,1),new r("áveis",73,1),new r("íeis",73,1),new r("aríeis",84,1),new r("eríeis",84,1),new r("iríeis",84,1),new r("ados",-1,1),new r("idos",-1,1),new r("amos",-1,1),new r("áramos",90,1),new r("éramos",90,1),new r("íramos",90,1),new r("ávamos",90,1),new r("íamos",90,1),new r("aríamos",95,1),new r("eríamos",95,1),new r("iríamos",95,1),new r("emos",-1,1),new r("aremos",99,1),new r("eremos",99,1),new r("iremos",99,1),new r("ássemos",99,1),new r("êssemos",99,1),new r("íssemos",99,1),new r("imos",-1,1),new r("armos",-1,1),new r("ermos",-1,1),new r("irmos",-1,1),new r("ámos",-1,1),new r("arás",-1,1),new r("erás",-1,1),new r("irás",-1,1),new r("eu",-1,1),new r("iu",-1,1),new r("ou",-1,1),new r("ará",-1,1),new r("erá",-1,1),new r("irá",-1,1)],W=[new r("a",-1,1),new r("i",-1,1),new r("o",-1,1),new r("os",-1,1),new r("á",-1,1),new r("í",-1,1),new r("ó",-1,1)],L=[new r("e",-1,1),new r("ç",-1,2),new r("é",-1,1),new r("ê",-1,1)],y=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],z=new s;this.setCurrent=function(e){z.setCurrent(e)},this.getCurrent=function(){return z.getCurrent()},this.stem=function(){var r=z.cursor;return e(),z.cursor=r,a(),z.limit_backward=r,z.cursor=z.limit,_(),z.cursor=z.limit,p(),z.cursor=z.limit_backward,u(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}});
```
--------------------------------------------------------------------------------
/docs/site/assets/javascripts/lunr/min/lunr.fr.min.js:
--------------------------------------------------------------------------------
```javascript
/*!
* Lunr languages, `French` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,"trimmer-fr"),e.fr.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,s){return!(!W.eq_s(1,e)||(W.ket=W.cursor,!W.in_grouping(F,97,251)))&&(W.slice_from(r),W.cursor=s,!0)}function i(e,r,s){return!!W.eq_s(1,e)&&(W.ket=W.cursor,W.slice_from(r),W.cursor=s,!0)}function n(){for(var r,s;;){if(r=W.cursor,W.in_grouping(F,97,251)){if(W.bra=W.cursor,s=W.cursor,e("u","U",r))continue;if(W.cursor=s,e("i","I",r))continue;if(W.cursor=s,i("y","Y",r))continue}if(W.cursor=r,W.bra=r,!e("y","Y",r)){if(W.cursor=r,W.eq_s(1,"q")&&(W.bra=W.cursor,i("u","U",r)))continue;if(W.cursor=r,r>=W.limit)return;W.cursor++}}}function t(){for(;!W.in_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}for(;!W.out_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}return!1}function u(){var e=W.cursor;if(q=W.limit,g=q,p=q,W.in_grouping(F,97,251)&&W.in_grouping(F,97,251)&&W.cursor<W.limit)W.cursor++;else if(W.cursor=e,!W.find_among(v,3)){W.cursor=e;do{if(W.cursor>=W.limit){W.cursor=q;break}W.cursor++}while(!W.in_grouping(F,97,251))}q=W.cursor,W.cursor=e,t()||(g=W.cursor,t()||(p=W.cursor))}function o(){for(var e,r;;){if(r=W.cursor,W.bra=r,!(e=W.find_among(h,4)))break;switch(W.ket=W.cursor,e){case 1:W.slice_from("i");break;case 2:W.slice_from("u");break;case 3:W.slice_from("y");break;case 4:if(W.cursor>=W.limit)return;W.cursor++}}}function c(){return q<=W.cursor}function a(){return g<=W.cursor}function l(){return p<=W.cursor}function w(){var e,r;if(W.ket=W.cursor,e=W.find_among_b(C,43)){switch(W.bra=W.cursor,e){case 1:if(!l())return!1;W.slice_del();break;case 2:if(!l())return!1;W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")&&(W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU"));break;case 3:if(!l())return!1;W.slice_from("log");break;case 4:if(!l())return!1;W.slice_from("u");break;case 5:if(!l())return!1;W.slice_from("ent");break;case 6:if(!c())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(z,6))switch(W.bra=W.cursor,e){case 1:l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&W.slice_del()));break;case 2:l()?W.slice_del():a()&&W.slice_from("eux");break;case 3:l()&&W.slice_del();break;case 4:c()&&W.slice_from("i")}break;case 7:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(y,3))switch(W.bra=W.cursor,e){case 1:l()?W.slice_del():W.slice_from("abl");break;case 2:l()?W.slice_del():W.slice_from("iqU");break;case 3:l()&&W.slice_del()}break;case 8:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")))){W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU");break}break;case 9:W.slice_from("eau");break;case 10:if(!a())return!1;W.slice_from("al");break;case 11:if(l())W.slice_del();else{if(!a())return!1;W.slice_from("eux")}break;case 12:if(!a()||!W.out_grouping_b(F,97,251))return!1;W.slice_del();break;case 13:return c()&&W.slice_from("ant"),!1;case 14:return c()&&W.slice_from("ent"),!1;case 15:return r=W.limit-W.cursor,W.in_grouping_b(F,97,251)&&c()&&(W.cursor=W.limit-r,W.slice_del()),!1}return!0}return!1}function f(){var e,r;if(W.cursor<q)return!1;if(r=W.limit_backward,W.limit_backward=q,W.ket=W.cursor,!(e=W.find_among_b(x,35)))return W.limit_backward=r,!1;if(W.bra=W.cursor,1==e){if(!W.out_grouping_b(F,97,251))return W.limit_backward=r,!1;W.slice_del()}return W.limit_backward=r,!0}function m(){var e,r,s;if(W.cursor<q)return!1;if(r=W.limit_backward,W.limit_backward=q,W.ket=W.cursor,!(e=W.find_among_b(I,38)))return W.limit_backward=r,!1;switch(W.bra=W.cursor,e){case 1:if(!l())return W.limit_backward=r,!1;W.slice_del();break;case 2:W.slice_del();break;case 3:W.slice_del(),s=W.limit-W.cursor,W.ket=W.cursor,W.eq_s_b(1,"e")?(W.bra=W.cursor,W.slice_del()):W.cursor=W.limit-s}return W.limit_backward=r,!0}function _(){var e,r,s,i,n=W.limit-W.cursor;if(W.ket=W.cursor,W.eq_s_b(1,"s")?(W.bra=W.cursor,r=W.limit-W.cursor,W.out_grouping_b(S,97,232)?(W.cursor=W.limit-r,W.slice_del()):W.cursor=W.limit-n):W.cursor=W.limit-n,W.cursor>=q){if(s=W.limit_backward,W.limit_backward=q,W.ket=W.cursor,e=W.find_among_b(P,7))switch(W.bra=W.cursor,e){case 1:if(l()){if(i=W.limit-W.cursor,!W.eq_s_b(1,"s")&&(W.cursor=W.limit-i,!W.eq_s_b(1,"t")))break;W.slice_del()}break;case 2:W.slice_from("i");break;case 3:W.slice_del();break;case 4:W.eq_s_b(2,"gu")&&W.slice_del()}W.limit_backward=s}}function b(){var e=W.limit-W.cursor;W.find_among_b(U,5)&&(W.cursor=W.limit-e,W.ket=W.cursor,W.cursor>W.limit_backward&&(W.cursor--,W.bra=W.cursor,W.slice_del()))}function d(){for(var e,r=1;W.out_grouping_b(F,97,251);)r--;if(r<=0){if(W.ket=W.cursor,e=W.limit-W.cursor,!W.eq_s_b(1,"é")&&(W.cursor=W.limit-e,!W.eq_s_b(1,"è")))return;W.bra=W.cursor,W.slice_from("e")}}function k(){if(!w()&&(W.cursor=W.limit,!f()&&(W.cursor=W.limit,!m())))return W.cursor=W.limit,void _();W.cursor=W.limit,W.ket=W.cursor,W.eq_s_b(1,"Y")?(W.bra=W.cursor,W.slice_from("i")):(W.cursor=W.limit,W.eq_s_b(1,"ç")&&(W.bra=W.cursor,W.slice_from("c")))}var p,g,q,v=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],h=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],z=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],y=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],C=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],x=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],I=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],P=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],U=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],F=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],S=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],W=new s;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){var e=W.cursor;return n(),W.cursor=e,u(),W.limit_backward=e,W.cursor=W.limit,k(),W.cursor=W.limit,b(),W.cursor=W.limit,d(),W.cursor=W.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}});
```
--------------------------------------------------------------------------------
/docs/site/assets/javascripts/lunr/min/lunr.ro.min.js:
--------------------------------------------------------------------------------
```javascript
/*!
* Lunr languages, `Romanian` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=function(){var i=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(e,i){L.eq_s(1,e)&&(L.ket=L.cursor,L.in_grouping(W,97,259)&&L.slice_from(i))}function n(){for(var i,r;;){if(i=L.cursor,L.in_grouping(W,97,259)&&(r=L.cursor,L.bra=r,e("u","U"),L.cursor=r,e("i","I")),L.cursor=i,L.cursor>=L.limit)break;L.cursor++}}function t(){if(L.out_grouping(W,97,259)){for(;!L.in_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}return!0}function a(){if(L.in_grouping(W,97,259))for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}function o(){var e,i,r=L.cursor;if(L.in_grouping(W,97,259)){if(e=L.cursor,!t())return void(h=L.cursor);if(L.cursor=e,!a())return void(h=L.cursor)}L.cursor=r,L.out_grouping(W,97,259)&&(i=L.cursor,t()&&(L.cursor=i,L.in_grouping(W,97,259)&&L.cursor<L.limit&&L.cursor++),h=L.cursor)}function u(){for(;!L.in_grouping(W,97,259);){if(L.cursor>=L.limit)return!1;L.cursor++}for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!1;L.cursor++}return!0}function c(){var e=L.cursor;h=L.limit,k=h,g=h,o(),L.cursor=e,u()&&(k=L.cursor,u()&&(g=L.cursor))}function s(){for(var e;;){if(L.bra=L.cursor,e=L.find_among(z,3))switch(L.ket=L.cursor,e){case 1:L.slice_from("i");continue;case 2:L.slice_from("u");continue;case 3:if(L.cursor>=L.limit)break;L.cursor++;continue}break}}function w(){return h<=L.cursor}function m(){return k<=L.cursor}function l(){return g<=L.cursor}function f(){var e,i;if(L.ket=L.cursor,(e=L.find_among_b(C,16))&&(L.bra=L.cursor,m()))switch(e){case 1:L.slice_del();break;case 2:L.slice_from("a");break;case 3:L.slice_from("e");break;case 4:L.slice_from("i");break;case 5:i=L.limit-L.cursor,L.eq_s_b(2,"ab")||(L.cursor=L.limit-i,L.slice_from("i"));break;case 6:L.slice_from("at");break;case 7:L.slice_from("aţi")}}function p(){var e,i=L.limit-L.cursor;if(L.ket=L.cursor,(e=L.find_among_b(P,46))&&(L.bra=L.cursor,m())){switch(e){case 1:L.slice_from("abil");break;case 2:L.slice_from("ibil");break;case 3:L.slice_from("iv");break;case 4:L.slice_from("ic");break;case 5:L.slice_from("at");break;case 6:L.slice_from("it")}return _=!0,L.cursor=L.limit-i,!0}return!1}function d(){var e,i;for(_=!1;;)if(i=L.limit-L.cursor,!p()){L.cursor=L.limit-i;break}if(L.ket=L.cursor,(e=L.find_among_b(F,62))&&(L.bra=L.cursor,l())){switch(e){case 1:L.slice_del();break;case 2:L.eq_s_b(1,"ţ")&&(L.bra=L.cursor,L.slice_from("t"));break;case 3:L.slice_from("ist")}_=!0}}function b(){var e,i,r;if(L.cursor>=h){if(i=L.limit_backward,L.limit_backward=h,L.ket=L.cursor,e=L.find_among_b(q,94))switch(L.bra=L.cursor,e){case 1:if(r=L.limit-L.cursor,!L.out_grouping_b(W,97,259)&&(L.cursor=L.limit-r,!L.eq_s_b(1,"u")))break;case 2:L.slice_del()}L.limit_backward=i}}function v(){var e;L.ket=L.cursor,(e=L.find_among_b(S,5))&&(L.bra=L.cursor,w()&&1==e&&L.slice_del())}var _,g,k,h,z=[new i("",-1,3),new i("I",0,1),new i("U",0,2)],C=[new i("ea",-1,3),new i("aţia",-1,7),new i("aua",-1,2),new i("iua",-1,4),new i("aţie",-1,7),new i("ele",-1,3),new i("ile",-1,5),new i("iile",6,4),new i("iei",-1,4),new i("atei",-1,6),new i("ii",-1,4),new i("ului",-1,1),new i("ul",-1,1),new i("elor",-1,3),new i("ilor",-1,4),new i("iilor",14,4)],P=[new i("icala",-1,4),new i("iciva",-1,4),new i("ativa",-1,5),new i("itiva",-1,6),new i("icale",-1,4),new i("aţiune",-1,5),new i("iţiune",-1,6),new i("atoare",-1,5),new i("itoare",-1,6),new i("ătoare",-1,5),new i("icitate",-1,4),new i("abilitate",-1,1),new i("ibilitate",-1,2),new i("ivitate",-1,3),new i("icive",-1,4),new i("ative",-1,5),new i("itive",-1,6),new i("icali",-1,4),new i("atori",-1,5),new i("icatori",18,4),new i("itori",-1,6),new i("ători",-1,5),new i("icitati",-1,4),new i("abilitati",-1,1),new i("ivitati",-1,3),new i("icivi",-1,4),new i("ativi",-1,5),new i("itivi",-1,6),new i("icităi",-1,4),new i("abilităi",-1,1),new i("ivităi",-1,3),new i("icităţi",-1,4),new i("abilităţi",-1,1),new i("ivităţi",-1,3),new i("ical",-1,4),new i("ator",-1,5),new i("icator",35,4),new i("itor",-1,6),new i("ător",-1,5),new i("iciv",-1,4),new i("ativ",-1,5),new i("itiv",-1,6),new i("icală",-1,4),new i("icivă",-1,4),new i("ativă",-1,5),new i("itivă",-1,6)],F=[new i("ica",-1,1),new i("abila",-1,1),new i("ibila",-1,1),new i("oasa",-1,1),new i("ata",-1,1),new i("ita",-1,1),new i("anta",-1,1),new i("ista",-1,3),new i("uta",-1,1),new i("iva",-1,1),new i("ic",-1,1),new i("ice",-1,1),new i("abile",-1,1),new i("ibile",-1,1),new i("isme",-1,3),new i("iune",-1,2),new i("oase",-1,1),new i("ate",-1,1),new i("itate",17,1),new i("ite",-1,1),new i("ante",-1,1),new i("iste",-1,3),new i("ute",-1,1),new i("ive",-1,1),new i("ici",-1,1),new i("abili",-1,1),new i("ibili",-1,1),new i("iuni",-1,2),new i("atori",-1,1),new i("osi",-1,1),new i("ati",-1,1),new i("itati",30,1),new i("iti",-1,1),new i("anti",-1,1),new i("isti",-1,3),new i("uti",-1,1),new i("işti",-1,3),new i("ivi",-1,1),new i("ităi",-1,1),new i("oşi",-1,1),new i("ităţi",-1,1),new i("abil",-1,1),new i("ibil",-1,1),new i("ism",-1,3),new i("ator",-1,1),new i("os",-1,1),new i("at",-1,1),new i("it",-1,1),new i("ant",-1,1),new i("ist",-1,3),new i("ut",-1,1),new i("iv",-1,1),new i("ică",-1,1),new i("abilă",-1,1),new i("ibilă",-1,1),new i("oasă",-1,1),new i("ată",-1,1),new i("ită",-1,1),new i("antă",-1,1),new i("istă",-1,3),new i("ută",-1,1),new i("ivă",-1,1)],q=[new i("ea",-1,1),new i("ia",-1,1),new i("esc",-1,1),new i("ăsc",-1,1),new i("ind",-1,1),new i("ând",-1,1),new i("are",-1,1),new i("ere",-1,1),new i("ire",-1,1),new i("âre",-1,1),new i("se",-1,2),new i("ase",10,1),new i("sese",10,2),new i("ise",10,1),new i("use",10,1),new i("âse",10,1),new i("eşte",-1,1),new i("ăşte",-1,1),new i("eze",-1,1),new i("ai",-1,1),new i("eai",19,1),new i("iai",19,1),new i("sei",-1,2),new i("eşti",-1,1),new i("ăşti",-1,1),new i("ui",-1,1),new i("ezi",-1,1),new i("âi",-1,1),new i("aşi",-1,1),new i("seşi",-1,2),new i("aseşi",29,1),new i("seseşi",29,2),new i("iseşi",29,1),new i("useşi",29,1),new i("âseşi",29,1),new i("işi",-1,1),new i("uşi",-1,1),new i("âşi",-1,1),new i("aţi",-1,2),new i("eaţi",38,1),new i("iaţi",38,1),new i("eţi",-1,2),new i("iţi",-1,2),new i("âţi",-1,2),new i("arăţi",-1,1),new i("serăţi",-1,2),new i("aserăţi",45,1),new i("seserăţi",45,2),new i("iserăţi",45,1),new i("userăţi",45,1),new i("âserăţi",45,1),new i("irăţi",-1,1),new i("urăţi",-1,1),new i("ârăţi",-1,1),new i("am",-1,1),new i("eam",54,1),new i("iam",54,1),new i("em",-1,2),new i("asem",57,1),new i("sesem",57,2),new i("isem",57,1),new i("usem",57,1),new i("âsem",57,1),new i("im",-1,2),new i("âm",-1,2),new i("ăm",-1,2),new i("arăm",65,1),new i("serăm",65,2),new i("aserăm",67,1),new i("seserăm",67,2),new i("iserăm",67,1),new i("userăm",67,1),new i("âserăm",67,1),new i("irăm",65,1),new i("urăm",65,1),new i("ârăm",65,1),new i("au",-1,1),new i("eau",76,1),new i("iau",76,1),new i("indu",-1,1),new i("ându",-1,1),new i("ez",-1,1),new i("ească",-1,1),new i("ară",-1,1),new i("seră",-1,2),new i("aseră",84,1),new i("seseră",84,2),new i("iseră",84,1),new i("useră",84,1),new i("âseră",84,1),new i("iră",-1,1),new i("ură",-1,1),new i("âră",-1,1),new i("ează",-1,1)],S=[new i("a",-1,1),new i("e",-1,1),new i("ie",1,1),new i("i",-1,1),new i("ă",-1,1)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var e=L.cursor;return n(),L.cursor=e,c(),L.limit_backward=e,L.cursor=L.limit,f(),L.cursor=L.limit,d(),L.cursor=L.limit,_||(L.cursor=L.limit,b(),L.cursor=L.limit),v(),L.cursor=L.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.ro.stemmer,"stemmer-ro"),e.ro.stopWordFilter=e.generateStopWordFilter("acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" ")),e.Pipeline.registerFunction(e.ro.stopWordFilter,"stopWordFilter-ro")}});
```
--------------------------------------------------------------------------------
/docs/site/assets/javascripts/lunr/min/lunr.it.min.js:
--------------------------------------------------------------------------------
```javascript
/*!
* Lunr languages, `Italian` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,"trimmer-it"),e.it.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!x.eq_s(1,e)||(x.ket=x.cursor,!x.in_grouping(L,97,249)))&&(x.slice_from(r),x.cursor=n,!0)}function i(){for(var r,n,i,o,t=x.cursor;;){if(x.bra=x.cursor,r=x.find_among(h,7))switch(x.ket=x.cursor,r){case 1:x.slice_from("à");continue;case 2:x.slice_from("è");continue;case 3:x.slice_from("ì");continue;case 4:x.slice_from("ò");continue;case 5:x.slice_from("ù");continue;case 6:x.slice_from("qU");continue;case 7:if(x.cursor>=x.limit)break;x.cursor++;continue}break}for(x.cursor=t;;)for(n=x.cursor;;){if(i=x.cursor,x.in_grouping(L,97,249)){if(x.bra=x.cursor,o=x.cursor,e("u","U",i))break;if(x.cursor=o,e("i","I",i))break}if(x.cursor=i,x.cursor>=x.limit)return void(x.cursor=n);x.cursor++}}function o(e){if(x.cursor=e,!x.in_grouping(L,97,249))return!1;for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function t(){if(x.in_grouping(L,97,249)){var e=x.cursor;if(x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return o(e);x.cursor++}return!0}return o(e)}return!1}function s(){var e,r=x.cursor;if(!t()){if(x.cursor=r,!x.out_grouping(L,97,249))return;if(e=x.cursor,x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return x.cursor=e,void(x.in_grouping(L,97,249)&&x.cursor<x.limit&&x.cursor++);x.cursor++}return void(k=x.cursor)}if(x.cursor=e,!x.in_grouping(L,97,249)||x.cursor>=x.limit)return;x.cursor++}k=x.cursor}function a(){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function u(){var e=x.cursor;k=x.limit,p=k,g=k,s(),x.cursor=e,a()&&(p=x.cursor,a()&&(g=x.cursor))}function c(){for(var e;;){if(x.bra=x.cursor,!(e=x.find_among(q,3)))break;switch(x.ket=x.cursor,e){case 1:x.slice_from("i");break;case 2:x.slice_from("u");break;case 3:if(x.cursor>=x.limit)return;x.cursor++}}}function w(){return k<=x.cursor}function l(){return p<=x.cursor}function m(){return g<=x.cursor}function f(){var e;if(x.ket=x.cursor,x.find_among_b(C,37)&&(x.bra=x.cursor,(e=x.find_among_b(z,5))&&w()))switch(e){case 1:x.slice_del();break;case 2:x.slice_from("e")}}function v(){var e;if(x.ket=x.cursor,!(e=x.find_among_b(S,51)))return!1;switch(x.bra=x.cursor,e){case 1:if(!m())return!1;x.slice_del();break;case 2:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del());break;case 3:if(!m())return!1;x.slice_from("log");break;case 4:if(!m())return!1;x.slice_from("u");break;case 5:if(!m())return!1;x.slice_from("ente");break;case 6:if(!w())return!1;x.slice_del();break;case 7:if(!l())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(P,4),e&&(x.bra=x.cursor,m()&&(x.slice_del(),1==e&&(x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&x.slice_del()))));break;case 8:if(!m())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(F,3),e&&(x.bra=x.cursor,1==e&&m()&&x.slice_del());break;case 9:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del())))}return!0}function b(){var e,r;x.cursor>=k&&(r=x.limit_backward,x.limit_backward=k,x.ket=x.cursor,e=x.find_among_b(W,87),e&&(x.bra=x.cursor,1==e&&x.slice_del()),x.limit_backward=r)}function d(){var e=x.limit-x.cursor;if(x.ket=x.cursor,x.in_grouping_b(y,97,242)&&(x.bra=x.cursor,w()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(1,"i")&&(x.bra=x.cursor,w()))))return void x.slice_del();x.cursor=x.limit-e}function _(){d(),x.ket=x.cursor,x.eq_s_b(1,"h")&&(x.bra=x.cursor,x.in_grouping_b(U,99,103)&&w()&&x.slice_del())}var g,p,k,h=[new r("",-1,7),new r("qu",0,6),new r("á",0,1),new r("é",0,2),new r("í",0,3),new r("ó",0,4),new r("ú",0,5)],q=[new r("",-1,3),new r("I",0,1),new r("U",0,2)],C=[new r("la",-1,-1),new r("cela",0,-1),new r("gliela",0,-1),new r("mela",0,-1),new r("tela",0,-1),new r("vela",0,-1),new r("le",-1,-1),new r("cele",6,-1),new r("gliele",6,-1),new r("mele",6,-1),new r("tele",6,-1),new r("vele",6,-1),new r("ne",-1,-1),new r("cene",12,-1),new r("gliene",12,-1),new r("mene",12,-1),new r("sene",12,-1),new r("tene",12,-1),new r("vene",12,-1),new r("ci",-1,-1),new r("li",-1,-1),new r("celi",20,-1),new r("glieli",20,-1),new r("meli",20,-1),new r("teli",20,-1),new r("veli",20,-1),new r("gli",20,-1),new r("mi",-1,-1),new r("si",-1,-1),new r("ti",-1,-1),new r("vi",-1,-1),new r("lo",-1,-1),new r("celo",31,-1),new r("glielo",31,-1),new r("melo",31,-1),new r("telo",31,-1),new r("velo",31,-1)],z=[new r("ando",-1,1),new r("endo",-1,1),new r("ar",-1,2),new r("er",-1,2),new r("ir",-1,2)],P=[new r("ic",-1,-1),new r("abil",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],F=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],S=[new r("ica",-1,1),new r("logia",-1,3),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,9),new r("anza",-1,1),new r("enza",-1,5),new r("ice",-1,1),new r("atrice",7,1),new r("iche",-1,1),new r("logie",-1,3),new r("abile",-1,1),new r("ibile",-1,1),new r("usione",-1,4),new r("azione",-1,2),new r("uzione",-1,4),new r("atore",-1,2),new r("ose",-1,1),new r("ante",-1,1),new r("mente",-1,1),new r("amente",19,7),new r("iste",-1,1),new r("ive",-1,9),new r("anze",-1,1),new r("enze",-1,5),new r("ici",-1,1),new r("atrici",25,1),new r("ichi",-1,1),new r("abili",-1,1),new r("ibili",-1,1),new r("ismi",-1,1),new r("usioni",-1,4),new r("azioni",-1,2),new r("uzioni",-1,4),new r("atori",-1,2),new r("osi",-1,1),new r("anti",-1,1),new r("amenti",-1,6),new r("imenti",-1,6),new r("isti",-1,1),new r("ivi",-1,9),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,6),new r("imento",-1,6),new r("ivo",-1,9),new r("ità",-1,8),new r("istà",-1,1),new r("istè",-1,1),new r("istì",-1,1)],W=[new r("isca",-1,1),new r("enda",-1,1),new r("ata",-1,1),new r("ita",-1,1),new r("uta",-1,1),new r("ava",-1,1),new r("eva",-1,1),new r("iva",-1,1),new r("erebbe",-1,1),new r("irebbe",-1,1),new r("isce",-1,1),new r("ende",-1,1),new r("are",-1,1),new r("ere",-1,1),new r("ire",-1,1),new r("asse",-1,1),new r("ate",-1,1),new r("avate",16,1),new r("evate",16,1),new r("ivate",16,1),new r("ete",-1,1),new r("erete",20,1),new r("irete",20,1),new r("ite",-1,1),new r("ereste",-1,1),new r("ireste",-1,1),new r("ute",-1,1),new r("erai",-1,1),new r("irai",-1,1),new r("isci",-1,1),new r("endi",-1,1),new r("erei",-1,1),new r("irei",-1,1),new r("assi",-1,1),new r("ati",-1,1),new r("iti",-1,1),new r("eresti",-1,1),new r("iresti",-1,1),new r("uti",-1,1),new r("avi",-1,1),new r("evi",-1,1),new r("ivi",-1,1),new r("isco",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("Yamo",-1,1),new r("iamo",-1,1),new r("avamo",-1,1),new r("evamo",-1,1),new r("ivamo",-1,1),new r("eremo",-1,1),new r("iremo",-1,1),new r("assimo",-1,1),new r("ammo",-1,1),new r("emmo",-1,1),new r("eremmo",54,1),new r("iremmo",54,1),new r("immo",-1,1),new r("ano",-1,1),new r("iscano",58,1),new r("avano",58,1),new r("evano",58,1),new r("ivano",58,1),new r("eranno",-1,1),new r("iranno",-1,1),new r("ono",-1,1),new r("iscono",65,1),new r("arono",65,1),new r("erono",65,1),new r("irono",65,1),new r("erebbero",-1,1),new r("irebbero",-1,1),new r("assero",-1,1),new r("essero",-1,1),new r("issero",-1,1),new r("ato",-1,1),new r("ito",-1,1),new r("uto",-1,1),new r("avo",-1,1),new r("evo",-1,1),new r("ivo",-1,1),new r("ar",-1,1),new r("ir",-1,1),new r("erà",-1,1),new r("irà",-1,1),new r("erò",-1,1),new r("irò",-1,1)],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],y=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],U=[17],x=new n;this.setCurrent=function(e){x.setCurrent(e)},this.getCurrent=function(){return x.getCurrent()},this.stem=function(){var e=x.cursor;return i(),x.cursor=e,u(),x.limit_backward=e,x.cursor=x.limit,f(),x.cursor=x.limit,v()||(x.cursor=x.limit,b()),x.cursor=x.limit,_(),x.cursor=x.limit_backward,c(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.it.stemmer,"stemmer-it"),e.it.stopWordFilter=e.generateStopWordFilter("a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" ")),e.Pipeline.registerFunction(e.it.stopWordFilter,"stopWordFilter-it")}});
```
--------------------------------------------------------------------------------
/tests/sample_project_typescript/src/advanced-types.ts:
--------------------------------------------------------------------------------
```typescript
/**
* Advanced Types
* Demonstrates TypeScript's advanced type system including mapped types,
* conditional types, template literal types, type manipulation, and complex patterns
*/
// ========== Mapped Types ==========
export type Optional<T> = {
[K in keyof T]?: T[K];
};
export type Required<T> = {
[K in keyof T]-?: T[K];
};
export type Readonly<T> = {
readonly [K in keyof T]: T[K];
};
export type Mutable<T> = {
-readonly [K in keyof T]: T[K];
};
// Custom mapped type with transformation
export type Stringify<T> = {
[K in keyof T]: string;
};
export type Nullify<T> = {
[K in keyof T]: T[K] | null;
};
// Mapped type with key transformation
export type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
export type Setters<T> = {
[K in keyof T as `set${Capitalize<string & K>}`]: (value: T[K]) => void;
};
// ========== Conditional Types ==========
export type NonNullable<T> = T extends null | undefined ? never : T;
export type IsArray<T> = T extends any[] ? true : false;
export type ArrayElementType<T> = T extends (infer U)[] ? U : never;
export type ReturnTypeOf<T> = T extends (...args: any[]) => infer R ? R : never;
export type ParametersOf<T> = T extends (...args: infer P) => any ? P : never;
// Complex conditional type
export type DeepReadonly<T> = T extends (infer U)[]
? DeepReadonlyArray<U>
: T extends object
? DeepReadonlyObject<T>
: T;
interface DeepReadonlyArray<T> extends ReadonlyArray<DeepReadonly<T>> {}
type DeepReadonlyObject<T> = {
readonly [K in keyof T]: DeepReadonly<T[K]>;
};
// Conditional type with multiple conditions
export type TypeName<T> = T extends string
? "string"
: T extends number
? "number"
: T extends boolean
? "boolean"
: T extends undefined
? "undefined"
: T extends Function
? "function"
: "object";
// ========== Template Literal Types ==========
export type EventNames<T extends string> = `${T}Changed` | `${T}Updated` | `before${Capitalize<T>}`;
export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
export type ApiEndpoint<T extends string> = `api/${T}`;
export type ApiUrl<T extends string, M extends HttpMethod> = `${M} /${ApiEndpoint<T>}`;
// CSS-in-JS style types
export type CSSProperty = `--${string}` | keyof CSSStyleDeclaration;
export type PixelValue<T extends number> = `${T}px`;
export type PercentValue<T extends number> = `${T}%`;
// Path-like template literals
export type Join<K, P> = K extends string | number
? P extends string | number
? `${K}${"" extends P ? "" : "."}${P}`
: never
: never;
export type Paths<T, D extends number = 10> = [D] extends [never]
? never
: T extends object
? {
[K in keyof T]-?: K extends string | number
? `${K}` | Join<K, Paths<T[K], Prev[D]>>
: never;
}[keyof T]
: "";
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...0[]];
// ========== Utility Types and Type Manipulation ==========
export type PickByType<T, U> = Pick<T, { [K in keyof T]: T[K] extends U ? K : never }[keyof T]>;
export type OmitByType<T, U> = Omit<T, { [K in keyof T]: T[K] extends U ? K : never }[keyof T]>;
export type ExcludeKeys<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
export type KeysOfType<T, U> = { [K in keyof T]: T[K] extends U ? K : never }[keyof T];
// Deep pick utility
export type DeepPick<T, K extends Paths<T>> = K extends `${infer Key}.${infer Rest}`
? Key extends keyof T
? { [P in Key]: DeepPick<T[P], Rest> }
: never
: K extends keyof T
? { [P in K]: T[P] }
: never;
// Function type utilities
export type Promisify<T> = T extends (...args: infer A) => infer R
? (...args: A) => Promise<R>
: never;
export type Curry<T> = T extends (...args: infer A) => infer R
? A extends [infer First, ...infer Rest]
? (arg: First) => Rest extends []
? R
: Curry<(...args: Rest) => R>
: () => R
: never;
// ========== Recursive Types ==========
export type DeepPartial<T> = T extends object
? {
[P in keyof T]?: DeepPartial<T[P]>;
}
: T;
export type DeepRequired<T> = T extends object
? {
[P in keyof T]-?: DeepRequired<T[P]>;
}
: T;
// JSON type
export type JSONValue = string | number | boolean | null | JSONObject | JSONArray;
interface JSONObject {
[key: string]: JSONValue;
}
interface JSONArray extends Array<JSONValue> {}
// ========== Branded Types ==========
declare const __brand: unique symbol;
type Brand<T, TBrand extends string> = T & { [__brand]: TBrand };
export type UserId = Brand<number, "UserId">;
export type Email = Brand<string, "Email">;
export type Timestamp = Brand<number, "Timestamp">;
// Brand creation utilities
export const createUserId = (id: number): UserId => id as UserId;
export const createEmail = (email: string): Email => {
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
throw new Error("Invalid email format");
}
return email as Email;
};
// ========== Tuple Utilities ==========
export type Head<T extends readonly any[]> = T extends readonly [infer H, ...any[]] ? H : never;
export type Tail<T extends readonly any[]> = T extends readonly [any, ...infer Rest] ? Rest : [];
export type Last<T extends readonly any[]> = T extends readonly [...any[], infer L] ? L : never;
export type Length<T extends readonly any[]> = T["length"];
export type Reverse<T extends any[]> = T extends [...infer Rest, infer Last]
? [Last, ...Reverse<Rest>]
: [];
// ========== String Manipulation Types ==========
export type Uppercase<S extends string> = intrinsic;
export type Lowercase<S extends string> = intrinsic;
export type Capitalize<S extends string> = intrinsic;
export type Uncapitalize<S extends string> = intrinsic;
export type Split<S extends string, D extends string> = string extends S
? string[]
: S extends ""
? []
: S extends `${infer T}${D}${infer U}`
? [T, ...Split<U, D>]
: [S];
export type Join<T extends string[], D extends string> = T extends [
infer First,
...infer Rest
]
? First extends string
? Rest extends string[]
? Rest["length"] extends 0
? First
: `${First}${D}${Join<Rest, D>}`
: never
: never
: "";
// ========== Advanced Pattern Matching ==========
export type ExtractRouteParams<T extends string> = T extends `${string}:${infer Param}/${infer Rest}`
? { [K in Param]: string } & ExtractRouteParams<Rest>
: T extends `${string}:${infer Param}`
? { [K in Param]: string }
: {};
export type ParseQueryString<T extends string> = T extends `${infer Key}=${infer Value}&${infer Rest}`
? { [K in Key]: Value } & ParseQueryString<Rest>
: T extends `${infer Key}=${infer Value}`
? { [K in Key]: Value }
: {};
// ========== Type Predicates and Guards ==========
export type IsUnion<T, U = T> = T extends U ? ([U] extends [T] ? false : true) : false;
export type IsNever<T> = [T] extends [never] ? true : false;
export type IsAny<T> = 0 extends 1 & T ? true : false;
export type IsUnknown<T> = IsAny<T> extends true ? false : unknown extends T ? true : false;
// ========== Higher-Kinded Types Simulation ==========
export interface Functor<F> {
map<A, B>(fn: (a: A) => B): <T extends F>(fa: T) => T extends HKT<F, A> ? HKT<F, B> : never;
}
export interface HKT<F, A> {
_F: F;
_A: A;
}
// Array functor instance
export type ArrayHKT = "Array";
export interface ArrayF<A> extends HKT<ArrayHKT, A> {
_tag: A[];
}
// ========== Example Usage Types ==========
interface User {
id: number;
name: string;
email: string;
age: number;
address: {
street: string;
city: string;
country: string;
};
preferences: {
theme: "light" | "dark";
notifications: boolean;
};
}
// Applied utility types
export type Examples = {
// Mapped types
optionalUser: Optional<User>;
readonlyUser: Readonly<User>;
stringifiedUser: Stringify<User>;
// Conditional types
userIsArray: IsArray<User>;
userArrayElement: ArrayElementType<User[]>;
nonNullableString: NonNullable<string | null>;
// Template literals
userEventNames: EventNames<"user">;
apiEndpoints: ApiUrl<"users", "GET"> | ApiUrl<"posts", "POST">;
// Utility combinations
userOnlyStrings: PickByType<User, string>;
userWithoutStrings: OmitByType<User, string>;
userPaths: Paths<User>;
// Branded types
userId: UserId;
userEmail: Email;
// Advanced patterns
routeParams: ExtractRouteParams<"/users/:id/posts/:postId">;
queryParams: ParseQueryString<"search=typescript&sort=date&limit=10">;
};
// ========== Complex Type Challenges ==========
// Function composition types
export type Compose<F extends any[], T = any> = F extends [
(...args: any[]) => infer R
]
? (arg: T) => R
: F extends [(...args: any[]) => infer R, ...infer Rest]
? (arg: T) => Compose<Rest, R>
: never;
// Object path access
export type Get<T, K> = K extends `${infer Key}.${infer Rest}`
? Key extends keyof T
? Get<T[Key], Rest>
: never
: K extends keyof T
? T[K]
: never;
// Type-safe SQL-like operations
export type Select<T, K extends keyof T> = Pick<T, K>;
export type Where<T, K extends keyof T, V> = T[K] extends V ? T : never;
export type OrderBy<T, K extends keyof T> = T; // Simplified for demo
// State machine types
export type StateMachine<States extends string, Events extends string> = {
[S in States]: {
[E in Events]?: States;
};
};
export type UserStateMachine = StateMachine<
"idle" | "loading" | "success" | "error",
"fetch" | "success" | "error" | "reset"
>;
// ========== Type-Level Arithmetic (Basic) ==========
export type Add<A extends number, B extends number> = [...Tuple<A>, ...Tuple<B>]["length"];
export type Tuple<T extends number> = T extends T ? (T extends 0 ? [] : [...Tuple<Subtract<T, 1>>, any]) : never;
export type Subtract<A extends number, B extends number> = Tuple<A> extends [...infer U, ...Tuple<B>] ? U["length"] : never;
// ========== Usage Examples ==========
export const advancedTypesExamples = {
// Branded types usage
userId: createUserId(123),
userEmail: createEmail("[email protected]"),
// Template literal types
apiUrl: "GET /api/users" as ApiUrl<"users", "GET">,
// Complex type transformations
userPaths: ["id", "name", "email", "address.street", "preferences.theme"] as Paths<User>[],
// Type predicates
isUnion: false as IsUnion<string | number>,
isNever: false as IsNever<never>,
isAny: false as IsAny<any>,
};
// Example of using advanced types in practice
export function createTypeSafeGetter<T>() {
return function get<K extends Paths<T>>(obj: T, path: K): Get<T, K> {
const keys = path.split('.') as string[];
let result: any = obj;
for (const key of keys) {
result = result?.[key];
}
return result as Get<T, K>;
};
}
// Usage of the type-safe getter
const userGetter = createTypeSafeGetter<User>();
export const getExample = {
userName: userGetter({} as User, "name"), // Type is string
userCity: userGetter({} as User, "address.city"), // Type is string
userTheme: userGetter({} as User, "preferences.theme"), // Type is "light" | "dark"
};
```
--------------------------------------------------------------------------------
/docs/docs/index.md:
--------------------------------------------------------------------------------
```markdown
# Welcome to CodeGraphContext
This is the official documentation for CodeGraphContext.
---
# CodeGraphContext
<!-- ====== Project stats ====== -->
[](https://github.com/Shashankss1205/CodeGraphContext/stargazers)
[](https://github.com/Shashankss1205/CodeGraphContext/network/members)
[](https://github.com/Shashankss1205/CodeGraphContext/issues)
[](https://github.com/Shashankss1205/CodeGraphContext/pulls)
[](https://github.com/Shashankss1205/CodeGraphContext/pulls?q=is%3Apr+is%3Aclosed)
[](https://github.com/Shashankss1205/CodeGraphContext/graphs/contributors)
[](https://github.com/Shashankss1205/CodeGraphContext)
[](https://github.com/Shashankss1205/CodeGraphContext/actions/workflows/test.yml)
[](https://github.com/Shashankss1205/CodeGraphContext/actions/workflows/e2e-tests.yml)
[](https://pypi.org/project/codegraphcontext/)
[](https://pypi.org/project/codegraphcontext/)
[](license.md)
[](http://codegraphcontext.vercel.app/)
[](https://youtu.be/KYYSdxhg1xU)
[](https://discord.gg/dR4QY32uYQ)
An MCP server that indexes local code into a graph database to provide context to AI assistants.
### Indexing a codebase

### Using the MCP server

## Project Details
- **Version:** 0.1.15
- **Authors:** Shashank Shekhar Singh <[email protected]>
- **License:** MIT License (See [LICENSE](license.md) for details)
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
## Star History
[](https://www.star-history.com/#Shashankss1205/CodeGraphContext&Date)
## Features
- **Code Indexing:** Analyzes code and builds a knowledge graph of its components.
- **Relationship Analysis:** Query for callers, callees, class hierarchies, call chains and more.
- **Live Updates:** Watches local files for changes and automatically updates the graph.
- **Interactive Setup:** A user-friendly command-line wizard for easy setup.
- **File Exclusion:** Supports `.cgcignore` files to exclude specific files and directories from indexing.
## Used By
CodeGraphContext is already being explored by developers and projects for:
- **Static code analysis in AI assistants**
- **Graph-based visualization of projects**
- **Dead code and complexity detection**
If you’re using CodeGraphContext in your project, feel free to open a PR and add it here! 🚀
## Dependencies
- `neo4j>=5.15.0`
- `watchdog>=3.0.0`
- `requests>=2.31.0`
- `stdlibs>=2023.11.18`
- `typer[all]>=0.9.0`
- `rich>=13.7.0`
- `inquirerpy>=0.3.4`
- `python-dotenv>=1.0.0`
- `tree-sitter==0.20.4`
- `tree-sitter-languages==1.10.2`
## Getting Started
1. **Install:** `pip install codegraphcontext`
2. **Configure Your Environment:**
Run the interactive setup wizard to connect to your database and configure your IDE:
```bash
cgc setup
```
The wizard helps you with:
- **Database Connection:**
- **Docker (Recommended):** Automatically sets up a local Neo4j instance.
- **Linux Binary:** Installs Neo4j directly on Debian-based systems.
- **Hosted:** Connects to a remote Neo4j database like AuraDB.
- **IDE Integration:**
- Automatically configures tools like VS Code, Cursor, Gemini CLI, and more.
- Generates the necessary `mcp.json` and `.env` files for you.
3. **Start:** `cgc start`
## MCP Client Configuration
The `cgc setup` command attempts to automatically configure your IDE/CLI. If you choose not to use the automatic setup, or if your tool is not supported, you can configure it manually.
Add the following server configuration to your client's settings file (e.g., VS Code's `settings.json` or `.claude.json`):
```json
{
"mcpServers": {
"CodeGraphContext": {
"command": "cgc",
"args": [
"start"
],
"env": {
"NEO4J_URI": "YOUR_NEO4J_URI",
"NEO4J_USERNAME": "YOUR_NEO4J_USERNAME",
"NEO4J_PASSWORD": "YOUR_NEO4J_PASSWORD"
},
"tools": {
"alwaysAllow": [
"add_code_to_graph",
"add_package_to_graph",
"check_job_status",
"list_jobs",
"find_code",
"analyze_code_relationships",
"watch_directory",
"find_dead_code",
"execute_cypher_query",
"calculate_cyclomatic_complexity",
"find_most_complex_functions",
"list_indexed_repositories",
"delete_repository",
"visualize_graph_query",
"list_watched_paths",
"unwatch_directory"
],
"disabled": false
},
"disabled": false,
"alwaysAllow": []
}
}
}
```
## Natural Language Interaction Examples
Once the server is running, you can interact with it through your AI assistant using plain English. Here are some examples of what you can say:
### Indexing and Watching Files
- **To index a new project:**
- "Please index the code in the `/path/to/my-project` directory."
OR
- "Add the project at `~/dev/my-other-project` to the code graph."
- **To start watching a directory for live changes:**
- "Watch the `/path/to/my-active-project` directory for changes."
OR
- "Keep the code graph updated for the project I'm working on at `~/dev/main-app`."
When you ask to watch a directory, the system performs two actions at once:
1. It kicks off a full scan to index all the code in that directory. This process runs in the background, and you'll receive a `job_id` to track its progress.
2. It begins watching the directory for any file changes to keep the graph updated in real-time.
This means you can start by simply telling the system to watch a directory, and it will handle both the initial indexing and the continuous updates automatically.
### Querying and Understanding Code
- **Finding where code is defined:**
- "Where is the `process_payment` function?"
- "Find the `User` class for me."
- "Show me any code related to 'database connection'."
- **Analyzing relationships and impact:**
- "What other functions call the `get_user_by_id` function?"
- "If I change the `calculate_tax` function, what other parts of the code will be affected?"
- "Show me the inheritance hierarchy for the `BaseController` class."
- "What methods does the `Order` class have?"
- **Exploring dependencies:**
- "Which files import the `requests` library?"
- "Find all implementations of the `render` method."
- **Advanced Call Chain and Dependency Tracking (Spanning Hundreds of Files):**
The CodeGraphContext excels at tracing complex execution flows and dependencies across vast codebases. Leveraging the power of graph databases, it can identify direct and indirect callers and callees, even when a function is called through multiple layers of abstraction or across numerous files. This is invaluable for:
- **Impact Analysis:** Understand the full ripple effect of a change to a core function.
- **Debugging:** Trace the path of execution from an entry point to a specific bug.
- **Code Comprehension:** Grasp how different parts of a large system interact.
- "Show me the full call chain from the `main` function to `process_data`."
- "Find all functions that directly or indirectly call `validate_input`."
- "What are all the functions that `initialize_system` eventually calls?"
- "Trace the dependencies of the `DatabaseManager` module."
- **Code Quality and Maintenance:**
- "Is there any dead or unused code in this project?"
- "Calculate the cyclomatic complexity of the `process_data` function in `src/utils.py`."
- "Find the 5 most complex functions in the codebase."
- **Repository Management:**
- "List all currently indexed repositories."
- "Delete the indexed repository at `/path/to/old-project`."
## Social Coverage
- **Youtube:** [https://www.youtube.com/watch?v=KYYSdxhg1xU](https://www.youtube.com/watch?v=KYYSdxhg1xU)
- **Blog:** [https://medium.com/@shashankshekharsingh1205/building-codegraphcontext-my-end-term-journey-in-summer-of-bitcoin-2025-422c9a4dc87e](https://medium.com/@shashankshekharsingh1205/building-codegraphcontext-my-end-term-journey-in-summer-of-bitcoin-2025-422c9a4dc87e)
- **Twitter:** [https://x.com/braidpool/status/1968683721625637203](https://x.com/braidpool/status/1968683721625637203)
- **PulseMCP:** [https://www.pulsemcp.com/servers/codegraphcontext](https://www.pulsemcp.com/servers/codegraphcontext)
- **MCPMarket:** [https://mcpmarket.com/server/codegraphcontext](https://mcpmarket.com/server/codegraphcontext)
- **Playbooks:** [https://playbooks.com/mcp/codegraphcontext](https://playbooks.com/mcp/codegraphcontext)
- **MCPHunt:** [https://mcp-hunt.com/mcp/server/codegraphcontext](https://mcp-hunt.com/mcp/server/codegraphcontext)
- **StackerNews:** [https://stacker.news/items/1227191](https://stacker.news/items/1227191)
- **Glama.ai:** [https://glama.ai/mcp/servers/@Shashankss1205/CodeGraphContext/blob/a346d340d8f705ce93626b4b322dd0e2823ba46b/src/codegraphcontext/core/jobs.py](https://glama.ai/mcp/servers/@Shashankss1205/CodeGraphContext/blob/a346d340d8f705ce93626b4b322dd0e2823ba46b/src/codegraphcontext/core/jobs.py)
## Contributing
Contributions are welcome! 🎉
Please see our [CONTRIBUTING.md](contributing.md) for detailed guidelines.
If you have ideas for new features, integrations, or improvements, open an [issue](https://github.com/Shashankss1205/CodeGraphContext/issues) or submit a Pull Request.
Join discussions and help shape the future of CodeGraphContext.
```
--------------------------------------------------------------------------------
/tests/sample_project_typescript/src/async-promises.ts:
--------------------------------------------------------------------------------
```typescript
/**
* Async and Promises
* Demonstrates TypeScript's asynchronous programming features including
* promises, async/await, error handling, concurrent operations, and patterns
*/
// ========== Basic Promises ==========
export function createPromise<T>(value: T, delay: number = 100): Promise<T> {
return new Promise((resolve) => {
setTimeout(() => resolve(value), delay);
});
}
export function createRejectedPromise(error: string, delay: number = 100): Promise<never> {
return new Promise((_, reject) => {
setTimeout(() => reject(new Error(error)), delay);
});
}
// ========== Async Functions ==========
export async function fetchUserData(id: number): Promise<{ id: number; name: string; email: string }> {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 200));
if (id <= 0) {
throw new Error("Invalid user ID");
}
return {
id,
name: `User ${id}`,
email: `user${id}@example.com`
};
}
export async function fetchUserPosts(userId: number): Promise<{ id: number; title: string; content: string }[]> {
await new Promise(resolve => setTimeout(resolve, 150));
return Array.from({ length: 3 }, (_, index) => ({
id: index + 1,
title: `Post ${index + 1} by User ${userId}`,
content: `This is the content of post ${index + 1}`
}));
}
// ========== Error Handling with Async/Await ==========
export async function safeAsyncOperation<T>(
operation: () => Promise<T>
): Promise<{ success: true; data: T } | { success: false; error: string }> {
try {
const data = await operation();
return { success: true, data };
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : "Unknown error"
};
}
}
export async function retryOperation<T>(
operation: () => Promise<T>,
maxRetries: number = 3,
delay: number = 1000
): Promise<T> {
let lastError: Error;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
lastError = error instanceof Error ? error : new Error(String(error));
if (attempt === maxRetries) {
throw lastError;
}
// Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay * Math.pow(2, attempt - 1)));
}
}
throw lastError!;
}
// ========== Promise Combinators ==========
export async function processInParallel<T>(
items: T[],
processor: (item: T) => Promise<any>,
concurrency: number = 3
): Promise<any[]> {
const results: any[] = [];
const chunks: T[][] = [];
// Split into chunks
for (let i = 0; i < items.length; i += concurrency) {
chunks.push(items.slice(i, i + concurrency));
}
// Process chunks sequentially, items within chunks in parallel
for (const chunk of chunks) {
const chunkResults = await Promise.all(chunk.map(processor));
results.push(...chunkResults);
}
return results;
}
export async function raceWithTimeout<T>(
promise: Promise<T>,
timeoutMs: number
): Promise<T> {
const timeoutPromise = new Promise<never>((_, reject) => {
setTimeout(() => reject(new Error(`Operation timed out after ${timeoutMs}ms`)), timeoutMs);
});
return Promise.race([promise, timeoutPromise]);
}
// ========== Async Iterators and Generators ==========
export async function* asyncGenerator(count: number): AsyncGenerator<number, void, unknown> {
for (let i = 0; i < count; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
export async function* fetchDataStream(urls: string[]): AsyncGenerator<string, void, unknown> {
for (const url of urls) {
// Simulate fetching data
await new Promise(resolve => setTimeout(resolve, 200));
yield `Data from ${url}`;
}
}
export async function consumeAsyncGenerator<T>(generator: AsyncGenerator<T>): Promise<T[]> {
const results: T[] = [];
for await (const item of generator) {
results.push(item);
}
return results;
}
// ========== Observable Pattern ==========
export class EventEmitter<T> {
private listeners: ((data: T) => void)[] = [];
private asyncListeners: ((data: T) => Promise<void>)[] = [];
subscribe(callback: (data: T) => void): () => void {
this.listeners.push(callback);
return () => {
const index = this.listeners.indexOf(callback);
if (index > -1) {
this.listeners.splice(index, 1);
}
};
}
subscribeAsync(callback: (data: T) => Promise<void>): () => void {
this.asyncListeners.push(callback);
return () => {
const index = this.asyncListeners.indexOf(callback);
if (index > -1) {
this.asyncListeners.splice(index, 1);
}
};
}
emit(data: T): void {
this.listeners.forEach(callback => callback(data));
// Fire async listeners but don't wait
this.asyncListeners.forEach(callback => callback(data).catch(console.error));
}
async emitAsync(data: T): Promise<void> {
this.listeners.forEach(callback => callback(data));
await Promise.all(this.asyncListeners.map(callback => callback(data)));
}
}
// ========== Promise Pool ==========
export class PromisePool<T, R> {
private concurrency: number;
private tasks: (() => Promise<R>)[] = [];
private running: number = 0;
private results: R[] = [];
private errors: Error[] = [];
constructor(concurrency: number = 5) {
this.concurrency = concurrency;
}
add(task: () => Promise<R>): void {
this.tasks.push(task);
}
async execute(): Promise<{ results: R[]; errors: Error[] }> {
return new Promise((resolve) => {
const executeNext = () => {
if (this.tasks.length === 0 && this.running === 0) {
resolve({ results: this.results, errors: this.errors });
return;
}
while (this.running < this.concurrency && this.tasks.length > 0) {
const task = this.tasks.shift()!;
this.running++;
task()
.then(result => {
this.results.push(result);
})
.catch(error => {
this.errors.push(error instanceof Error ? error : new Error(String(error)));
})
.finally(() => {
this.running--;
executeNext();
});
}
};
executeNext();
});
}
}
// ========== Async Cache ==========
export class AsyncCache<K, V> {
private cache = new Map<K, Promise<V>>();
private ttl: number;
constructor(ttlMs: number = 60000) {
this.ttl = ttlMs;
}
async get(key: K, factory: () => Promise<V>): Promise<V> {
if (this.cache.has(key)) {
try {
return await this.cache.get(key)!;
} catch (error) {
// Remove failed promise from cache
this.cache.delete(key);
throw error;
}
}
const promise = factory();
this.cache.set(key, promise);
// Set TTL
setTimeout(() => {
this.cache.delete(key);
}, this.ttl);
return promise;
}
clear(): void {
this.cache.clear();
}
has(key: K): boolean {
return this.cache.has(key);
}
}
// ========== Async Semaphore ==========
export class Semaphore {
private permits: number;
private waiting: (() => void)[] = [];
constructor(permits: number) {
this.permits = permits;
}
async acquire(): Promise<void> {
if (this.permits > 0) {
this.permits--;
return;
}
return new Promise<void>((resolve) => {
this.waiting.push(resolve);
});
}
release(): void {
if (this.waiting.length > 0) {
const next = this.waiting.shift()!;
next();
} else {
this.permits++;
}
}
async execute<T>(fn: () => Promise<T>): Promise<T> {
await this.acquire();
try {
return await fn();
} finally {
this.release();
}
}
}
// ========== Worker Pattern ==========
export class TaskQueue<T> {
private queue: T[] = [];
private processing = false;
private processor: (item: T) => Promise<void>;
constructor(processor: (item: T) => Promise<void>) {
this.processor = processor;
}
enqueue(item: T): void {
this.queue.push(item);
if (!this.processing) {
this.processQueue();
}
}
private async processQueue(): Promise<void> {
this.processing = true;
while (this.queue.length > 0) {
const item = this.queue.shift()!;
try {
await this.processor(item);
} catch (error) {
console.error("Error processing queue item:", error);
}
}
this.processing = false;
}
get length(): number {
return this.queue.length;
}
get isProcessing(): boolean {
return this.processing;
}
}
// ========== Stream Processing ==========
export async function processStream<T, R>(
items: T[],
transformer: (item: T) => Promise<R>,
batchSize: number = 10
): Promise<R[]> {
const results: R[] = [];
for (let i = 0; i < items.length; i += batchSize) {
const batch = items.slice(i, i + batchSize);
const batchResults = await Promise.all(batch.map(transformer));
results.push(...batchResults);
}
return results;
}
// ========== Usage Examples ==========
export const asyncExamples = {
// Event emitter
userEvents: new EventEmitter<{ userId: number; action: string }>(),
// Promise pool
apiCallPool: new PromisePool<void, any>(3),
// Async cache
userCache: new AsyncCache<number, { id: number; name: string }>(30000),
// Semaphore for rate limiting
rateLimiter: new Semaphore(5),
// Task queue
notificationQueue: new TaskQueue<{ userId: number; message: string }>(async (notification) => {
console.log(`Sending notification to user ${notification.userId}: ${notification.message}`);
await new Promise(resolve => setTimeout(resolve, 100));
}),
};
// ========== Complex Async Operations ==========
export async function fetchUserProfile(userId: number): Promise<{
user: { id: number; name: string; email: string };
posts: { id: number; title: string; content: string }[];
}> {
try {
// Fetch user and posts in parallel
const [user, posts] = await Promise.all([
fetchUserData(userId),
fetchUserPosts(userId)
]);
return { user, posts };
} catch (error) {
throw new Error(`Failed to fetch user profile: ${error}`);
}
}
export async function batchProcessUsers(userIds: number[]): Promise<any[]> {
// Use the promise pool to limit concurrent API calls
const pool = new PromisePool<void, any>(3);
userIds.forEach(id => {
pool.add(async () => {
const profile = await fetchUserProfile(id);
return profile;
});
});
const { results, errors } = await pool.execute();
if (errors.length > 0) {
console.warn(`${errors.length} errors occurred during batch processing:`, errors);
}
return results;
}
// Initialize some examples
asyncExamples.userEvents.subscribe((event) => {
console.log(`User event: ${event.action} for user ${event.userId}`);
});
// Example of using the notification queue
asyncExamples.notificationQueue.enqueue({
userId: 1,
message: "Welcome to our platform!"
});
asyncExamples.notificationQueue.enqueue({
userId: 2,
message: "Your order has been shipped!"
});
```
--------------------------------------------------------------------------------
/tests/sample_project_typescript/src/modules-namespaces.ts:
--------------------------------------------------------------------------------
```typescript
/**
* Modules and Namespaces
* Demonstrates TypeScript's module system, imports/exports, namespaces,
* ambient declarations, and advanced module patterns
*/
// ========== Basic Exports ==========
export const MODULE_VERSION = "1.0.0";
export const DEFAULT_CONFIG = {
debug: false,
timeout: 5000,
retries: 3
};
// Named export
export function calculateSum(a: number, b: number): number {
return a + b;
}
// Export with alias
export { calculateSum as add };
// Multiple exports
export const PI = Math.PI;
export const E = Math.E;
// ========== Default Export ==========
class DefaultLogger {
private prefix: string;
constructor(prefix: string = "LOG") {
this.prefix = prefix;
}
log(message: string): void {
console.log(`[${this.prefix}] ${message}`);
}
error(message: string): void {
console.error(`[${this.prefix}] ERROR: ${message}`);
}
}
export default DefaultLogger;
// ========== Re-exports ==========
// Re-export everything from types-interfaces
export * from './types-interfaces';
// Re-export specific items with aliases
export {
Person as BasePerson,
Employee as StaffMember
} from './classes-inheritance';
// Re-export default with a name
export { default as Logger } from './modules-namespaces';
// ========== Namespace Declarations ==========
export namespace MathUtils {
export interface Point2D {
x: number;
y: number;
}
export interface Point3D extends Point2D {
z: number;
}
export class Vector2D implements Point2D {
constructor(public x: number, public y: number) {}
add(other: Vector2D): Vector2D {
return new Vector2D(this.x + other.x, this.y + other.y);
}
magnitude(): number {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
}
export class Vector3D implements Point3D {
constructor(public x: number, public y: number, public z: number) {}
add(other: Vector3D): Vector3D {
return new Vector3D(this.x + other.x, this.y + other.y, this.z + other.z);
}
magnitude(): number {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
}
}
export function distance2D(p1: Point2D, p2: Point2D): number {
const dx = p1.x - p2.x;
const dy = p1.y - p2.y;
return Math.sqrt(dx * dx + dy * dy);
}
export function distance3D(p1: Point3D, p2: Point3D): number {
const dx = p1.x - p2.x;
const dy = p1.y - p2.y;
const dz = p1.z - p2.z;
return Math.sqrt(dx * dx + dy * dy + dz * dz);
}
export namespace Constants {
export const GOLDEN_RATIO = 1.618033988749895;
export const EULER_CONSTANT = 0.5772156649015329;
export const SQRT_2 = Math.sqrt(2);
}
}
// Nested namespace
export namespace DataStructures {
export namespace Trees {
export interface TreeNode<T> {
value: T;
left?: TreeNode<T>;
right?: TreeNode<T>;
}
export class BinaryTree<T> {
constructor(public root?: TreeNode<T>) {}
insert(value: T): void {
this.root = this.insertNode(this.root, value);
}
private insertNode(node: TreeNode<T> | undefined, value: T): TreeNode<T> {
if (!node) {
return { value };
}
// Simple insertion based on string comparison
if (String(value) < String(node.value)) {
node.left = this.insertNode(node.left, value);
} else {
node.right = this.insertNode(node.right, value);
}
return node;
}
}
}
export namespace Graphs {
export interface Edge<T> {
from: T;
to: T;
weight?: number;
}
export class Graph<T> {
private adjacencyList: Map<T, T[]> = new Map();
addVertex(vertex: T): void {
if (!this.adjacencyList.has(vertex)) {
this.adjacencyList.set(vertex, []);
}
}
addEdge(from: T, to: T): void {
this.addVertex(from);
this.addVertex(to);
this.adjacencyList.get(from)!.push(to);
}
getNeighbors(vertex: T): T[] {
return this.adjacencyList.get(vertex) || [];
}
getVertices(): T[] {
return Array.from(this.adjacencyList.keys());
}
}
}
}
// ========== Module Augmentation ==========
// Extending existing modules
declare global {
interface String {
toTitleCase(): string;
truncate(length: number): string;
}
interface Array<T> {
chunk(size: number): T[][];
unique(): T[];
}
}
// Implement the extensions
String.prototype.toTitleCase = function(): string {
return this.replace(/\w\S*/g, (txt) =>
txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
);
};
String.prototype.truncate = function(length: number): string {
return this.length > length ? this.substring(0, length) + '...' : this.toString();
};
Array.prototype.chunk = function<T>(this: T[], size: number): T[][] {
const chunks: T[][] = [];
for (let i = 0; i < this.length; i += size) {
chunks.push(this.slice(i, i + size));
}
return chunks;
};
Array.prototype.unique = function<T>(this: T[]): T[] {
return [...new Set(this)];
};
// ========== Ambient Declarations ==========
// Declare external libraries or global variables
declare global {
var GLOBAL_CONFIG: {
apiUrl: string;
version: string;
features: string[];
};
}
// Ambient module declaration
declare module "fictional-library" {
export interface Config {
apiKey: string;
endpoint: string;
}
export class Client {
constructor(config: Config);
request(path: string): Promise<any>;
}
export function initialize(config: Config): Client;
}
// Declare a module with wildcard
declare module "*.json" {
const value: any;
export default value;
}
declare module "*.svg" {
const content: string;
export default content;
}
// ========== Conditional Exports ==========
export interface DatabaseConnection {
connect(): Promise<void>;
disconnect(): Promise<void>;
query(sql: string): Promise<any[]>;
}
// Different implementations based on environment
const isDevelopment = process.env.NODE_ENV === 'development';
export const createDatabaseConnection = (): DatabaseConnection => {
if (isDevelopment) {
return new MockDatabaseConnection();
} else {
return new ProductionDatabaseConnection();
}
};
class MockDatabaseConnection implements DatabaseConnection {
async connect(): Promise<void> {
console.log("Connected to mock database");
}
async disconnect(): Promise<void> {
console.log("Disconnected from mock database");
}
async query(sql: string): Promise<any[]> {
console.log(`Mock query: ${sql}`);
return [{ id: 1, name: "Mock Data" }];
}
}
class ProductionDatabaseConnection implements DatabaseConnection {
async connect(): Promise<void> {
console.log("Connected to production database");
}
async disconnect(): Promise<void> {
console.log("Disconnected from production database");
}
async query(sql: string): Promise<any[]> {
console.log(`Production query: ${sql}`);
// Would connect to real database
return [];
}
}
// ========== Dynamic Imports ==========
export async function loadModule(moduleName: string): Promise<any> {
try {
switch (moduleName) {
case 'math':
return await import('./functions-generics');
case 'classes':
return await import('./classes-inheritance');
case 'types':
return await import('./types-interfaces');
default:
throw new Error(`Module ${moduleName} not found`);
}
} catch (error) {
console.error(`Failed to load module ${moduleName}:`, error);
throw error;
}
}
// Dynamic import with type assertion
export async function loadTypedModule<T>(): Promise<T> {
const module = await import('./types-interfaces');
return module as T;
}
// ========== Module Factory Pattern ==========
export interface ModuleConfig {
name: string;
version: string;
dependencies?: string[];
}
export abstract class BaseModule {
constructor(protected config: ModuleConfig) {}
abstract initialize(): Promise<void>;
abstract cleanup(): Promise<void>;
getConfig(): ModuleConfig {
return this.config;
}
}
export class FeatureModule extends BaseModule {
private isInitialized = false;
async initialize(): Promise<void> {
console.log(`Initializing ${this.config.name} v${this.config.version}`);
if (this.config.dependencies) {
for (const dep of this.config.dependencies) {
await this.loadDependency(dep);
}
}
this.isInitialized = true;
}
async cleanup(): Promise<void> {
console.log(`Cleaning up ${this.config.name}`);
this.isInitialized = false;
}
private async loadDependency(name: string): Promise<void> {
console.log(`Loading dependency: ${name}`);
// Simulate loading dependency
await new Promise(resolve => setTimeout(resolve, 100));
}
isReady(): boolean {
return this.isInitialized;
}
}
// ========== Barrel Exports ==========
// This file can serve as a barrel export for the entire project
export {
// Re-export all from other modules to create a single entry point
createUser,
greet,
sum
} from './functions-generics';
export {
EventEmitter,
PromisePool,
AsyncCache
} from './async-promises';
// ========== Triple-Slash Directives ==========
/// <reference types="node" />
/// <reference lib="es2020" />
// ========== Usage Examples ==========
export const moduleExamples = {
// Math utilities
vector2D: new MathUtils.Vector2D(3, 4),
vector3D: new MathUtils.Vector3D(1, 2, 3),
distance: MathUtils.distance2D({ x: 0, y: 0 }, { x: 3, y: 4 }),
// Data structures
binaryTree: new DataStructures.Trees.BinaryTree<number>(),
graph: new DataStructures.Graphs.Graph<string>(),
// String extensions (using global augmentation)
titleCase: "hello world".toTitleCase(),
truncated: "This is a very long string".truncate(10),
// Array extensions
chunked: [1, 2, 3, 4, 5, 6].chunk(2),
uniqueArray: [1, 2, 2, 3, 3, 3].unique(),
// Module factory
featureModule: new FeatureModule({
name: "SampleFeature",
version: "1.0.0",
dependencies: ["core", "utils"]
}),
// Database connection
dbConnection: createDatabaseConnection()
};
// Initialize examples
moduleExamples.binaryTree.insert(5);
moduleExamples.binaryTree.insert(3);
moduleExamples.binaryTree.insert(7);
moduleExamples.graph.addVertex("A");
moduleExamples.graph.addVertex("B");
moduleExamples.graph.addEdge("A", "B");
// Constants from nested namespace
export const mathConstants = {
goldenRatio: MathUtils.Constants.GOLDEN_RATIO,
eulerConstant: MathUtils.Constants.EULER_CONSTANT,
sqrt2: MathUtils.Constants.SQRT_2
};
// ========== Module Types ==========
export type ModuleLoader = (name: string) => Promise<any>;
export type ModuleRegistry = Map<string, BaseModule>;
export interface ModuleSystem {
register(name: string, module: BaseModule): void;
unregister(name: string): void;
get(name: string): BaseModule | undefined;
has(name: string): boolean;
initialize(): Promise<void>;
shutdown(): Promise<void>;
}
```
--------------------------------------------------------------------------------
/docs/site/assets/javascripts/lunr/min/lunr.es.min.js:
--------------------------------------------------------------------------------
```javascript
/*!
* Lunr languages, `Spanish` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,s){"function"==typeof define&&define.amd?define(s):"object"==typeof exports?module.exports=s():s()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.es=function(){this.pipeline.reset(),this.pipeline.add(e.es.trimmer,e.es.stopWordFilter,e.es.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.es.stemmer))},e.es.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.es.trimmer=e.trimmerSupport.generateTrimmer(e.es.wordCharacters),e.Pipeline.registerFunction(e.es.trimmer,"trimmer-es"),e.es.stemmer=function(){var s=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(){if(A.out_grouping(x,97,252)){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}return!0}function n(){if(A.in_grouping(x,97,252)){var s=A.cursor;if(e()){if(A.cursor=s,!A.in_grouping(x,97,252))return!0;for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}}return!1}return!0}function i(){var s,r=A.cursor;if(n()){if(A.cursor=r,!A.out_grouping(x,97,252))return;if(s=A.cursor,e()){if(A.cursor=s,!A.in_grouping(x,97,252)||A.cursor>=A.limit)return;A.cursor++}}g=A.cursor}function a(){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}return!0}function t(){var e=A.cursor;g=A.limit,p=g,v=g,i(),A.cursor=e,a()&&(p=A.cursor,a()&&(v=A.cursor))}function o(){for(var e;;){if(A.bra=A.cursor,e=A.find_among(k,6))switch(A.ket=A.cursor,e){case 1:A.slice_from("a");continue;case 2:A.slice_from("e");continue;case 3:A.slice_from("i");continue;case 4:A.slice_from("o");continue;case 5:A.slice_from("u");continue;case 6:if(A.cursor>=A.limit)break;A.cursor++;continue}break}}function u(){return g<=A.cursor}function w(){return p<=A.cursor}function c(){return v<=A.cursor}function m(){var e;if(A.ket=A.cursor,A.find_among_b(y,13)&&(A.bra=A.cursor,(e=A.find_among_b(q,11))&&u()))switch(e){case 1:A.bra=A.cursor,A.slice_from("iendo");break;case 2:A.bra=A.cursor,A.slice_from("ando");break;case 3:A.bra=A.cursor,A.slice_from("ar");break;case 4:A.bra=A.cursor,A.slice_from("er");break;case 5:A.bra=A.cursor,A.slice_from("ir");break;case 6:A.slice_del();break;case 7:A.eq_s_b(1,"u")&&A.slice_del()}}function l(e,s){if(!c())return!0;A.slice_del(),A.ket=A.cursor;var r=A.find_among_b(e,s);return r&&(A.bra=A.cursor,1==r&&c()&&A.slice_del()),!1}function d(e){return!c()||(A.slice_del(),A.ket=A.cursor,A.eq_s_b(2,e)&&(A.bra=A.cursor,c()&&A.slice_del()),!1)}function b(){var e;if(A.ket=A.cursor,e=A.find_among_b(S,46)){switch(A.bra=A.cursor,e){case 1:if(!c())return!1;A.slice_del();break;case 2:if(d("ic"))return!1;break;case 3:if(!c())return!1;A.slice_from("log");break;case 4:if(!c())return!1;A.slice_from("u");break;case 5:if(!c())return!1;A.slice_from("ente");break;case 6:if(!w())return!1;A.slice_del(),A.ket=A.cursor,e=A.find_among_b(C,4),e&&(A.bra=A.cursor,c()&&(A.slice_del(),1==e&&(A.ket=A.cursor,A.eq_s_b(2,"at")&&(A.bra=A.cursor,c()&&A.slice_del()))));break;case 7:if(l(P,3))return!1;break;case 8:if(l(F,3))return!1;break;case 9:if(d("at"))return!1}return!0}return!1}function f(){var e,s;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(W,12),A.limit_backward=s,e)){if(A.bra=A.cursor,1==e){if(!A.eq_s_b(1,"u"))return!1;A.slice_del()}return!0}return!1}function _(){var e,s,r,n;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(L,96),A.limit_backward=s,e))switch(A.bra=A.cursor,e){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"u")?(n=A.limit-A.cursor,A.eq_s_b(1,"g")?A.cursor=A.limit-n:A.cursor=A.limit-r):A.cursor=A.limit-r,A.bra=A.cursor;case 2:A.slice_del()}}function h(){var e,s;if(A.ket=A.cursor,e=A.find_among_b(z,8))switch(A.bra=A.cursor,e){case 1:u()&&A.slice_del();break;case 2:u()&&(A.slice_del(),A.ket=A.cursor,A.eq_s_b(1,"u")&&(A.bra=A.cursor,s=A.limit-A.cursor,A.eq_s_b(1,"g")&&(A.cursor=A.limit-s,u()&&A.slice_del())))}}var v,p,g,k=[new s("",-1,6),new s("á",0,1),new s("é",0,2),new s("í",0,3),new s("ó",0,4),new s("ú",0,5)],y=[new s("la",-1,-1),new s("sela",0,-1),new s("le",-1,-1),new s("me",-1,-1),new s("se",-1,-1),new s("lo",-1,-1),new s("selo",5,-1),new s("las",-1,-1),new s("selas",7,-1),new s("les",-1,-1),new s("los",-1,-1),new s("selos",10,-1),new s("nos",-1,-1)],q=[new s("ando",-1,6),new s("iendo",-1,6),new s("yendo",-1,7),new s("ándo",-1,2),new s("iéndo",-1,1),new s("ar",-1,6),new s("er",-1,6),new s("ir",-1,6),new s("ár",-1,3),new s("ér",-1,4),new s("ír",-1,5)],C=[new s("ic",-1,-1),new s("ad",-1,-1),new s("os",-1,-1),new s("iv",-1,1)],P=[new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,1)],F=[new s("ic",-1,1),new s("abil",-1,1),new s("iv",-1,1)],S=[new s("ica",-1,1),new s("ancia",-1,2),new s("encia",-1,5),new s("adora",-1,2),new s("osa",-1,1),new s("ista",-1,1),new s("iva",-1,9),new s("anza",-1,1),new s("logía",-1,3),new s("idad",-1,8),new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,2),new s("mente",-1,7),new s("amente",13,6),new s("ación",-1,2),new s("ución",-1,4),new s("ico",-1,1),new s("ismo",-1,1),new s("oso",-1,1),new s("amiento",-1,1),new s("imiento",-1,1),new s("ivo",-1,9),new s("ador",-1,2),new s("icas",-1,1),new s("ancias",-1,2),new s("encias",-1,5),new s("adoras",-1,2),new s("osas",-1,1),new s("istas",-1,1),new s("ivas",-1,9),new s("anzas",-1,1),new s("logías",-1,3),new s("idades",-1,8),new s("ables",-1,1),new s("ibles",-1,1),new s("aciones",-1,2),new s("uciones",-1,4),new s("adores",-1,2),new s("antes",-1,2),new s("icos",-1,1),new s("ismos",-1,1),new s("osos",-1,1),new s("amientos",-1,1),new s("imientos",-1,1),new s("ivos",-1,9)],W=[new s("ya",-1,1),new s("ye",-1,1),new s("yan",-1,1),new s("yen",-1,1),new s("yeron",-1,1),new s("yendo",-1,1),new s("yo",-1,1),new s("yas",-1,1),new s("yes",-1,1),new s("yais",-1,1),new s("yamos",-1,1),new s("yó",-1,1)],L=[new s("aba",-1,2),new s("ada",-1,2),new s("ida",-1,2),new s("ara",-1,2),new s("iera",-1,2),new s("ía",-1,2),new s("aría",5,2),new s("ería",5,2),new s("iría",5,2),new s("ad",-1,2),new s("ed",-1,2),new s("id",-1,2),new s("ase",-1,2),new s("iese",-1,2),new s("aste",-1,2),new s("iste",-1,2),new s("an",-1,2),new s("aban",16,2),new s("aran",16,2),new s("ieran",16,2),new s("ían",16,2),new s("arían",20,2),new s("erían",20,2),new s("irían",20,2),new s("en",-1,1),new s("asen",24,2),new s("iesen",24,2),new s("aron",-1,2),new s("ieron",-1,2),new s("arán",-1,2),new s("erán",-1,2),new s("irán",-1,2),new s("ado",-1,2),new s("ido",-1,2),new s("ando",-1,2),new s("iendo",-1,2),new s("ar",-1,2),new s("er",-1,2),new s("ir",-1,2),new s("as",-1,2),new s("abas",39,2),new s("adas",39,2),new s("idas",39,2),new s("aras",39,2),new s("ieras",39,2),new s("ías",39,2),new s("arías",45,2),new s("erías",45,2),new s("irías",45,2),new s("es",-1,1),new s("ases",49,2),new s("ieses",49,2),new s("abais",-1,2),new s("arais",-1,2),new s("ierais",-1,2),new s("íais",-1,2),new s("aríais",55,2),new s("eríais",55,2),new s("iríais",55,2),new s("aseis",-1,2),new s("ieseis",-1,2),new s("asteis",-1,2),new s("isteis",-1,2),new s("áis",-1,2),new s("éis",-1,1),new s("aréis",64,2),new s("eréis",64,2),new s("iréis",64,2),new s("ados",-1,2),new s("idos",-1,2),new s("amos",-1,2),new s("ábamos",70,2),new s("áramos",70,2),new s("iéramos",70,2),new s("íamos",70,2),new s("aríamos",74,2),new s("eríamos",74,2),new s("iríamos",74,2),new s("emos",-1,1),new s("aremos",78,2),new s("eremos",78,2),new s("iremos",78,2),new s("ásemos",78,2),new s("iésemos",78,2),new s("imos",-1,2),new s("arás",-1,2),new s("erás",-1,2),new s("irás",-1,2),new s("ís",-1,2),new s("ará",-1,2),new s("erá",-1,2),new s("irá",-1,2),new s("aré",-1,2),new s("eré",-1,2),new s("iré",-1,2),new s("ió",-1,2)],z=[new s("a",-1,1),new s("e",-1,2),new s("o",-1,1),new s("os",-1,1),new s("á",-1,1),new s("é",-1,2),new s("í",-1,1),new s("ó",-1,1)],x=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],A=new r;this.setCurrent=function(e){A.setCurrent(e)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return t(),A.limit_backward=e,A.cursor=A.limit,m(),A.cursor=A.limit,b()||(A.cursor=A.limit,f()||(A.cursor=A.limit,_())),A.cursor=A.limit,h(),A.cursor=A.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.es.stemmer,"stemmer-es"),e.es.stopWordFilter=e.generateStopWordFilter("a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" ")),e.Pipeline.registerFunction(e.es.stopWordFilter,"stopWordFilter-es")}});
```